Methods Summary |
---|
public android.media.tv.ITvInputHardware | acquireHardware(int deviceId, android.media.tv.ITvInputHardwareCallback callback, android.media.tv.TvInputInfo info, int callingUid, int resolvedUserId)Create a TvInputHardware object with a specific deviceId. One service at a time can access
the object, and if more than one process attempts to create hardware with the same deviceId,
the latest service will get the object and all the other hardware are released. The
release is notified via ITvInputHardwareCallback.onReleased().
if (callback == null) {
throw new NullPointerException();
}
synchronized (mLock) {
Connection connection = mConnections.get(deviceId);
if (connection == null) {
Slog.e(TAG, "Invalid deviceId : " + deviceId);
return null;
}
if (checkUidChangedLocked(connection, callingUid, resolvedUserId)) {
TvInputHardwareImpl hardware =
new TvInputHardwareImpl(connection.getHardwareInfoLocked());
try {
callback.asBinder().linkToDeath(connection, 0);
} catch (RemoteException e) {
hardware.release();
return null;
}
connection.resetLocked(hardware, callback, info, callingUid, resolvedUserId);
}
return connection.getHardwareLocked();
}
|
public void | addHardwareTvInput(int deviceId, android.media.tv.TvInputInfo info)
synchronized (mLock) {
String oldInputId = mHardwareInputIdMap.get(deviceId);
if (oldInputId != null) {
Slog.w(TAG, "Trying to override previous registration: old = "
+ mInputMap.get(oldInputId) + ":" + deviceId + ", new = "
+ info + ":" + deviceId);
}
mHardwareInputIdMap.put(deviceId, info.getId());
mInputMap.put(info.getId(), info);
// Process pending state changes
// For logical HDMI devices, they have information from HDMI CEC signals.
for (int i = 0; i < mHdmiStateMap.size(); ++i) {
TvInputHardwareInfo hardwareInfo =
findHardwareInfoForHdmiPortLocked(mHdmiStateMap.keyAt(i));
if (hardwareInfo == null) {
continue;
}
String inputId = mHardwareInputIdMap.get(hardwareInfo.getDeviceId());
if (inputId != null && inputId.equals(info.getId())) {
mHandler.obtainMessage(ListenerHandler.STATE_CHANGED,
convertConnectedToState(mHdmiStateMap.valueAt(i)), 0,
inputId).sendToTarget();
return;
}
}
// For the rest of the devices, we can tell by the number of available streams.
Connection connection = mConnections.get(deviceId);
if (connection != null) {
mHandler.obtainMessage(ListenerHandler.STATE_CHANGED,
convertConnectedToState(connection.getConfigsLocked().length > 0), 0,
info.getId()).sendToTarget();
return;
}
}
|
public void | addHdmiTvInput(int id, android.media.tv.TvInputInfo info)
if (info.getType() != TvInputInfo.TYPE_HDMI) {
throw new IllegalArgumentException("info (" + info + ") has non-HDMI type.");
}
synchronized (mLock) {
String parentId = info.getParentId();
int parentIndex = indexOfEqualValue(mHardwareInputIdMap, parentId);
if (parentIndex < 0) {
throw new IllegalArgumentException("info (" + info + ") has invalid parentId.");
}
String oldInputId = mHdmiInputIdMap.get(id);
if (oldInputId != null) {
Slog.w(TAG, "Trying to override previous registration: old = "
+ mInputMap.get(oldInputId) + ":" + id + ", new = "
+ info + ":" + id);
}
mHdmiInputIdMap.put(id, info.getId());
mInputMap.put(info.getId(), info);
}
|
private void | buildHardwareListLocked()
mHardwareList.clear();
for (int i = 0; i < mConnections.size(); ++i) {
mHardwareList.add(mConnections.valueAt(i).getHardwareInfoLocked());
}
|
public boolean | captureFrame(java.lang.String inputId, android.view.Surface surface, android.media.tv.TvStreamConfig config, int callingUid, int resolvedUserId)Take a snapshot of the given TV input into the provided Surface.
synchronized (mLock) {
int deviceId = findDeviceIdForInputIdLocked(inputId);
if (deviceId < 0) {
Slog.e(TAG, "Invalid inputId : " + inputId);
return false;
}
Connection connection = mConnections.get(deviceId);
final TvInputHardwareImpl hardwareImpl = connection.getHardwareImplLocked();
if (hardwareImpl != null) {
// Stop previous capture.
Runnable runnable = connection.getOnFirstFrameCapturedLocked();
if (runnable != null) {
runnable.run();
connection.setOnFirstFrameCapturedLocked(null);
}
boolean result = hardwareImpl.startCapture(surface, config);
if (result) {
connection.setOnFirstFrameCapturedLocked(new Runnable() {
@Override
public void run() {
hardwareImpl.stopCapture(config);
}
});
}
return result;
}
}
return false;
|
private boolean | checkUidChangedLocked(com.android.server.tv.TvInputHardwareManager$Connection connection, int callingUid, int resolvedUserId)
Integer connectionCallingUid = connection.getCallingUidLocked();
Integer connectionResolvedUserId = connection.getResolvedUserIdLocked();
if (connectionCallingUid == null || connectionResolvedUserId == null) {
return true;
}
if (connectionCallingUid != callingUid || connectionResolvedUserId != resolvedUserId) {
return true;
}
return false;
|
private int | convertConnectedToState(boolean connected)
if (connected) {
return INPUT_STATE_CONNECTED;
} else {
return INPUT_STATE_DISCONNECTED;
}
|
private int | findDeviceIdForInputIdLocked(java.lang.String inputId)
for (int i = 0; i < mConnections.size(); ++i) {
Connection connection = mConnections.get(i);
if (connection.getInfoLocked().getId().equals(inputId)) {
return i;
}
}
return -1;
|
private android.media.tv.TvInputHardwareInfo | findHardwareInfoForHdmiPortLocked(int port)
for (TvInputHardwareInfo hardwareInfo : mHardwareList) {
if (hardwareInfo.getType() == TvInputHardwareInfo.TV_INPUT_TYPE_HDMI
&& hardwareInfo.getHdmiPortId() == port) {
return hardwareInfo;
}
}
return null;
|
public java.util.List | getAvailableTvStreamConfigList(java.lang.String inputId, int callingUid, int resolvedUserId)Get the list of TvStreamConfig which is buffered mode.
List<TvStreamConfig> configsList = new ArrayList<TvStreamConfig>();
synchronized (mLock) {
int deviceId = findDeviceIdForInputIdLocked(inputId);
if (deviceId < 0) {
Slog.e(TAG, "Invalid inputId : " + inputId);
return configsList;
}
Connection connection = mConnections.get(deviceId);
for (TvStreamConfig config : connection.getConfigsLocked()) {
if (config.getType() == TvStreamConfig.STREAM_TYPE_BUFFER_PRODUCER) {
configsList.add(config);
}
}
}
return configsList;
|
public java.util.List | getHardwareList()
synchronized (mLock) {
return Collections.unmodifiableList(mHardwareList);
}
|
public java.util.List | getHdmiDeviceList()
synchronized (mLock) {
return Collections.unmodifiableList(mHdmiDeviceList);
}
|
private float | getMediaStreamVolume()
return mUseMasterVolume ? 1.0f : ((float) mCurrentIndex / (float) mCurrentMaxIndex);
|
private void | handleVolumeChange(android.content.Context context, android.content.Intent intent)
String action = intent.getAction();
if (action.equals(AudioManager.VOLUME_CHANGED_ACTION)) {
int streamType = intent.getIntExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE, -1);
if (streamType != AudioManager.STREAM_MUSIC) {
return;
}
int index = intent.getIntExtra(AudioManager.EXTRA_VOLUME_STREAM_VALUE, 0);
if (index == mCurrentIndex) {
return;
}
mCurrentIndex = index;
} else if (action.equals(AudioManager.STREAM_MUTE_CHANGED_ACTION)) {
int streamType = intent.getIntExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE, -1);
if (streamType != AudioManager.STREAM_MUSIC) {
return;
}
// volume index will be updated at onMediaStreamVolumeChanged() through updateVolume().
} else {
Slog.w(TAG, "Unrecognized intent: " + intent);
return;
}
synchronized (mLock) {
for (int i = 0; i < mConnections.size(); ++i) {
TvInputHardwareImpl hardwareImpl = mConnections.valueAt(i).getHardwareImplLocked();
if (hardwareImpl != null) {
hardwareImpl.onMediaStreamVolumeChanged();
}
}
}
|
private static int | indexOfEqualValue(android.util.SparseArray map, T value)
for (int i = 0; i < map.size(); ++i) {
if (map.valueAt(i).equals(value)) {
return i;
}
}
return -1;
|
private static boolean | intArrayContains(int[] array, int value)
for (int element : array) {
if (element == value) return true;
}
return false;
|
public void | onBootPhase(int phase)
if (phase == SystemService.PHASE_SYSTEM_SERVICES_READY) {
mHdmiControlService = IHdmiControlService.Stub.asInterface(ServiceManager.getService(
Context.HDMI_CONTROL_SERVICE));
if (mHdmiControlService != null) {
try {
mHdmiControlService.addHotplugEventListener(mHdmiHotplugEventListener);
mHdmiControlService.addDeviceEventListener(mHdmiDeviceEventListener);
mHdmiControlService.addSystemAudioModeChangeListener(
mHdmiSystemAudioModeChangeListener);
mHdmiDeviceList.addAll(mHdmiControlService.getInputDevices());
} catch (RemoteException e) {
Slog.w(TAG, "Error registering listeners to HdmiControlService:", e);
}
} else {
Slog.w(TAG, "HdmiControlService is not available");
}
if (!mUseMasterVolume) {
final IntentFilter filter = new IntentFilter();
filter.addAction(AudioManager.VOLUME_CHANGED_ACTION);
filter.addAction(AudioManager.STREAM_MUTE_CHANGED_ACTION);
mContext.registerReceiver(mVolumeReceiver, filter);
}
updateVolume();
}
|
public void | onDeviceAvailable(android.media.tv.TvInputHardwareInfo info, android.media.tv.TvStreamConfig[] configs)
synchronized (mLock) {
Connection connection = new Connection(info);
connection.updateConfigsLocked(configs);
mConnections.put(info.getDeviceId(), connection);
buildHardwareListLocked();
mHandler.obtainMessage(
ListenerHandler.HARDWARE_DEVICE_ADDED, 0, 0, info).sendToTarget();
if (info.getType() == TvInputHardwareInfo.TV_INPUT_TYPE_HDMI) {
processPendingHdmiDeviceEventsLocked();
}
}
|
public void | onDeviceUnavailable(int deviceId)
synchronized (mLock) {
Connection connection = mConnections.get(deviceId);
if (connection == null) {
Slog.e(TAG, "onDeviceUnavailable: Cannot find a connection with " + deviceId);
return;
}
connection.resetLocked(null, null, null, null, null);
mConnections.remove(deviceId);
buildHardwareListLocked();
TvInputHardwareInfo info = connection.getHardwareInfoLocked();
if (info.getType() == TvInputHardwareInfo.TV_INPUT_TYPE_HDMI) {
// Remove HDMI devices linked with this hardware.
for (Iterator<HdmiDeviceInfo> it = mHdmiDeviceList.iterator(); it.hasNext();) {
HdmiDeviceInfo deviceInfo = it.next();
if (deviceInfo.getPortId() == info.getHdmiPortId()) {
mHandler.obtainMessage(ListenerHandler.HDMI_DEVICE_REMOVED, 0, 0,
deviceInfo).sendToTarget();
it.remove();
}
}
}
mHandler.obtainMessage(
ListenerHandler.HARDWARE_DEVICE_REMOVED, 0, 0, info).sendToTarget();
}
|
public void | onFirstFrameCaptured(int deviceId, int streamId)
synchronized (mLock) {
Connection connection = mConnections.get(deviceId);
if (connection == null) {
Slog.e(TAG, "FirstFrameCaptured: Cannot find a connection with "
+ deviceId);
return;
}
Runnable runnable = connection.getOnFirstFrameCapturedLocked();
if (runnable != null) {
runnable.run();
connection.setOnFirstFrameCapturedLocked(null);
}
}
|
public void | onStreamConfigurationChanged(int deviceId, android.media.tv.TvStreamConfig[] configs)
synchronized (mLock) {
Connection connection = mConnections.get(deviceId);
if (connection == null) {
Slog.e(TAG, "StreamConfigurationChanged: Cannot find a connection with "
+ deviceId);
return;
}
connection.updateConfigsLocked(configs);
String inputId = mHardwareInputIdMap.get(deviceId);
if (inputId != null) {
mHandler.obtainMessage(ListenerHandler.STATE_CHANGED,
convertConnectedToState(configs.length > 0), 0, inputId).sendToTarget();
}
ITvInputHardwareCallback callback = connection.getCallbackLocked();
if (callback != null) {
try {
callback.onStreamConfigChanged(configs);
} catch (RemoteException e) {
Slog.e(TAG, "error in onStreamConfigurationChanged", e);
}
}
}
|
private void | processPendingHdmiDeviceEventsLocked()
for (Iterator<Message> it = mPendingHdmiDeviceEvents.iterator(); it.hasNext(); ) {
Message msg = it.next();
HdmiDeviceInfo deviceInfo = (HdmiDeviceInfo) msg.obj;
TvInputHardwareInfo hardwareInfo =
findHardwareInfoForHdmiPortLocked(deviceInfo.getPortId());
if (hardwareInfo != null) {
msg.sendToTarget();
it.remove();
}
}
|
public void | releaseHardware(int deviceId, android.media.tv.ITvInputHardware hardware, int callingUid, int resolvedUserId)Release the specified hardware.
synchronized (mLock) {
Connection connection = mConnections.get(deviceId);
if (connection == null) {
Slog.e(TAG, "Invalid deviceId : " + deviceId);
return;
}
if (connection.getHardwareLocked() != hardware
|| checkUidChangedLocked(connection, callingUid, resolvedUserId)) {
return;
}
connection.resetLocked(null, null, null, null, null);
}
|
public void | removeTvInput(java.lang.String inputId)
synchronized (mLock) {
mInputMap.remove(inputId);
int hardwareIndex = indexOfEqualValue(mHardwareInputIdMap, inputId);
if (hardwareIndex >= 0) {
mHardwareInputIdMap.removeAt(hardwareIndex);
}
int deviceIndex = indexOfEqualValue(mHdmiInputIdMap, inputId);
if (deviceIndex >= 0) {
mHdmiInputIdMap.removeAt(deviceIndex);
}
}
|
private void | updateVolume()
mCurrentMaxIndex = mAudioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
mCurrentIndex = mAudioManager.getStreamVolume(AudioManager.STREAM_MUSIC);
|