diff options
author | Jinsuk Kim <jinsukkim@google.com> | 2014-06-18 10:00:39 +0900 |
---|---|---|
committer | Jinsuk Kim <jinsukkim@google.com> | 2014-06-18 03:53:16 +0000 |
commit | a062a9339add79a84862a34e363e3e454a6ec435 (patch) | |
tree | 762956e7db68884b17ca92f5374b06ddfec66de9 | |
parent | df48918c3f54043e2f4c4c333d407867f8d2339a (diff) | |
download | frameworks_base-a062a9339add79a84862a34e363e3e454a6ec435.zip frameworks_base-a062a9339add79a84862a34e363e3e454a6ec435.tar.gz frameworks_base-a062a9339add79a84862a34e363e3e454a6ec435.tar.bz2 |
Implement portSelect/sendKeyEvent for HdmiControlService
TIF (TV Input Framework) uses these API to switch inputs, send
keys for selected device on CEC bus. Also renamed getActiveInput
to getActivePortId to use a unified term for port/input.
Change-Id: I8196825c0d960988cc1c0bb58a628ccd8ab1957e
6 files changed, 110 insertions, 17 deletions
diff --git a/core/java/android/hardware/hdmi/HdmiCec.java b/core/java/android/hardware/hdmi/HdmiCec.java index 8ad9463..d86dd5e 100644 --- a/core/java/android/hardware/hdmi/HdmiCec.java +++ b/core/java/android/hardware/hdmi/HdmiCec.java @@ -185,6 +185,7 @@ public final class HdmiCec { public static final int RESULT_TARGET_NOT_AVAILABLE = 3; public static final int RESULT_ALREADY_IN_PROGRESS = 4; public static final int RESULT_EXCEPTION = 5; + public static final int RESULT_INCORRECT_MODE = 6; private static final int[] ADDRESS_TO_TYPE = { DEVICE_TV, // ADDR_TV diff --git a/services/core/java/com/android/server/hdmi/ActiveSourceHandler.java b/services/core/java/com/android/server/hdmi/ActiveSourceHandler.java index 23cf40b..74eaf2a 100644 --- a/services/core/java/com/android/server/hdmi/ActiveSourceHandler.java +++ b/services/core/java/com/android/server/hdmi/ActiveSourceHandler.java @@ -72,9 +72,9 @@ final class ActiveSourceHandler { } if (!mSource.isInPresetInstallationMode()) { - int prevActiveInput = mSource.getActiveInput(); + int prevActiveInput = mSource.getActivePortId(); mSource.updateActiveDevice(deviceLogicalAddress, routingPath); - if (prevActiveInput != mSource.getActiveInput()) { + if (prevActiveInput != mSource.getActivePortId()) { // TODO: change port input here. } invokeCallback(HdmiCec.RESULT_SUCCESS); diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java index 08d7786..f86d655 100644 --- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java +++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java @@ -372,15 +372,28 @@ abstract class HdmiCecLocalDevice { } /** - * Returns the ID of the active HDMI port. The active input is the port that has the active - * routing path connected directly or indirectly under the device hierarchy. + * Returns the ID of the active HDMI port. The active port is the one that has the active + * routing path connected to it directly or indirectly under the device hierarchy. */ - int getActiveInput() { + int getActivePortId() { synchronized (mLock) { return mService.pathToPortId(mActiveRoutingPath); } } + /** + * Update the active port. + * + * @param portId the new active port id + */ + void setActivePortId(int portId) { + synchronized (mLock) { + // We update active routing path instead, since we get the active port id from + // the active routing path. + mActiveRoutingPath = mService.portIdToPath(portId); + } + } + void updateActiveDevice(int logicalAddress, int physicalAddress) { synchronized (mLock) { mActiveSource = logicalAddress; diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java index 18a3bbf..353f603 100644 --- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java +++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java @@ -87,6 +87,60 @@ final class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice { addAndStartAction(new DeviceSelectAction(this, targetDevice, callback)); } + /** + * Performs the action routing control. + * + * @param portId new HDMI port to route to + * @param callback callback object to report the result with + */ + void portSelect(int portId, IHdmiControlCallback callback) { + assertRunOnServiceThread(); + if (isInPresetInstallationMode()) { + invokeCallback(callback, HdmiCec.RESULT_INCORRECT_MODE); + return; + } + // Make sure this call does not stem from <Active Source> message reception, in + // which case the two ports will be the same. + if (portId == getActivePortId()) { + invokeCallback(callback, HdmiCec.RESULT_SUCCESS); + return; + } + setActivePortId(portId); + + // TODO: Return immediately if the operation is triggered by <Text/Image View On> + // TODO: Handle invalid port id / active input which should be treated as an + // internal tuner. + + removeAction(RoutingControlAction.class); + + int oldPath = mService.portIdToPath(mService.portIdToPath(getActivePortId())); + int newPath = mService.portIdToPath(portId); + HdmiCecMessage routingChange = + HdmiCecMessageBuilder.buildRoutingChange(mAddress, oldPath, newPath); + mService.sendCecCommand(routingChange); + addAndStartAction(new RoutingControlAction(this, newPath, callback)); + } + + /** + * Sends key to a target CEC device. + * + * @param keyCode key code to send. Defined in {@link KeyEvent}. + * @param isPressed true if this is keypress event + */ + void sendKeyEvent(int keyCode, boolean isPressed) { + assertRunOnServiceThread(); + List<SendKeyAction> action = getActions(SendKeyAction.class); + if (!action.isEmpty()) { + action.get(0).processKeyEvent(keyCode, isPressed); + } else { + if (isPressed) { + addAndStartAction(new SendKeyAction(this, getActiveSource(), keyCode)); + } else { + Slog.w(TAG, "Discard key release event"); + } + } + } + private static void invokeCallback(IHdmiControlCallback callback, int result) { try { callback.onComplete(result); diff --git a/services/core/java/com/android/server/hdmi/HdmiControlService.java b/services/core/java/com/android/server/hdmi/HdmiControlService.java index 10da756..fddb833 100644 --- a/services/core/java/com/android/server/hdmi/HdmiControlService.java +++ b/services/core/java/com/android/server/hdmi/HdmiControlService.java @@ -507,7 +507,7 @@ public final class HdmiControlService extends SystemService { public void run() { HdmiCecLocalDeviceTv tv = tv(); if (tv == null) { - Slog.w(TAG, "Local playback device not available"); + Slog.w(TAG, "Local tv device not available"); invokeCallback(callback, HdmiCec.RESULT_SOURCE_NOT_AVAILABLE); return; } @@ -517,6 +517,41 @@ public final class HdmiControlService extends SystemService { } @Override + public void portSelect(final int portId, final IHdmiControlCallback callback) { + enforceAccessPermission(); + runOnServiceThread(new Runnable() { + @Override + public void run() { + HdmiCecLocalDeviceTv tv = tv(); + if (tv == null) { + Slog.w(TAG, "Local tv device not available"); + invokeCallback(callback, HdmiCec.RESULT_SOURCE_NOT_AVAILABLE); + return; + } + tv.portSelect(portId, callback); + } + }); + } + + @Override + public void sendKeyEvent(final int keyCode, final boolean isPressed) { + enforceAccessPermission(); + runOnServiceThread(new Runnable() { + @Override + public void run() { + // TODO: sendKeyEvent is for TV device only for now. Allow other + // local devices of different types to use this as well. + HdmiCecLocalDeviceTv tv = tv(); + if (tv == null) { + Slog.w(TAG, "Local tv device not available"); + return; + } + tv.sendKeyEvent(keyCode, isPressed); + } + }); + } + + @Override public void oneTouchPlay(final IHdmiControlCallback callback) { enforceAccessPermission(); runOnServiceThread(new Runnable() { @@ -572,16 +607,6 @@ public final class HdmiControlService extends SystemService { } @Override - public void portSelect(int portId, IHdmiControlCallback callback) { - // TODO: Implement this - } - - @Override - public void sendKeyEvent(int keyCode, boolean isPressed) { - // TODO: Implement this - } - - @Override public List<HdmiPortInfo> getPortInfo() { enforceAccessPermission(); return mPortInfo; diff --git a/services/core/java/com/android/server/hdmi/RoutingControlAction.java b/services/core/java/com/android/server/hdmi/RoutingControlAction.java index 2eec846..0d657b2 100644 --- a/services/core/java/com/android/server/hdmi/RoutingControlAction.java +++ b/services/core/java/com/android/server/hdmi/RoutingControlAction.java @@ -196,7 +196,7 @@ final class RoutingControlAction extends FeatureAction { // Called whenever an HDMI input of the TV shall become the active input. private boolean maybeChangeActiveInput(int path) { - if (localDevice().getActiveInput() == localDevice().pathToPortId(path)) { + if (localDevice().getActivePortId() == localDevice().pathToPortId(path)) { return false; } // TODO: Remember the currently active input |