Loading services/core/java/com/android/server/hdmi/ActiveSourceHandler.java +35 −28 Original line number Diff line number Diff line Loading @@ -26,31 +26,29 @@ import android.util.Slog; /** * Handles CEC command <Active Source>. * * <p>Used by feature actions that need to handle the command in their flow. * <p> * Used by feature actions that need to handle the command in their flow. */ final class ActiveSourceHandler { private static final String TAG = "ActiveSourceHandler"; private final HdmiCecLocalDevice mSource; private final HdmiControlService mService; private final int mSourceAddress; private final int mSourcePath; @Nullable private final IHdmiControlCallback mCallback; @Nullable private final IHdmiControlCallback mCallback; static ActiveSourceHandler create(HdmiControlService service, int sourceAddress, int sourcePath, IHdmiControlCallback callback) { if (service == null) { static ActiveSourceHandler create(HdmiCecLocalDevice source, IHdmiControlCallback callback) { if (source == null) { Slog.e(TAG, "Wrong arguments"); return null; } return new ActiveSourceHandler(service, sourceAddress, sourcePath, callback); return new ActiveSourceHandler(source, callback); } private ActiveSourceHandler(HdmiControlService service, int sourceAddress, int sourcePath, IHdmiControlCallback callback) { mService = service; mSourceAddress = sourceAddress; mSourcePath = sourcePath; private ActiveSourceHandler(HdmiCecLocalDevice source, IHdmiControlCallback callback) { mSource = source; mService = mSource.getService(); mCallback = callback; } Loading @@ -61,7 +59,7 @@ final class ActiveSourceHandler { * @param routingPath routing path of the device to be the active source */ void process(int deviceLogicalAddress, int routingPath) { if (mSourcePath == routingPath && mService.getActiveSource() == mSourceAddress) { if (getSourcePath() == routingPath && mSource.getActiveSource() == getSourceAddress()) { invokeCallback(HdmiCec.RESULT_SUCCESS); return; } Loading @@ -69,14 +67,14 @@ final class ActiveSourceHandler { if (device == null) { // "New device action" initiated by <Active Source> does not require // "Routing change action". mService.addAndStartAction(new NewDeviceAction(mService, mSourceAddress, deviceLogicalAddress, routingPath, false)); mSource.addAndStartAction(new NewDeviceAction(mSource, deviceLogicalAddress, routingPath, false)); } if (!mService.isInPresetInstallationMode()) { int prevActiveInput = mService.getActiveInput(); mService.updateActiveDevice(deviceLogicalAddress, routingPath); if (prevActiveInput != mService.getActiveInput()) { if (!mSource.isInPresetInstallationMode()) { int prevActiveInput = mSource.getActiveInput(); mSource.updateActiveDevice(deviceLogicalAddress, routingPath); if (prevActiveInput != mSource.getActiveInput()) { // TODO: change port input here. } invokeCallback(HdmiCec.RESULT_SUCCESS); Loading @@ -84,24 +82,33 @@ final class ActiveSourceHandler { // TV is in a mode that should keep its current source/input from // being changed for its operation. Reclaim the active source // or switch the port back to the one used for the current mode. if (mService.getActiveSource() == mSourceAddress) { if (mSource.getActiveSource() == getSourceAddress()) { HdmiCecMessage activeSource = HdmiCecMessageBuilder.buildActiveSource(mSourceAddress, mSourcePath); HdmiCecMessageBuilder.buildActiveSource(getSourceAddress(), getSourcePath()); mService.sendCecCommand(activeSource); mService.updateActiveDevice(deviceLogicalAddress, routingPath); mSource.updateActiveDevice(deviceLogicalAddress, routingPath); invokeCallback(HdmiCec.RESULT_SUCCESS); } else { int activePath = mService.getActivePath(); mService.sendCecCommand(HdmiCecMessageBuilder.buildRoutingChange(mSourceAddress, int activePath = mSource.getActivePath(); mService.sendCecCommand(HdmiCecMessageBuilder.buildRoutingChange(getSourceAddress(), routingPath, activePath)); // TODO: Start port select action here // PortSelectAction action = new PortSelectAction(mService, mSourceAddress, // PortSelectAction action = new PortSelectAction(mService, getSourceAddress(), // activePath, mCallback); // mService.addActionAndStart(action); } } } private final int getSourceAddress() { return mSource.getDeviceInfo().getLogicalAddress(); } private final int getSourcePath() { return mSource.getDeviceInfo().getPhysicalAddress(); } private void invokeCallback(int result) { if (mCallback == null) { return; Loading services/core/java/com/android/server/hdmi/DeviceDiscoveryAction.java +9 −10 Original line number Diff line number Diff line Loading @@ -94,12 +94,10 @@ final class DeviceDiscoveryAction extends FeatureAction { /** * Constructor. * * @param service an instance of {@link HdmiControlService}. * @param sourceAddress a logical address which initiates this action * @param source an instance of {@link HdmiCecLocalDevice}. */ DeviceDiscoveryAction(HdmiControlService service, int sourceAddress, DeviceDiscoveryCallback callback) { super(service, sourceAddress); DeviceDiscoveryAction(HdmiCecLocalDevice source, DeviceDiscoveryCallback callback) { super(source); mCallback = Preconditions.checkNotNull(callback); } Loading @@ -108,7 +106,7 @@ final class DeviceDiscoveryAction extends FeatureAction { mDevices.clear(); mState = STATE_WAITING_FOR_DEVICE_POLLING; mService.pollDevices(new DevicePollingCallback() { pollDevices(new DevicePollingCallback() { @Override public void onPollingFinished(List<Integer> ackedAddress) { if (ackedAddress.isEmpty()) { Loading Loading @@ -156,7 +154,7 @@ final class DeviceDiscoveryAction extends FeatureAction { if (mayProcessMessageIfCached(address, HdmiCec.MESSAGE_REPORT_PHYSICAL_ADDRESS)) { return; } sendCommand(HdmiCecMessageBuilder.buildGivePhysicalAddress(mSourceAddress, address)); sendCommand(HdmiCecMessageBuilder.buildGivePhysicalAddress(getSourceAddress(), address)); addTimer(mState, TIMEOUT_MS); } Loading @@ -179,7 +177,7 @@ final class DeviceDiscoveryAction extends FeatureAction { if (mayProcessMessageIfCached(address, HdmiCec.MESSAGE_SET_OSD_NAME)) { return; } sendCommand(HdmiCecMessageBuilder.buildGiveOsdNameCommand(mSourceAddress, address)); sendCommand(HdmiCecMessageBuilder.buildGiveOsdNameCommand(getSourceAddress(), address)); addTimer(mState, TIMEOUT_MS); } Loading @@ -203,12 +201,13 @@ final class DeviceDiscoveryAction extends FeatureAction { if (mayProcessMessageIfCached(address, HdmiCec.MESSAGE_DEVICE_VENDOR_ID)) { return; } sendCommand(HdmiCecMessageBuilder.buildGiveDeviceVendorIdCommand(mSourceAddress, address)); sendCommand( HdmiCecMessageBuilder.buildGiveDeviceVendorIdCommand(getSourceAddress(), address)); addTimer(mState, TIMEOUT_MS); } private boolean mayProcessMessageIfCached(int address, int opcode) { HdmiCecMessage message = mService.getCecMessageCache().getMessage(address, opcode); HdmiCecMessage message = getCecMessageCache().getMessage(address, opcode); if (message != null) { processCommand(message); return true; Loading services/core/java/com/android/server/hdmi/DevicePowerStatusAction.java +9 −8 Original line number Diff line number Diff line Loading @@ -16,9 +16,10 @@ package com.android.server.hdmi; * limitations under the License. */ import android.hardware.hdmi.IHdmiControlCallback; import android.hardware.hdmi.HdmiCec; import android.hardware.hdmi.HdmiCecMessage; import android.hardware.hdmi.HdmiControlManager; import android.hardware.hdmi.IHdmiControlCallback; import android.os.RemoteException; import android.util.Slog; Loading @@ -40,18 +41,18 @@ final class DevicePowerStatusAction extends FeatureAction { private final int mTargetAddress; private final IHdmiControlCallback mCallback; static DevicePowerStatusAction create(HdmiControlService service, int sourceAddress, static DevicePowerStatusAction create(HdmiCecLocalDevice source, int targetAddress, IHdmiControlCallback callback) { if (service == null || callback == null) { if (source == null || callback == null) { Slog.e(TAG, "Wrong arguments"); return null; } return new DevicePowerStatusAction(service, sourceAddress, targetAddress, callback); return new DevicePowerStatusAction(source, targetAddress, callback); } private DevicePowerStatusAction(HdmiControlService service, int sourceAddress, private DevicePowerStatusAction(HdmiCecLocalDevice localDevice, int targetAddress, IHdmiControlCallback callback) { super(service, sourceAddress); super(localDevice); mTargetAddress = targetAddress; mCallback = callback; } Loading @@ -65,8 +66,8 @@ final class DevicePowerStatusAction extends FeatureAction { } private void queryDevicePowerStatus() { mService.sendCecCommand( HdmiCecMessageBuilder.buildGiveDevicePowerStatus(mSourceAddress, mTargetAddress)); sendCommand(HdmiCecMessageBuilder.buildGiveDevicePowerStatus(getSourceAddress(), mTargetAddress)); } @Override Loading services/core/java/com/android/server/hdmi/DeviceSelectAction.java +12 −14 Original line number Diff line number Diff line Loading @@ -16,10 +16,11 @@ package com.android.server.hdmi; import android.hardware.hdmi.IHdmiControlCallback; import android.hardware.hdmi.HdmiCecDeviceInfo; import android.hardware.hdmi.HdmiCec; import android.hardware.hdmi.HdmiCecDeviceInfo; import android.hardware.hdmi.HdmiCecMessage; import android.hardware.hdmi.HdmiTvClient; import android.hardware.hdmi.IHdmiControlCallback; import android.os.RemoteException; import android.util.Slog; Loading Loading @@ -66,24 +67,20 @@ final class DeviceSelectAction extends FeatureAction { private final HdmiCecDeviceInfo mTarget; private final IHdmiControlCallback mCallback; private final int mSourcePath; private int mPowerStatusCounter = 0; /** * Constructor. * * @param service {@link HdmiControlService} instance * @param sourceAddress logical address of TV initiating this action * @param sourcePath physical address of TV * @param source {@link HdmiCecLocalDevice} instance * @param target target logical device that will be a new active source * @param callback callback object */ public DeviceSelectAction(HdmiControlService service, int sourceAddress, int sourcePath, public DeviceSelectAction(HdmiCecLocalDevice source, HdmiCecDeviceInfo target, IHdmiControlCallback callback) { super(service, sourceAddress); super(source); mCallback = callback; mSourcePath = sourcePath; mTarget = target; } Loading @@ -96,7 +93,7 @@ final class DeviceSelectAction extends FeatureAction { private void queryDevicePowerStatus() { sendCommand(HdmiCecMessageBuilder.buildGiveDevicePowerStatus( mSourceAddress, mTarget.getLogicalAddress())); getSourceAddress(), mTarget.getLogicalAddress())); mState = STATE_WAIT_FOR_REPORT_POWER_STATUS; addTimer(mState, TIMEOUT_MS); } Loading @@ -118,7 +115,8 @@ final class DeviceSelectAction extends FeatureAction { case STATE_WAIT_FOR_ACTIVE_SOURCE: if (opcode == HdmiCec.MESSAGE_ACTIVE_SOURCE && params.length == 2) { int activePath = HdmiUtils.twoBytesToInt(params); ActiveSourceHandler.create(mService, mSourceAddress, mSourcePath, mCallback) ActiveSourceHandler .create(localDevice(), mCallback) .process(cmd.getSource(), activePath); finish(); return true; Loading Loading @@ -174,15 +172,15 @@ final class DeviceSelectAction extends FeatureAction { private void sendSetStreamPath() { sendCommand(HdmiCecMessageBuilder.buildSetStreamPath( mSourceAddress, mTarget.getPhysicalAddress())); getSourceAddress(), mTarget.getPhysicalAddress())); mState = STATE_WAIT_FOR_ACTIVE_SOURCE; addTimer(mState, TIMEOUT_ACTIVE_SOURCE_MS); } private void sendRemoteKeyCommand(int keyCode) { sendCommand(HdmiCecMessageBuilder.buildUserControlPressed(mSourceAddress, sendCommand(HdmiCecMessageBuilder.buildUserControlPressed(getSourceAddress(), mTarget.getLogicalAddress(), keyCode)); sendCommand(HdmiCecMessageBuilder.buildUserControlReleased(mSourceAddress, sendCommand(HdmiCecMessageBuilder.buildUserControlReleased(getSourceAddress(), mTarget.getLogicalAddress())); } Loading services/core/java/com/android/server/hdmi/FeatureAction.java +64 −19 Original line number Diff line number Diff line Loading @@ -22,6 +22,9 @@ import android.os.Message; import android.util.Slog; import com.android.internal.annotations.VisibleForTesting; import com.android.server.hdmi.HdmiControlService.DevicePollingCallback; import java.util.List; /** * Encapsulates a sequence of CEC/MHL command exchange for a certain feature. Loading @@ -33,14 +36,13 @@ import com.android.internal.annotations.VisibleForTesting; * of the object. All the actual action classes inherit FeatureAction. * * <p>More than one FeatureAction objects can be up and running simultaneously, * maintained by {@link HdmiControlService}. Each action is passed a new command * maintained by {@link HdmiCecLocalDevice}. Each action is passed a new command * arriving from the bus, and either consumes it if the command is what the action expects, * or yields it to other action. * * Declared as package private, accessed by {@link HdmiControlService} only. */ abstract class FeatureAction { private static final String TAG = "FeatureAction"; // Timer handler message used for timeout event Loading @@ -56,19 +58,16 @@ abstract class FeatureAction { // Internal state indicating the progress of action. protected int mState = STATE_NONE; protected final HdmiControlService mService; // Logical address of the device for which the feature action is taken. The commands // generated in an action all use this field as source address. protected final int mSourceAddress; private final HdmiControlService mService; private final HdmiCecLocalDevice mSource; // Timer that manages timeout events. protected ActionTimer mActionTimer; FeatureAction(HdmiControlService service, int sourceAddress) { mService = service; mSourceAddress = sourceAddress; mActionTimer = createActionTimer(service.getServiceLooper()); FeatureAction(HdmiCecLocalDevice source) { mSource = source; mService = mSource.getService(); mActionTimer = createActionTimer(mService.getServiceLooper()); } @VisibleForTesting Loading Loading @@ -175,6 +174,42 @@ abstract class FeatureAction { mService.sendCecCommand(cmd, callback); } protected final void addAndStartAction(FeatureAction action) { mSource.addAndStartAction(action); } protected final <T extends FeatureAction> List<T> getActions(final Class<T> clazz) { return mSource.getActions(clazz); } protected final HdmiCecMessageCache getCecMessageCache() { return mSource.getCecMessageCache(); } /** * Remove the action from the action queue. This is called after the action finishes * its role. * * @param action */ protected final void removeAction(FeatureAction action) { mSource.removeAction(action); } protected final <T extends FeatureAction> void removeAction(final Class<T> clazz) { mSource.removeActionExcept(clazz, null); } protected final <T extends FeatureAction> void removeActionExcept(final Class<T> clazz, final FeatureAction exception) { mSource.removeActionExcept(clazz, exception); } protected final void pollDevices(DevicePollingCallback callback, int pickStrategy, int retryCount) { mService.pollDevices(callback, pickStrategy, retryCount); } /** * Clean up action's state. * Loading @@ -194,13 +229,23 @@ abstract class FeatureAction { removeAction(this); } /** * Remove the action from the action queue. This is called after the action finishes * its role. * * @param action */ private void removeAction(FeatureAction action) { mService.removeAction(action); protected final HdmiCecLocalDevice localDevice() { return mSource; } protected final HdmiCecLocalDevicePlayback playback() { return (HdmiCecLocalDevicePlayback) mSource; } protected final HdmiCecLocalDeviceTv tv() { return (HdmiCecLocalDeviceTv) mSource; } protected final int getSourceAddress() { return mSource.getDeviceInfo().getLogicalAddress(); } protected final int getSourcePath() { return mSource.getDeviceInfo().getPhysicalAddress(); } } Loading
services/core/java/com/android/server/hdmi/ActiveSourceHandler.java +35 −28 Original line number Diff line number Diff line Loading @@ -26,31 +26,29 @@ import android.util.Slog; /** * Handles CEC command <Active Source>. * * <p>Used by feature actions that need to handle the command in their flow. * <p> * Used by feature actions that need to handle the command in their flow. */ final class ActiveSourceHandler { private static final String TAG = "ActiveSourceHandler"; private final HdmiCecLocalDevice mSource; private final HdmiControlService mService; private final int mSourceAddress; private final int mSourcePath; @Nullable private final IHdmiControlCallback mCallback; @Nullable private final IHdmiControlCallback mCallback; static ActiveSourceHandler create(HdmiControlService service, int sourceAddress, int sourcePath, IHdmiControlCallback callback) { if (service == null) { static ActiveSourceHandler create(HdmiCecLocalDevice source, IHdmiControlCallback callback) { if (source == null) { Slog.e(TAG, "Wrong arguments"); return null; } return new ActiveSourceHandler(service, sourceAddress, sourcePath, callback); return new ActiveSourceHandler(source, callback); } private ActiveSourceHandler(HdmiControlService service, int sourceAddress, int sourcePath, IHdmiControlCallback callback) { mService = service; mSourceAddress = sourceAddress; mSourcePath = sourcePath; private ActiveSourceHandler(HdmiCecLocalDevice source, IHdmiControlCallback callback) { mSource = source; mService = mSource.getService(); mCallback = callback; } Loading @@ -61,7 +59,7 @@ final class ActiveSourceHandler { * @param routingPath routing path of the device to be the active source */ void process(int deviceLogicalAddress, int routingPath) { if (mSourcePath == routingPath && mService.getActiveSource() == mSourceAddress) { if (getSourcePath() == routingPath && mSource.getActiveSource() == getSourceAddress()) { invokeCallback(HdmiCec.RESULT_SUCCESS); return; } Loading @@ -69,14 +67,14 @@ final class ActiveSourceHandler { if (device == null) { // "New device action" initiated by <Active Source> does not require // "Routing change action". mService.addAndStartAction(new NewDeviceAction(mService, mSourceAddress, deviceLogicalAddress, routingPath, false)); mSource.addAndStartAction(new NewDeviceAction(mSource, deviceLogicalAddress, routingPath, false)); } if (!mService.isInPresetInstallationMode()) { int prevActiveInput = mService.getActiveInput(); mService.updateActiveDevice(deviceLogicalAddress, routingPath); if (prevActiveInput != mService.getActiveInput()) { if (!mSource.isInPresetInstallationMode()) { int prevActiveInput = mSource.getActiveInput(); mSource.updateActiveDevice(deviceLogicalAddress, routingPath); if (prevActiveInput != mSource.getActiveInput()) { // TODO: change port input here. } invokeCallback(HdmiCec.RESULT_SUCCESS); Loading @@ -84,24 +82,33 @@ final class ActiveSourceHandler { // TV is in a mode that should keep its current source/input from // being changed for its operation. Reclaim the active source // or switch the port back to the one used for the current mode. if (mService.getActiveSource() == mSourceAddress) { if (mSource.getActiveSource() == getSourceAddress()) { HdmiCecMessage activeSource = HdmiCecMessageBuilder.buildActiveSource(mSourceAddress, mSourcePath); HdmiCecMessageBuilder.buildActiveSource(getSourceAddress(), getSourcePath()); mService.sendCecCommand(activeSource); mService.updateActiveDevice(deviceLogicalAddress, routingPath); mSource.updateActiveDevice(deviceLogicalAddress, routingPath); invokeCallback(HdmiCec.RESULT_SUCCESS); } else { int activePath = mService.getActivePath(); mService.sendCecCommand(HdmiCecMessageBuilder.buildRoutingChange(mSourceAddress, int activePath = mSource.getActivePath(); mService.sendCecCommand(HdmiCecMessageBuilder.buildRoutingChange(getSourceAddress(), routingPath, activePath)); // TODO: Start port select action here // PortSelectAction action = new PortSelectAction(mService, mSourceAddress, // PortSelectAction action = new PortSelectAction(mService, getSourceAddress(), // activePath, mCallback); // mService.addActionAndStart(action); } } } private final int getSourceAddress() { return mSource.getDeviceInfo().getLogicalAddress(); } private final int getSourcePath() { return mSource.getDeviceInfo().getPhysicalAddress(); } private void invokeCallback(int result) { if (mCallback == null) { return; Loading
services/core/java/com/android/server/hdmi/DeviceDiscoveryAction.java +9 −10 Original line number Diff line number Diff line Loading @@ -94,12 +94,10 @@ final class DeviceDiscoveryAction extends FeatureAction { /** * Constructor. * * @param service an instance of {@link HdmiControlService}. * @param sourceAddress a logical address which initiates this action * @param source an instance of {@link HdmiCecLocalDevice}. */ DeviceDiscoveryAction(HdmiControlService service, int sourceAddress, DeviceDiscoveryCallback callback) { super(service, sourceAddress); DeviceDiscoveryAction(HdmiCecLocalDevice source, DeviceDiscoveryCallback callback) { super(source); mCallback = Preconditions.checkNotNull(callback); } Loading @@ -108,7 +106,7 @@ final class DeviceDiscoveryAction extends FeatureAction { mDevices.clear(); mState = STATE_WAITING_FOR_DEVICE_POLLING; mService.pollDevices(new DevicePollingCallback() { pollDevices(new DevicePollingCallback() { @Override public void onPollingFinished(List<Integer> ackedAddress) { if (ackedAddress.isEmpty()) { Loading Loading @@ -156,7 +154,7 @@ final class DeviceDiscoveryAction extends FeatureAction { if (mayProcessMessageIfCached(address, HdmiCec.MESSAGE_REPORT_PHYSICAL_ADDRESS)) { return; } sendCommand(HdmiCecMessageBuilder.buildGivePhysicalAddress(mSourceAddress, address)); sendCommand(HdmiCecMessageBuilder.buildGivePhysicalAddress(getSourceAddress(), address)); addTimer(mState, TIMEOUT_MS); } Loading @@ -179,7 +177,7 @@ final class DeviceDiscoveryAction extends FeatureAction { if (mayProcessMessageIfCached(address, HdmiCec.MESSAGE_SET_OSD_NAME)) { return; } sendCommand(HdmiCecMessageBuilder.buildGiveOsdNameCommand(mSourceAddress, address)); sendCommand(HdmiCecMessageBuilder.buildGiveOsdNameCommand(getSourceAddress(), address)); addTimer(mState, TIMEOUT_MS); } Loading @@ -203,12 +201,13 @@ final class DeviceDiscoveryAction extends FeatureAction { if (mayProcessMessageIfCached(address, HdmiCec.MESSAGE_DEVICE_VENDOR_ID)) { return; } sendCommand(HdmiCecMessageBuilder.buildGiveDeviceVendorIdCommand(mSourceAddress, address)); sendCommand( HdmiCecMessageBuilder.buildGiveDeviceVendorIdCommand(getSourceAddress(), address)); addTimer(mState, TIMEOUT_MS); } private boolean mayProcessMessageIfCached(int address, int opcode) { HdmiCecMessage message = mService.getCecMessageCache().getMessage(address, opcode); HdmiCecMessage message = getCecMessageCache().getMessage(address, opcode); if (message != null) { processCommand(message); return true; Loading
services/core/java/com/android/server/hdmi/DevicePowerStatusAction.java +9 −8 Original line number Diff line number Diff line Loading @@ -16,9 +16,10 @@ package com.android.server.hdmi; * limitations under the License. */ import android.hardware.hdmi.IHdmiControlCallback; import android.hardware.hdmi.HdmiCec; import android.hardware.hdmi.HdmiCecMessage; import android.hardware.hdmi.HdmiControlManager; import android.hardware.hdmi.IHdmiControlCallback; import android.os.RemoteException; import android.util.Slog; Loading @@ -40,18 +41,18 @@ final class DevicePowerStatusAction extends FeatureAction { private final int mTargetAddress; private final IHdmiControlCallback mCallback; static DevicePowerStatusAction create(HdmiControlService service, int sourceAddress, static DevicePowerStatusAction create(HdmiCecLocalDevice source, int targetAddress, IHdmiControlCallback callback) { if (service == null || callback == null) { if (source == null || callback == null) { Slog.e(TAG, "Wrong arguments"); return null; } return new DevicePowerStatusAction(service, sourceAddress, targetAddress, callback); return new DevicePowerStatusAction(source, targetAddress, callback); } private DevicePowerStatusAction(HdmiControlService service, int sourceAddress, private DevicePowerStatusAction(HdmiCecLocalDevice localDevice, int targetAddress, IHdmiControlCallback callback) { super(service, sourceAddress); super(localDevice); mTargetAddress = targetAddress; mCallback = callback; } Loading @@ -65,8 +66,8 @@ final class DevicePowerStatusAction extends FeatureAction { } private void queryDevicePowerStatus() { mService.sendCecCommand( HdmiCecMessageBuilder.buildGiveDevicePowerStatus(mSourceAddress, mTargetAddress)); sendCommand(HdmiCecMessageBuilder.buildGiveDevicePowerStatus(getSourceAddress(), mTargetAddress)); } @Override Loading
services/core/java/com/android/server/hdmi/DeviceSelectAction.java +12 −14 Original line number Diff line number Diff line Loading @@ -16,10 +16,11 @@ package com.android.server.hdmi; import android.hardware.hdmi.IHdmiControlCallback; import android.hardware.hdmi.HdmiCecDeviceInfo; import android.hardware.hdmi.HdmiCec; import android.hardware.hdmi.HdmiCecDeviceInfo; import android.hardware.hdmi.HdmiCecMessage; import android.hardware.hdmi.HdmiTvClient; import android.hardware.hdmi.IHdmiControlCallback; import android.os.RemoteException; import android.util.Slog; Loading Loading @@ -66,24 +67,20 @@ final class DeviceSelectAction extends FeatureAction { private final HdmiCecDeviceInfo mTarget; private final IHdmiControlCallback mCallback; private final int mSourcePath; private int mPowerStatusCounter = 0; /** * Constructor. * * @param service {@link HdmiControlService} instance * @param sourceAddress logical address of TV initiating this action * @param sourcePath physical address of TV * @param source {@link HdmiCecLocalDevice} instance * @param target target logical device that will be a new active source * @param callback callback object */ public DeviceSelectAction(HdmiControlService service, int sourceAddress, int sourcePath, public DeviceSelectAction(HdmiCecLocalDevice source, HdmiCecDeviceInfo target, IHdmiControlCallback callback) { super(service, sourceAddress); super(source); mCallback = callback; mSourcePath = sourcePath; mTarget = target; } Loading @@ -96,7 +93,7 @@ final class DeviceSelectAction extends FeatureAction { private void queryDevicePowerStatus() { sendCommand(HdmiCecMessageBuilder.buildGiveDevicePowerStatus( mSourceAddress, mTarget.getLogicalAddress())); getSourceAddress(), mTarget.getLogicalAddress())); mState = STATE_WAIT_FOR_REPORT_POWER_STATUS; addTimer(mState, TIMEOUT_MS); } Loading @@ -118,7 +115,8 @@ final class DeviceSelectAction extends FeatureAction { case STATE_WAIT_FOR_ACTIVE_SOURCE: if (opcode == HdmiCec.MESSAGE_ACTIVE_SOURCE && params.length == 2) { int activePath = HdmiUtils.twoBytesToInt(params); ActiveSourceHandler.create(mService, mSourceAddress, mSourcePath, mCallback) ActiveSourceHandler .create(localDevice(), mCallback) .process(cmd.getSource(), activePath); finish(); return true; Loading Loading @@ -174,15 +172,15 @@ final class DeviceSelectAction extends FeatureAction { private void sendSetStreamPath() { sendCommand(HdmiCecMessageBuilder.buildSetStreamPath( mSourceAddress, mTarget.getPhysicalAddress())); getSourceAddress(), mTarget.getPhysicalAddress())); mState = STATE_WAIT_FOR_ACTIVE_SOURCE; addTimer(mState, TIMEOUT_ACTIVE_SOURCE_MS); } private void sendRemoteKeyCommand(int keyCode) { sendCommand(HdmiCecMessageBuilder.buildUserControlPressed(mSourceAddress, sendCommand(HdmiCecMessageBuilder.buildUserControlPressed(getSourceAddress(), mTarget.getLogicalAddress(), keyCode)); sendCommand(HdmiCecMessageBuilder.buildUserControlReleased(mSourceAddress, sendCommand(HdmiCecMessageBuilder.buildUserControlReleased(getSourceAddress(), mTarget.getLogicalAddress())); } Loading
services/core/java/com/android/server/hdmi/FeatureAction.java +64 −19 Original line number Diff line number Diff line Loading @@ -22,6 +22,9 @@ import android.os.Message; import android.util.Slog; import com.android.internal.annotations.VisibleForTesting; import com.android.server.hdmi.HdmiControlService.DevicePollingCallback; import java.util.List; /** * Encapsulates a sequence of CEC/MHL command exchange for a certain feature. Loading @@ -33,14 +36,13 @@ import com.android.internal.annotations.VisibleForTesting; * of the object. All the actual action classes inherit FeatureAction. * * <p>More than one FeatureAction objects can be up and running simultaneously, * maintained by {@link HdmiControlService}. Each action is passed a new command * maintained by {@link HdmiCecLocalDevice}. Each action is passed a new command * arriving from the bus, and either consumes it if the command is what the action expects, * or yields it to other action. * * Declared as package private, accessed by {@link HdmiControlService} only. */ abstract class FeatureAction { private static final String TAG = "FeatureAction"; // Timer handler message used for timeout event Loading @@ -56,19 +58,16 @@ abstract class FeatureAction { // Internal state indicating the progress of action. protected int mState = STATE_NONE; protected final HdmiControlService mService; // Logical address of the device for which the feature action is taken. The commands // generated in an action all use this field as source address. protected final int mSourceAddress; private final HdmiControlService mService; private final HdmiCecLocalDevice mSource; // Timer that manages timeout events. protected ActionTimer mActionTimer; FeatureAction(HdmiControlService service, int sourceAddress) { mService = service; mSourceAddress = sourceAddress; mActionTimer = createActionTimer(service.getServiceLooper()); FeatureAction(HdmiCecLocalDevice source) { mSource = source; mService = mSource.getService(); mActionTimer = createActionTimer(mService.getServiceLooper()); } @VisibleForTesting Loading Loading @@ -175,6 +174,42 @@ abstract class FeatureAction { mService.sendCecCommand(cmd, callback); } protected final void addAndStartAction(FeatureAction action) { mSource.addAndStartAction(action); } protected final <T extends FeatureAction> List<T> getActions(final Class<T> clazz) { return mSource.getActions(clazz); } protected final HdmiCecMessageCache getCecMessageCache() { return mSource.getCecMessageCache(); } /** * Remove the action from the action queue. This is called after the action finishes * its role. * * @param action */ protected final void removeAction(FeatureAction action) { mSource.removeAction(action); } protected final <T extends FeatureAction> void removeAction(final Class<T> clazz) { mSource.removeActionExcept(clazz, null); } protected final <T extends FeatureAction> void removeActionExcept(final Class<T> clazz, final FeatureAction exception) { mSource.removeActionExcept(clazz, exception); } protected final void pollDevices(DevicePollingCallback callback, int pickStrategy, int retryCount) { mService.pollDevices(callback, pickStrategy, retryCount); } /** * Clean up action's state. * Loading @@ -194,13 +229,23 @@ abstract class FeatureAction { removeAction(this); } /** * Remove the action from the action queue. This is called after the action finishes * its role. * * @param action */ private void removeAction(FeatureAction action) { mService.removeAction(action); protected final HdmiCecLocalDevice localDevice() { return mSource; } protected final HdmiCecLocalDevicePlayback playback() { return (HdmiCecLocalDevicePlayback) mSource; } protected final HdmiCecLocalDeviceTv tv() { return (HdmiCecLocalDeviceTv) mSource; } protected final int getSourceAddress() { return mSource.getDeviceInfo().getLogicalAddress(); } protected final int getSourcePath() { return mSource.getDeviceInfo().getPhysicalAddress(); } }