summaryrefslogtreecommitdiffstats
path: root/services
diff options
context:
space:
mode:
authorJinsuk Kim <jinsukkim@google.com>2014-07-04 02:24:30 +0000
committerAndroid (Google) Code Review <android-gerrit@google.com>2014-07-02 19:52:36 +0000
commitea1e84b8ca6cdfa971b9e868c3ecd0569863e218 (patch)
treee2dece250438eec145ff669a4ddde0505bcedb1e /services
parent517cc7f99effa4ab174db560548b8495adfdd4e0 (diff)
parent9c37e1f53ea4734bfe5ae156dc5399ce5f2c7ccc (diff)
downloadframeworks_base-ea1e84b8ca6cdfa971b9e868c3ecd0569863e218.zip
frameworks_base-ea1e84b8ca6cdfa971b9e868c3ecd0569863e218.tar.gz
frameworks_base-ea1e84b8ca6cdfa971b9e868c3ecd0569863e218.tar.bz2
Merge "Implement some apis for TV Input Framework and HdmiControlService"
Diffstat (limited to 'services')
-rw-r--r--services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java42
-rw-r--r--services/core/java/com/android/server/hdmi/HdmiControlService.java60
2 files changed, 89 insertions, 13 deletions
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java
index 0881af3..cd4ad38 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java
@@ -21,6 +21,7 @@ import android.hardware.hdmi.HdmiCecDeviceInfo;
import android.hardware.hdmi.HdmiCecMessage;
import android.hardware.hdmi.IHdmiControlCallback;
import android.media.AudioSystem;
+import android.os.IBinder;
import android.os.RemoteException;
import android.util.Slog;
import android.util.SparseArray;
@@ -69,9 +70,9 @@ final class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice {
// Copy of mDeviceInfos to guarantee thread-safety.
@GuardedBy("mLock")
private List<HdmiCecDeviceInfo> mSafeAllDeviceInfos = Collections.emptyList();
- // All external cec device which excludes local devices.
+ // All external cec input(source) devices. Does not include system audio device.
@GuardedBy("mLock")
- private List<HdmiCecDeviceInfo> mSafeExternalDeviceInfos = Collections.emptyList();
+ private List<HdmiCecDeviceInfo> mSafeExternalInputs = Collections.emptyList();
// Map-like container of all cec devices including local ones.
// A logical address of device is used as key of container.
@@ -186,6 +187,7 @@ final class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice {
setPrevPortId(portId);
// TODO: Actually switch the physical port here. Handle PAP/PIP as well.
// Show OSD port change banner
+ mService.invokeInputChangeListener(getActiveSource());
}
@ServiceThreadOnly
@@ -807,17 +809,11 @@ final class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice {
}
/**
- * Return a list of {@link HdmiCecDeviceInfo}.
- *
- * @param includeLocalDevice whether to include local device in result.
+ * Return external input devices.
*/
- List<HdmiCecDeviceInfo> getSafeDeviceInfoList(boolean includeLocalDevice) {
+ List<HdmiCecDeviceInfo> getSafeExternalInputs() {
synchronized (mLock) {
- if (includeLocalDevice) {
- return mSafeAllDeviceInfos;
- } else {
- return mSafeExternalDeviceInfos;
- }
+ return mSafeExternalInputs;
}
}
@@ -825,11 +821,31 @@ final class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice {
private void updateSafeDeviceInfoList() {
assertRunOnServiceThread();
List<HdmiCecDeviceInfo> copiedDevices = HdmiUtils.sparseArrayToList(mDeviceInfos);
- List<HdmiCecDeviceInfo> externalDeviceInfos = getDeviceInfoList(false);
+ List<HdmiCecDeviceInfo> externalInputs = getInputDevices();
synchronized (mLock) {
mSafeAllDeviceInfos = copiedDevices;
- mSafeExternalDeviceInfos = externalDeviceInfos;
+ mSafeExternalInputs = externalInputs;
+ }
+ }
+
+ /**
+ * Return a list of external cec input (source) devices.
+ *
+ * <p>Note that this effectively excludes non-source devices like system audio,
+ * secondary TV.
+ */
+ private List<HdmiCecDeviceInfo> getInputDevices() {
+ ArrayList<HdmiCecDeviceInfo> infoList = new ArrayList<>();
+ for (int i = 0; i < mDeviceInfos.size(); ++i) {
+ HdmiCecDeviceInfo info = mDeviceInfos.valueAt(i);
+ if (isLocalDeviceAddress(i)) {
+ continue;
+ }
+ if (info.isSourceType()) {
+ infoList.add(info);
+ }
}
+ return infoList;
}
@ServiceThreadOnly
diff --git a/services/core/java/com/android/server/hdmi/HdmiControlService.java b/services/core/java/com/android/server/hdmi/HdmiControlService.java
index 95d8333..a6936c0 100644
--- a/services/core/java/com/android/server/hdmi/HdmiControlService.java
+++ b/services/core/java/com/android/server/hdmi/HdmiControlService.java
@@ -30,6 +30,7 @@ import android.hardware.hdmi.IHdmiControlCallback;
import android.hardware.hdmi.IHdmiControlService;
import android.hardware.hdmi.IHdmiDeviceEventListener;
import android.hardware.hdmi.IHdmiHotplugEventListener;
+import android.hardware.hdmi.IHdmiInputChangeListener;
import android.hardware.hdmi.IHdmiSystemAudioModeChangeListener;
import android.media.AudioManager;
import android.os.Build;
@@ -139,6 +140,12 @@ public final class HdmiControlService extends SystemService {
private final ArrayList<DeviceEventListenerRecord> mDeviceEventListenerRecords =
new ArrayList<>();
+ @GuardedBy("mLock")
+ private IHdmiInputChangeListener mInputChangeListener;
+
+ @GuardedBy("mLock")
+ private InputChangeListenerRecord mInputChangeListenerRecord;
+
// Set to true while HDMI control is enabled. If set to false, HDMI-CEC/MHL protocol
// handling will be disabled and no request will be handled.
@GuardedBy("mLock")
@@ -773,6 +780,24 @@ public final class HdmiControlService extends SystemService {
}
@Override
+ public void setInputChangeListener(final IHdmiInputChangeListener listener) {
+ enforceAccessPermission();
+ HdmiControlService.this.setInputChangeListener(listener);
+ }
+
+ @Override
+ public List<HdmiCecDeviceInfo> getInputDevices() {
+ enforceAccessPermission();
+ // No need to hold the lock for obtaining TV device as the local device instance
+ // is preserved while the HDMI control is enabled.
+ HdmiCecLocalDeviceTv tv = tv();
+ if (tv == null) {
+ return Collections.emptyList();
+ }
+ return tv.getSafeExternalInputs();
+ }
+
+ @Override
public void setControlEnabled(final boolean enabled) {
enforceAccessPermission();
synchronized (mLock) {
@@ -981,6 +1006,41 @@ public final class HdmiControlService extends SystemService {
}
}
+ private final class InputChangeListenerRecord implements IBinder.DeathRecipient {
+ @Override
+ public void binderDied() {
+ synchronized (mLock) {
+ mInputChangeListener = null;
+ }
+ }
+ }
+
+ private void setInputChangeListener(IHdmiInputChangeListener listener) {
+ synchronized (mLock) {
+ mInputChangeListenerRecord = new InputChangeListenerRecord();
+ try {
+ listener.asBinder().linkToDeath(mInputChangeListenerRecord, 0);
+ } catch (RemoteException e) {
+ Slog.w(TAG, "Listener already died");
+ return;
+ }
+ mInputChangeListener = listener;
+ }
+ }
+
+ void invokeInputChangeListener(int activeAddress) {
+ synchronized (mLock) {
+ if (mInputChangeListener != null) {
+ HdmiCecDeviceInfo activeSource = getDeviceInfo(activeAddress);
+ try {
+ mInputChangeListener.onChanged(activeSource);
+ } catch (RemoteException e) {
+ Slog.w(TAG, "Exception thrown by IHdmiInputChangeListener: " + e);
+ }
+ }
+ }
+ }
+
private void invokeCallback(IHdmiControlCallback callback, int result) {
try {
callback.onComplete(result);