summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJinsuk Kim <jinsukkim@google.com>2014-06-18 10:00:39 +0900
committerJinsuk Kim <jinsukkim@google.com>2014-06-18 03:53:16 +0000
commita062a9339add79a84862a34e363e3e454a6ec435 (patch)
tree762956e7db68884b17ca92f5374b06ddfec66de9
parentdf48918c3f54043e2f4c4c333d407867f8d2339a (diff)
downloadframeworks_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
-rw-r--r--core/java/android/hardware/hdmi/HdmiCec.java1
-rw-r--r--services/core/java/com/android/server/hdmi/ActiveSourceHandler.java4
-rw-r--r--services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java19
-rw-r--r--services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java54
-rw-r--r--services/core/java/com/android/server/hdmi/HdmiControlService.java47
-rw-r--r--services/core/java/com/android/server/hdmi/RoutingControlAction.java2
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