diff options
author | Jinsuk Kim <jinsukkim@google.com> | 2014-07-04 02:24:30 +0000 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2014-07-02 19:52:36 +0000 |
commit | ea1e84b8ca6cdfa971b9e868c3ecd0569863e218 (patch) | |
tree | e2dece250438eec145ff669a4ddde0505bcedb1e /services | |
parent | 517cc7f99effa4ab174db560548b8495adfdd4e0 (diff) | |
parent | 9c37e1f53ea4734bfe5ae156dc5399ce5f2c7ccc (diff) | |
download | frameworks_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.java | 42 | ||||
-rw-r--r-- | services/core/java/com/android/server/hdmi/HdmiControlService.java | 60 |
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); |