am 1dc7352e: am d0f94173: Merge "TIF: Extend multiple TV input per service for HDMI logical devices" into lmp-dev
* commit '1dc7352eacde37dac5459f0bc82c868e9548b521': TIF: Extend multiple TV input per service for HDMI logical devices
This commit is contained in:
@@ -64,11 +64,6 @@ interface ITvInputManager {
|
||||
|
||||
// For TV input hardware binding
|
||||
List<TvInputHardwareInfo> getHardwareList();
|
||||
/*
|
||||
* All TvInputServices which want to use hardware must call this method on
|
||||
* BOOT_COMPLETE.
|
||||
*/
|
||||
void registerTvInputInfo(in TvInputInfo info, int deviceId);
|
||||
ITvInputHardware acquireTvInputHardware(int deviceId, in ITvInputHardwareCallback callback,
|
||||
in TvInputInfo info, int userId);
|
||||
void releaseTvInputHardware(int deviceId, in ITvInputHardware hardware, int userId);
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package android.media.tv;
|
||||
|
||||
import android.hardware.hdmi.HdmiCecDeviceInfo;
|
||||
import android.media.tv.ITvInputServiceCallback;
|
||||
import android.media.tv.ITvInputSessionCallback;
|
||||
import android.media.tv.TvInputHardwareInfo;
|
||||
@@ -32,6 +33,8 @@ oneway interface ITvInputService {
|
||||
in String inputId);
|
||||
|
||||
// For hardware TvInputService
|
||||
void notifyHardwareAdded(in TvInputHardwareInfo info);
|
||||
void notifyHardwareRemoved(int deviceId);
|
||||
void notifyHardwareAdded(in TvInputHardwareInfo hardwareInfo);
|
||||
void notifyHardwareRemoved(in TvInputHardwareInfo hardwareInfo);
|
||||
void notifyHdmiCecDeviceAdded(in HdmiCecDeviceInfo cecDeviceInfo);
|
||||
void notifyHdmiCecDeviceRemoved(in HdmiCecDeviceInfo cecDeviceInfo);
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ import android.media.tv.TvInputInfo;
|
||||
* @hide
|
||||
*/
|
||||
oneway interface ITvInputServiceCallback {
|
||||
void addTvInput(in TvInputInfo inputInfo);
|
||||
void addHardwareTvInput(in int deviceID, in TvInputInfo inputInfo);
|
||||
void addHdmiCecTvInput(in int logicalAddress, in TvInputInfo inputInfo);
|
||||
void removeTvInput(in String inputId);
|
||||
}
|
||||
|
||||
@@ -122,7 +122,8 @@ public final class TvInputInfo implements Parcelable {
|
||||
public static TvInputInfo createTvInputInfo(Context context, ResolveInfo service)
|
||||
throws XmlPullParserException, IOException {
|
||||
return createTvInputInfo(context, service, generateInputIdForComponentName(
|
||||
new ComponentName(service.serviceInfo.packageName, service.serviceInfo.name)));
|
||||
new ComponentName(service.serviceInfo.packageName, service.serviceInfo.name)),
|
||||
null);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -134,10 +135,10 @@ public final class TvInputInfo implements Parcelable {
|
||||
* @hide
|
||||
*/
|
||||
public static TvInputInfo createTvInputInfo(Context context, ResolveInfo service,
|
||||
HdmiCecDeviceInfo cecInfo) throws XmlPullParserException, IOException {
|
||||
HdmiCecDeviceInfo cecInfo, String parentId) throws XmlPullParserException, IOException {
|
||||
return createTvInputInfo(context, service, generateInputIdForHdmiCec(
|
||||
new ComponentName(service.serviceInfo.packageName, service.serviceInfo.name),
|
||||
cecInfo));
|
||||
cecInfo), parentId);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -152,11 +153,11 @@ public final class TvInputInfo implements Parcelable {
|
||||
TvInputHardwareInfo hardwareInfo) throws XmlPullParserException, IOException {
|
||||
return createTvInputInfo(context, service, generateInputIdForHardware(
|
||||
new ComponentName(service.serviceInfo.packageName, service.serviceInfo.name),
|
||||
hardwareInfo));
|
||||
hardwareInfo), null);
|
||||
}
|
||||
|
||||
private static TvInputInfo createTvInputInfo(Context context, ResolveInfo service,
|
||||
String id) throws XmlPullParserException, IOException {
|
||||
String id, String parentId) throws XmlPullParserException, IOException {
|
||||
ServiceInfo si = service.serviceInfo;
|
||||
PackageManager pm = context.getPackageManager();
|
||||
XmlResourceParser parser = null;
|
||||
@@ -181,7 +182,7 @@ public final class TvInputInfo implements Parcelable {
|
||||
"Meta-data does not start with tv-input-service tag in " + si.name);
|
||||
}
|
||||
|
||||
TvInputInfo input = new TvInputInfo(context, service, id, null);
|
||||
TvInputInfo input = new TvInputInfo(service, id, parentId);
|
||||
TypedArray sa = res.obtainAttributes(attrs,
|
||||
com.android.internal.R.styleable.TvInputService);
|
||||
input.mSetupActivity = sa.getString(
|
||||
@@ -222,9 +223,8 @@ public final class TvInputInfo implements Parcelable {
|
||||
* @param id ID of this TV input. Should be generated via generateInputId*().
|
||||
* @param parentId ID of this TV input's parent input. {@code null} if none exists.
|
||||
*/
|
||||
private TvInputInfo(Context context, ResolveInfo service, String id, String parentId) {
|
||||
private TvInputInfo(ResolveInfo service, String id, String parentId) {
|
||||
mService = service;
|
||||
ServiceInfo si = service.serviceInfo;
|
||||
mId = id;
|
||||
mParentId = parentId;
|
||||
}
|
||||
@@ -429,7 +429,6 @@ public final class TvInputInfo implements Parcelable {
|
||||
|
||||
/**
|
||||
* Used to make this class parcelable.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public static final Parcelable.Creator<TvInputInfo> CREATOR =
|
||||
|
||||
@@ -23,6 +23,7 @@ import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.graphics.PixelFormat;
|
||||
import android.graphics.Rect;
|
||||
import android.hardware.hdmi.HdmiCecDeviceInfo;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
@@ -121,21 +122,32 @@ public abstract class TvInputService extends Service {
|
||||
|
||||
@Override
|
||||
public void notifyHardwareAdded(TvInputHardwareInfo hardwareInfo) {
|
||||
mHandler.obtainMessage(ServiceHandler.DO_ADD_TV_INPUT_FROM_HARDWARE,
|
||||
mHandler.obtainMessage(ServiceHandler.DO_ADD_HARDWARE_TV_INPUT,
|
||||
hardwareInfo).sendToTarget();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void notifyHardwareRemoved(int deviceId) {
|
||||
mHandler.obtainMessage(ServiceHandler.DO_REMOVE_TV_INPUT_FROM_HARDWARE,
|
||||
deviceId, 0).sendToTarget();
|
||||
public void notifyHardwareRemoved(TvInputHardwareInfo hardwareInfo) {
|
||||
mHandler.obtainMessage(ServiceHandler.DO_REMOVE_HARDWARE_TV_INPUT,
|
||||
hardwareInfo).sendToTarget();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void notifyHdmiCecDeviceAdded(HdmiCecDeviceInfo cecDeviceInfo) {
|
||||
mHandler.obtainMessage(ServiceHandler.DO_ADD_HDMI_CEC_TV_INPUT,
|
||||
cecDeviceInfo).sendToTarget();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void notifyHdmiCecDeviceRemoved(HdmiCecDeviceInfo cecDeviceInfo) {
|
||||
mHandler.obtainMessage(ServiceHandler.DO_REMOVE_HDMI_CEC_TV_INPUT,
|
||||
cecDeviceInfo).sendToTarget();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the number of callbacks that are registered.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
@VisibleForTesting
|
||||
@@ -153,11 +165,11 @@ public abstract class TvInputService extends Service {
|
||||
public abstract Session onCreateSession(String inputId);
|
||||
|
||||
/**
|
||||
* Returns a new TvInputInfo object if this service is responsible for {@code hardwareInfo};
|
||||
* otherwise, return {@code null}. Override to modify default behavior of ignoring all input.
|
||||
*
|
||||
* @param hardwareInfo TvInputHardwareInfo object just added.
|
||||
* Returns a new {@link TvInputInfo} object if this service is responsible for
|
||||
* {@code hardwareInfo}; otherwise, return {@code null}. Override to modify default behavior of
|
||||
* ignoring all hardware input.
|
||||
*
|
||||
* @param hardwareInfo {@link TvInputHardwareInfo} object just added.
|
||||
* @hide
|
||||
*/
|
||||
@SystemApi
|
||||
@@ -167,12 +179,40 @@ public abstract class TvInputService extends Service {
|
||||
|
||||
/**
|
||||
* Returns the input ID for {@code deviceId} if it is handled by this service;
|
||||
* otherwise, return {@code null}. Override to modify default behavior of ignoring all input.
|
||||
* otherwise, return {@code null}. Override to modify default behavior of ignoring all hardware
|
||||
* input.
|
||||
*
|
||||
* @param hardwareInfo {@link TvInputHardwareInfo} object just removed.
|
||||
* @hide
|
||||
*/
|
||||
@SystemApi
|
||||
public String onHardwareRemoved(int deviceId) {
|
||||
public String onHardwareRemoved(TvInputHardwareInfo hardwareInfo) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new {@link TvInputInfo} object if this service is responsible for
|
||||
* {@code cecDeviceInfo}; otherwise, return {@code null}. Override to modify default behavior
|
||||
* of ignoring all HDMI CEC logical input device.
|
||||
*
|
||||
* @param cecDeviceInfo {@link HdmiCecDeviceInfo} object just added.
|
||||
* @hide
|
||||
*/
|
||||
@SystemApi
|
||||
public TvInputInfo onHdmiCecDeviceAdded(HdmiCecDeviceInfo cecDeviceInfo) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the input ID for {@code logicalAddress} if it is handled by this service;
|
||||
* otherwise, return {@code null}. Override to modify default behavior of ignoring all HDMI CEC
|
||||
* logical input device.
|
||||
*
|
||||
* @param cecDeviceInfo {@link HdmiCecDeviceInfo} object just removed.
|
||||
* @hide
|
||||
*/
|
||||
@SystemApi
|
||||
public String onHdmiCecDeviceRemoved(HdmiCecDeviceInfo cecDeviceInfo) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -899,14 +939,29 @@ public abstract class TvInputService extends Service {
|
||||
@SuppressLint("HandlerLeak")
|
||||
private final class ServiceHandler extends Handler {
|
||||
private static final int DO_CREATE_SESSION = 1;
|
||||
private static final int DO_ADD_TV_INPUT_FROM_HARDWARE = 2;
|
||||
private static final int DO_REMOVE_TV_INPUT_FROM_HARDWARE = 3;
|
||||
private static final int DO_ADD_HARDWARE_TV_INPUT = 2;
|
||||
private static final int DO_REMOVE_HARDWARE_TV_INPUT = 3;
|
||||
private static final int DO_ADD_HDMI_CEC_TV_INPUT = 4;
|
||||
private static final int DO_REMOVE_HDMI_CEC_TV_INPUT = 5;
|
||||
|
||||
private void broadcastAddTvInput(TvInputInfo inputInfo) {
|
||||
private void broadcastAddHardwareTvInput(int deviceId, TvInputInfo inputInfo) {
|
||||
int n = mCallbacks.beginBroadcast();
|
||||
for (int i = 0; i < n; ++i) {
|
||||
try {
|
||||
mCallbacks.getBroadcastItem(i).addTvInput(inputInfo);
|
||||
mCallbacks.getBroadcastItem(i).addHardwareTvInput(deviceId, inputInfo);
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, "Error while broadcasting: " + e);
|
||||
}
|
||||
}
|
||||
mCallbacks.finishBroadcast();
|
||||
}
|
||||
|
||||
private void broadcastAddHdmiCecTvInput(
|
||||
int logicalAddress, TvInputInfo inputInfo) {
|
||||
int n = mCallbacks.beginBroadcast();
|
||||
for (int i = 0; i < n; ++i) {
|
||||
try {
|
||||
mCallbacks.getBroadcastItem(i).addHdmiCecTvInput(logicalAddress, inputInfo);
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, "Error while broadcasting: " + e);
|
||||
}
|
||||
@@ -951,17 +1006,33 @@ public abstract class TvInputService extends Service {
|
||||
args.recycle();
|
||||
return;
|
||||
}
|
||||
case DO_ADD_TV_INPUT_FROM_HARDWARE: {
|
||||
case DO_ADD_HARDWARE_TV_INPUT: {
|
||||
TvInputHardwareInfo hardwareInfo = (TvInputHardwareInfo) msg.obj;
|
||||
TvInputInfo inputInfo = onHardwareAdded(hardwareInfo);
|
||||
if (inputInfo != null) {
|
||||
broadcastAddTvInput(inputInfo);
|
||||
broadcastAddHardwareTvInput(hardwareInfo.getDeviceId(), inputInfo);
|
||||
}
|
||||
return;
|
||||
}
|
||||
case DO_REMOVE_TV_INPUT_FROM_HARDWARE: {
|
||||
int deviceId = msg.arg1;
|
||||
String inputId = onHardwareRemoved(deviceId);
|
||||
case DO_REMOVE_HARDWARE_TV_INPUT: {
|
||||
TvInputHardwareInfo hardwareInfo = (TvInputHardwareInfo) msg.obj;
|
||||
String inputId = onHardwareRemoved(hardwareInfo);
|
||||
if (inputId != null) {
|
||||
broadcastRemoveTvInput(inputId);
|
||||
}
|
||||
return;
|
||||
}
|
||||
case DO_ADD_HDMI_CEC_TV_INPUT: {
|
||||
HdmiCecDeviceInfo cecDeviceInfo = (HdmiCecDeviceInfo) msg.obj;
|
||||
TvInputInfo inputInfo = onHdmiCecDeviceAdded(cecDeviceInfo);
|
||||
if (inputInfo != null) {
|
||||
broadcastAddHdmiCecTvInput(cecDeviceInfo.getLogicalAddress(), inputInfo);
|
||||
}
|
||||
return;
|
||||
}
|
||||
case DO_REMOVE_HDMI_CEC_TV_INPUT: {
|
||||
HdmiCecDeviceInfo cecDeviceInfo = (HdmiCecDeviceInfo) msg.obj;
|
||||
String inputId = onHdmiCecDeviceRemoved(cecDeviceInfo);
|
||||
if (inputId != null) {
|
||||
broadcastRemoveTvInput(inputId);
|
||||
}
|
||||
|
||||
@@ -42,6 +42,7 @@ import android.os.Looper;
|
||||
import android.os.Message;
|
||||
import android.os.RemoteException;
|
||||
import android.os.ServiceManager;
|
||||
import android.util.ArrayMap;
|
||||
import android.util.Slog;
|
||||
import android.util.SparseArray;
|
||||
import android.util.SparseBooleanArray;
|
||||
@@ -51,8 +52,10 @@ import android.view.Surface;
|
||||
import com.android.server.SystemService;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
@@ -65,20 +68,27 @@ import java.util.Set;
|
||||
*/
|
||||
class TvInputHardwareManager implements TvInputHal.Callback {
|
||||
private static final String TAG = TvInputHardwareManager.class.getSimpleName();
|
||||
|
||||
private final Context mContext;
|
||||
private final Listener mListener;
|
||||
private final TvInputHal mHal = new TvInputHal(this);
|
||||
private final SparseArray<Connection> mConnections = new SparseArray<Connection>();
|
||||
private final List<TvInputHardwareInfo> mInfoList = new ArrayList<TvInputHardwareInfo>();
|
||||
private final Context mContext;
|
||||
private final Listener mListener;
|
||||
private final Set<Integer> mActiveHdmiSources = new HashSet<Integer>();
|
||||
/* A map from a device ID to the matching TV input ID. */
|
||||
private final SparseArray<String> mHardwareInputIdMap = new SparseArray<String>();
|
||||
/* A map from a HDMI logical address to the matching TV input ID. */
|
||||
private final SparseArray<String> mHdmiCecInputIdMap = new SparseArray<String>();
|
||||
private final Map<String, TvInputInfo> mInputMap = new ArrayMap<String, TvInputInfo>();
|
||||
|
||||
private final AudioManager mAudioManager;
|
||||
private final SparseBooleanArray mHdmiStateMap = new SparseBooleanArray();
|
||||
// TODO: Should handle INACTIVE case.
|
||||
private final SparseArray<TvInputInfo> mTvInputInfoMap = new SparseArray<TvInputInfo>();
|
||||
private final IHdmiDeviceEventListener mHdmiDeviceEventListener = new HdmiDeviceEventListener();
|
||||
private IHdmiControlService mHdmiControlService;
|
||||
private final IHdmiHotplugEventListener mHdmiHotplugEventListener =
|
||||
new HdmiHotplugEventListener();
|
||||
private final IHdmiDeviceEventListener mHdmiDeviceEventListener = new HdmiDeviceEventListener();
|
||||
private final IHdmiInputChangeListener mHdmiInputChangeListener = new HdmiInputChangeListener();
|
||||
private final Set<Integer> mActiveHdmiSources = new HashSet<Integer>();
|
||||
// TODO: Should handle INACTIVE case.
|
||||
private final SparseBooleanArray mHdmiStateMap = new SparseBooleanArray();
|
||||
|
||||
// Calls to mListener should happen here.
|
||||
private final Handler mHandler = new ListenerHandler();
|
||||
@@ -94,23 +104,22 @@ class TvInputHardwareManager implements TvInputHal.Callback {
|
||||
|
||||
public void onBootPhase(int phase) {
|
||||
if (phase == SystemService.PHASE_SYSTEM_SERVICES_READY) {
|
||||
IHdmiControlService hdmiControlService = IHdmiControlService.Stub.asInterface(
|
||||
ServiceManager.getService(Context.HDMI_CONTROL_SERVICE));
|
||||
if (hdmiControlService != null) {
|
||||
mHdmiControlService = IHdmiControlService.Stub.asInterface(ServiceManager.getService(
|
||||
Context.HDMI_CONTROL_SERVICE));
|
||||
if (mHdmiControlService != null) {
|
||||
try {
|
||||
hdmiControlService.addHotplugEventListener(mHdmiHotplugEventListener);
|
||||
hdmiControlService.addDeviceEventListener(mHdmiDeviceEventListener);
|
||||
hdmiControlService.setInputChangeListener(mHdmiInputChangeListener);
|
||||
mHdmiControlService.addHotplugEventListener(mHdmiHotplugEventListener);
|
||||
mHdmiControlService.addDeviceEventListener(mHdmiDeviceEventListener);
|
||||
mHdmiControlService.setInputChangeListener(mHdmiInputChangeListener);
|
||||
} catch (RemoteException e) {
|
||||
Slog.w(TAG, "Error registering listeners to HdmiControlService:" + e);
|
||||
Slog.w(TAG, "Error registering listeners to HdmiControlService:", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDeviceAvailable(
|
||||
TvInputHardwareInfo info, TvStreamConfig[] configs) {
|
||||
public void onDeviceAvailable(TvInputHardwareInfo info, TvStreamConfig[] configs) {
|
||||
synchronized (mLock) {
|
||||
Connection connection = new Connection(info);
|
||||
connection.updateConfigsLocked(configs);
|
||||
@@ -139,8 +148,9 @@ class TvInputHardwareManager implements TvInputHal.Callback {
|
||||
connection.resetLocked(null, null, null, null, null);
|
||||
mConnections.remove(deviceId);
|
||||
buildInfoListLocked();
|
||||
TvInputHardwareInfo info = connection.getHardwareInfoLocked();
|
||||
mHandler.obtainMessage(
|
||||
ListenerHandler.HARDWARE_DEVICE_REMOVED, deviceId, 0).sendToTarget();
|
||||
ListenerHandler.HARDWARE_DEVICE_REMOVED, 0, 0, info).sendToTarget();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -157,7 +167,7 @@ class TvInputHardwareManager implements TvInputHal.Callback {
|
||||
try {
|
||||
connection.getCallbackLocked().onStreamConfigChanged(configs);
|
||||
} catch (RemoteException e) {
|
||||
Slog.e(TAG, "onStreamConfigurationChanged: " + e);
|
||||
Slog.e(TAG, "error in onStreamConfigurationChanged", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -168,6 +178,17 @@ class TvInputHardwareManager implements TvInputHal.Callback {
|
||||
}
|
||||
}
|
||||
|
||||
public List<HdmiCecDeviceInfo> getHdmiCecInputDeviceList() {
|
||||
if (mHdmiControlService != null) {
|
||||
try {
|
||||
return mHdmiControlService.getInputDevices();
|
||||
} catch (RemoteException e) {
|
||||
Slog.e(TAG, "error in getHdmiCecInputDeviceList", e);
|
||||
}
|
||||
}
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
private boolean checkUidChangedLocked(
|
||||
Connection connection, int callingUid, int resolvedUserId) {
|
||||
Integer connectionCallingUid = connection.getCallingUidLocked();
|
||||
@@ -189,17 +210,19 @@ class TvInputHardwareManager implements TvInputHal.Callback {
|
||||
}
|
||||
}
|
||||
|
||||
public void registerTvInputInfo(TvInputInfo info, int deviceId) {
|
||||
public void addHardwareTvInput(int deviceId, TvInputInfo info) {
|
||||
if (info.getType() == TvInputInfo.TYPE_VIRTUAL) {
|
||||
throw new IllegalArgumentException("info (" + info + ") has virtual type.");
|
||||
}
|
||||
synchronized (mLock) {
|
||||
if (mTvInputInfoMap.indexOfKey(deviceId) >= 0) {
|
||||
String oldInputId = mHardwareInputIdMap.get(deviceId);
|
||||
if (oldInputId != null) {
|
||||
Slog.w(TAG, "Trying to override previous registration: old = "
|
||||
+ mTvInputInfoMap.get(deviceId) + ":" + deviceId + ", new = "
|
||||
+ mInputMap.get(oldInputId) + ":" + deviceId + ", new = "
|
||||
+ info + ":" + deviceId);
|
||||
}
|
||||
mTvInputInfoMap.put(deviceId, info);
|
||||
mHardwareInputIdMap.put(deviceId, info.getId());
|
||||
mInputMap.put(info.getId(), info);
|
||||
|
||||
for (int i = 0; i < mHdmiStateMap.size(); ++i) {
|
||||
String inputId = findInputIdForHdmiPortLocked(mHdmiStateMap.keyAt(i));
|
||||
@@ -212,6 +235,41 @@ class TvInputHardwareManager implements TvInputHal.Callback {
|
||||
}
|
||||
}
|
||||
|
||||
public void addHdmiCecTvInput(int logicalAddress, 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 = mHardwareInputIdMap.indexOfValue(parentId);
|
||||
if (parentIndex < 0 || !parentId.equals(mHardwareInputIdMap.valueAt(parentIndex))) {
|
||||
throw new IllegalArgumentException("info (" + info + ") has invalid parentId.");
|
||||
}
|
||||
String oldInputId = mHdmiCecInputIdMap.get(logicalAddress);
|
||||
if (oldInputId != null) {
|
||||
Slog.w(TAG, "Trying to override previous registration: old = "
|
||||
+ mInputMap.get(oldInputId) + ":" + logicalAddress + ", new = "
|
||||
+ info + ":" + logicalAddress);
|
||||
}
|
||||
mHdmiCecInputIdMap.put(logicalAddress, info.getId());
|
||||
mInputMap.put(info.getId(), info);
|
||||
}
|
||||
}
|
||||
|
||||
public void removeTvInput(String inputId) {
|
||||
synchronized (mLock) {
|
||||
mInputMap.remove(inputId);
|
||||
int hardwareIndex = mHardwareInputIdMap.indexOfValue(inputId);
|
||||
if (hardwareIndex >= 0) {
|
||||
mHardwareInputIdMap.removeAt(hardwareIndex);
|
||||
}
|
||||
int cecIndex = mHdmiCecInputIdMap.indexOfValue(inputId);
|
||||
if (cecIndex >= 0) {
|
||||
mHdmiCecInputIdMap.removeAt(cecIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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,
|
||||
@@ -267,8 +325,7 @@ class TvInputHardwareManager implements TvInputHal.Callback {
|
||||
for (TvInputHardwareInfo hardwareInfo : mInfoList) {
|
||||
if (hardwareInfo.getType() == TvInputHardwareInfo.TV_INPUT_TYPE_HDMI
|
||||
&& hardwareInfo.getHdmiPortId() == port) {
|
||||
TvInputInfo info = mTvInputInfoMap.get(hardwareInfo.getDeviceId());
|
||||
return (info == null) ? null : info.getId();
|
||||
return mHardwareInputIdMap.get(hardwareInfo.getDeviceId());
|
||||
}
|
||||
}
|
||||
return null;
|
||||
@@ -295,7 +352,7 @@ class TvInputHardwareManager implements TvInputHal.Callback {
|
||||
try {
|
||||
mCallback.onReleased();
|
||||
} catch (RemoteException e) {
|
||||
Slog.e(TAG, "Connection::resetHardware: " + e);
|
||||
Slog.e(TAG, "error in Connection::resetLocked", e);
|
||||
}
|
||||
mHardware.release();
|
||||
}
|
||||
@@ -309,7 +366,7 @@ class TvInputHardwareManager implements TvInputHal.Callback {
|
||||
try {
|
||||
mCallback.onStreamConfigChanged(getConfigsLocked());
|
||||
} catch (RemoteException e) {
|
||||
Slog.e(TAG, "Connection::resetHardware: " + e);
|
||||
Slog.e(TAG, "error in Connection::resetLocked", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -501,7 +558,7 @@ class TvInputHardwareManager implements TvInputHal.Callback {
|
||||
interface Listener {
|
||||
public void onStateChanged(String inputId, int state);
|
||||
public void onHardwareDeviceAdded(TvInputHardwareInfo info);
|
||||
public void onHardwareDeviceRemoved(int deviceId);
|
||||
public void onHardwareDeviceRemoved(TvInputHardwareInfo info);
|
||||
public void onHdmiCecDeviceAdded(HdmiCecDeviceInfo cecDevice);
|
||||
public void onHdmiCecDeviceRemoved(HdmiCecDeviceInfo cecDevice);
|
||||
}
|
||||
@@ -510,8 +567,8 @@ class TvInputHardwareManager implements TvInputHal.Callback {
|
||||
private static final int STATE_CHANGED = 1;
|
||||
private static final int HARDWARE_DEVICE_ADDED = 2;
|
||||
private static final int HARDWARE_DEVICE_REMOVED = 3;
|
||||
private static final int CEC_DEVICE_ADDED = 4;
|
||||
private static final int CEC_DEVICE_REMOVED = 5;
|
||||
private static final int HDMI_CEC_DEVICE_ADDED = 4;
|
||||
private static final int HDMI_CEC_DEVICE_REMOVED = 5;
|
||||
|
||||
@Override
|
||||
public final void handleMessage(Message msg) {
|
||||
@@ -528,16 +585,16 @@ class TvInputHardwareManager implements TvInputHal.Callback {
|
||||
break;
|
||||
}
|
||||
case HARDWARE_DEVICE_REMOVED: {
|
||||
int deviceId = msg.arg1;
|
||||
mListener.onHardwareDeviceRemoved(deviceId);
|
||||
TvInputHardwareInfo info = (TvInputHardwareInfo) msg.obj;
|
||||
mListener.onHardwareDeviceRemoved(info);
|
||||
break;
|
||||
}
|
||||
case CEC_DEVICE_ADDED: {
|
||||
case HDMI_CEC_DEVICE_ADDED: {
|
||||
HdmiCecDeviceInfo info = (HdmiCecDeviceInfo) msg.obj;
|
||||
mListener.onHdmiCecDeviceAdded(info);
|
||||
break;
|
||||
}
|
||||
case CEC_DEVICE_REMOVED: {
|
||||
case HDMI_CEC_DEVICE_REMOVED: {
|
||||
HdmiCecDeviceInfo info = (HdmiCecDeviceInfo) msg.obj;
|
||||
mListener.onHdmiCecDeviceRemoved(info);
|
||||
break;
|
||||
@@ -571,8 +628,8 @@ class TvInputHardwareManager implements TvInputHal.Callback {
|
||||
@Override
|
||||
public void onStatusChanged(HdmiCecDeviceInfo deviceInfo, boolean activated) {
|
||||
mHandler.obtainMessage(
|
||||
activated ? ListenerHandler.CEC_DEVICE_ADDED
|
||||
: ListenerHandler.CEC_DEVICE_REMOVED,
|
||||
activated ? ListenerHandler.HDMI_CEC_DEVICE_ADDED
|
||||
: ListenerHandler.HDMI_CEC_DEVICE_REMOVED,
|
||||
0, 0, deviceInfo).sendToTarget();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -220,7 +220,7 @@ public final class TvInputManagerService extends SystemService {
|
||||
List<ResolveInfo> services = pm.queryIntentServices(
|
||||
new Intent(TvInputService.SERVICE_INTERFACE),
|
||||
PackageManager.GET_SERVICES | PackageManager.GET_META_DATA);
|
||||
List<TvInputInfo> infoList = new ArrayList<TvInputInfo>();
|
||||
List<TvInputInfo> inputList = new ArrayList<TvInputInfo>();
|
||||
for (ResolveInfo ri : services) {
|
||||
ServiceInfo si = ri.serviceInfo;
|
||||
if (!android.Manifest.permission.BIND_TV_INPUT.equals(si.permission)) {
|
||||
@@ -229,7 +229,7 @@ public final class TvInputManagerService extends SystemService {
|
||||
continue;
|
||||
}
|
||||
try {
|
||||
infoList.clear();
|
||||
inputList.clear();
|
||||
ComponentName service = new ComponentName(si.packageName, si.name);
|
||||
if (hasHardwarePermission(pm, service)) {
|
||||
ServiceState serviceState = userState.serviceStateMap.get(service);
|
||||
@@ -240,13 +240,13 @@ public final class TvInputManagerService extends SystemService {
|
||||
serviceState = new ServiceState(service, userId);
|
||||
userState.serviceStateMap.put(service, serviceState);
|
||||
} else {
|
||||
infoList.addAll(serviceState.mInputList);
|
||||
inputList.addAll(serviceState.mInputList);
|
||||
}
|
||||
} else {
|
||||
infoList.add(TvInputInfo.createTvInputInfo(mContext, ri));
|
||||
inputList.add(TvInputInfo.createTvInputInfo(mContext, ri));
|
||||
}
|
||||
|
||||
for (TvInputInfo info : infoList) {
|
||||
for (TvInputInfo info : inputList) {
|
||||
if (DEBUG) Slog.d(TAG, "add " + info.getId());
|
||||
TvInputState state = userState.inputMap.get(info.getId());
|
||||
if (state == null) {
|
||||
@@ -1212,22 +1212,6 @@ public final class TvInputManagerService extends SystemService {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerTvInputInfo(TvInputInfo info, int deviceId) {
|
||||
// TODO: Revisit to sort out deviceId ownership.
|
||||
if (mContext.checkCallingPermission(android.Manifest.permission.TV_INPUT_HARDWARE)
|
||||
!= PackageManager.PERMISSION_GRANTED) {
|
||||
return;
|
||||
}
|
||||
|
||||
final long identity = Binder.clearCallingIdentity();
|
||||
try {
|
||||
mTvInputHardwareManager.registerTvInputInfo(info, deviceId);
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(identity);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ITvInputHardware acquireTvInputHardware(int deviceId,
|
||||
ITvInputHardwareCallback callback, TvInputInfo info, int userId)
|
||||
@@ -1550,8 +1534,6 @@ public final class TvInputManagerService extends SystemService {
|
||||
Slog.d(TAG, "onServiceConnected(name=" + name + ")");
|
||||
}
|
||||
synchronized (mLock) {
|
||||
List<TvInputHardwareInfo> hardwareInfoList =
|
||||
mTvInputHardwareManager.getHardwareList();
|
||||
UserState userState = getUserStateLocked(mUserId);
|
||||
ServiceState serviceState = userState.serviceStateMap.get(mName);
|
||||
serviceState.mService = ITvInputService.Stub.asInterface(service);
|
||||
@@ -1580,6 +1562,8 @@ public final class TvInputManagerService extends SystemService {
|
||||
}
|
||||
|
||||
if (serviceState.mIsHardware) {
|
||||
List<TvInputHardwareInfo> hardwareInfoList =
|
||||
mTvInputHardwareManager.getHardwareList();
|
||||
for (TvInputHardwareInfo hardwareInfo : hardwareInfoList) {
|
||||
try {
|
||||
serviceState.mService.notifyHardwareAdded(hardwareInfo);
|
||||
@@ -1588,7 +1572,15 @@ public final class TvInputManagerService extends SystemService {
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Grab CEC devices and notify them to the service.
|
||||
List<HdmiCecDeviceInfo> cecDeviceInfoList =
|
||||
mTvInputHardwareManager.getHdmiCecInputDeviceList();
|
||||
for (HdmiCecDeviceInfo cecDeviceInfo : cecDeviceInfoList) {
|
||||
try {
|
||||
serviceState.mService.notifyHdmiCecDeviceAdded(cecDeviceInfo);
|
||||
} catch (RemoteException e) {
|
||||
Slog.e(TAG, "error in notifyHdmiCecDeviceAdded", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1642,32 +1634,49 @@ public final class TvInputManagerService extends SystemService {
|
||||
mUserId = userId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addTvInput(TvInputInfo inputInfo) {
|
||||
synchronized (mLock) {
|
||||
if (mContext.checkCallingPermission(android.Manifest.permission.TV_INPUT_HARDWARE)
|
||||
!= PackageManager.PERMISSION_GRANTED) {
|
||||
Slog.w(TAG, "The caller does not have permission to add a TV input ("
|
||||
+ inputInfo + ").");
|
||||
return;
|
||||
}
|
||||
private void ensureHardwarePermission() {
|
||||
if (mContext.checkCallingPermission(android.Manifest.permission.TV_INPUT_HARDWARE)
|
||||
!= PackageManager.PERMISSION_GRANTED) {
|
||||
throw new SecurityException("The caller does not have hardware permission");
|
||||
}
|
||||
}
|
||||
|
||||
ServiceState serviceState = getServiceStateLocked(mName, mUserId);
|
||||
serviceState.mInputList.add(inputInfo);
|
||||
buildTvInputListLocked(mUserId);
|
||||
private void ensureValidInput(TvInputInfo inputInfo) {
|
||||
if (inputInfo.getId() == null || !mName.equals(inputInfo.getComponent())) {
|
||||
throw new IllegalArgumentException("Invalid TvInputInfo");
|
||||
}
|
||||
}
|
||||
|
||||
private void addTvInputLocked(TvInputInfo inputInfo) {
|
||||
ServiceState serviceState = getServiceStateLocked(mName, mUserId);
|
||||
serviceState.mInputList.add(inputInfo);
|
||||
buildTvInputListLocked(mUserId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addHardwareTvInput(int deviceId, TvInputInfo inputInfo) {
|
||||
ensureHardwarePermission();
|
||||
ensureValidInput(inputInfo);
|
||||
synchronized (mLock) {
|
||||
mTvInputHardwareManager.addHardwareTvInput(deviceId, inputInfo);
|
||||
addTvInputLocked(inputInfo);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addHdmiCecTvInput(int logicalAddress, TvInputInfo inputInfo) {
|
||||
ensureHardwarePermission();
|
||||
ensureValidInput(inputInfo);
|
||||
synchronized (mLock) {
|
||||
mTvInputHardwareManager.addHdmiCecTvInput(logicalAddress, inputInfo);
|
||||
addTvInputLocked(inputInfo);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeTvInput(String inputId) {
|
||||
ensureHardwarePermission();
|
||||
synchronized (mLock) {
|
||||
if (mContext.checkCallingPermission(android.Manifest.permission.TV_INPUT_HARDWARE)
|
||||
!= PackageManager.PERMISSION_GRANTED) {
|
||||
Slog.w(TAG, "The caller does not have permission to remove a TV input ("
|
||||
+ inputId + ").");
|
||||
return;
|
||||
}
|
||||
|
||||
ServiceState serviceState = getServiceStateLocked(mName, mUserId);
|
||||
boolean removed = false;
|
||||
for (Iterator<TvInputInfo> it = serviceState.mInputList.iterator();
|
||||
@@ -1680,6 +1689,7 @@ public final class TvInputManagerService extends SystemService {
|
||||
}
|
||||
if (removed) {
|
||||
buildTvInputListLocked(mUserId);
|
||||
mTvInputHardwareManager.removeTvInput(inputId);
|
||||
} else {
|
||||
Slog.e(TAG, "TvInputInfo with inputId=" + inputId + " not found.");
|
||||
}
|
||||
@@ -1856,14 +1866,14 @@ public final class TvInputManagerService extends SystemService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onHardwareDeviceRemoved(int deviceId) {
|
||||
public void onHardwareDeviceRemoved(TvInputHardwareInfo info) {
|
||||
synchronized (mLock) {
|
||||
UserState userState = getUserStateLocked(mCurrentUserId);
|
||||
// Broadcast the event to all hardware inputs.
|
||||
for (ServiceState serviceState : userState.serviceStateMap.values()) {
|
||||
if (!serviceState.mIsHardware || serviceState.mService == null) continue;
|
||||
try {
|
||||
serviceState.mService.notifyHardwareRemoved(deviceId);
|
||||
serviceState.mService.notifyHardwareRemoved(info);
|
||||
} catch (RemoteException e) {
|
||||
Slog.e(TAG, "error in notifyHardwareRemoved", e);
|
||||
}
|
||||
@@ -1872,16 +1882,34 @@ public final class TvInputManagerService extends SystemService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onHdmiCecDeviceAdded(HdmiCecDeviceInfo cecDevice) {
|
||||
public void onHdmiCecDeviceAdded(HdmiCecDeviceInfo cecDeviceInfo) {
|
||||
synchronized (mLock) {
|
||||
// TODO
|
||||
UserState userState = getUserStateLocked(mCurrentUserId);
|
||||
// Broadcast the event to all hardware inputs.
|
||||
for (ServiceState serviceState : userState.serviceStateMap.values()) {
|
||||
if (!serviceState.mIsHardware || serviceState.mService == null) continue;
|
||||
try {
|
||||
serviceState.mService.notifyHdmiCecDeviceAdded(cecDeviceInfo);
|
||||
} catch (RemoteException e) {
|
||||
Slog.e(TAG, "error in notifyHdmiCecDeviceAdded", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onHdmiCecDeviceRemoved(HdmiCecDeviceInfo cecDevice) {
|
||||
public void onHdmiCecDeviceRemoved(HdmiCecDeviceInfo cecDeviceInfo) {
|
||||
synchronized (mLock) {
|
||||
// TODO
|
||||
UserState userState = getUserStateLocked(mCurrentUserId);
|
||||
// Broadcast the event to all hardware inputs.
|
||||
for (ServiceState serviceState : userState.serviceStateMap.values()) {
|
||||
if (!serviceState.mIsHardware || serviceState.mService == null) continue;
|
||||
try {
|
||||
serviceState.mService.notifyHdmiCecDeviceRemoved(cecDeviceInfo);
|
||||
} catch (RemoteException e) {
|
||||
Slog.e(TAG, "error in notifyHdmiCecDeviceRemoved", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user