am 90b50ad5: am 58afc5c4: am 235b2e66: Merge "CEC: return non-null MHL controller when not ready" into lmp-dev

* commit '90b50ad5fef035cc83da8ecb9dde6249b9db5064':
  CEC: return non-null MHL controller when not ready
This commit is contained in:
Jinsuk Kim
2014-08-28 04:17:27 +00:00
committed by Android Git Automerger
2 changed files with 91 additions and 106 deletions

View File

@@ -248,6 +248,11 @@ final class Constants {
static final int DISABLED = 0;
static final int ENABLED = 1;
// Property name for the local device configurations.
// TODO(OEM): OEM should provide this property, and the value is the comma separated integer
// values which denotes the device type in HDMI Spec 1.4.
static final String PROPERTY_DEVICE_TYPE = "ro.hdmi.device_type";
// --------------------------------------------------
// MHL sub command message types.
static final int MHL_MSG_MSGE = 0x02;
@@ -275,11 +280,6 @@ final class Constants {
static final int MHL_CBUS_MODE_ECBUS_S = 2;
static final int MHL_CBUS_MODE_ECBUS_D = 3;
// Property name for the local device configurations.
// TODO(OEM): OEM should provide this property, and the value is the comma separated integer
// values which denotes the device type in HDMI Spec 1.4.
static final String PROPERTY_DEVICE_TYPE = "ro.hdmi.device_type";
// MHL RCPE messages
static final int MHL_RCPE_NO_ERROR = 0x00;
static final int MHL_RCPE_INEFFECTIVE_KEYCODE = 0x01;

View File

@@ -179,11 +179,6 @@ public final class HdmiControlService extends SystemService {
private final ArrayList<VendorCommandListenerRecord> mVendorCommandListenerRecords =
new ArrayList<>();
// List of records for MHL Scratchpad command listener to handle the caller killed in action.
@GuardedBy("mLock")
private final ArrayList<HdmiMhlScratchpadCommandListenerRecord>
mScratchpadCommandListenerRecords = new ArrayList<>();
@GuardedBy("mLock")
private InputChangeListenerRecord mInputChangeListenerRecord;
@@ -201,13 +196,6 @@ public final class HdmiControlService extends SystemService {
@GuardedBy("mLock")
private boolean mProhibitMode;
// Set to true while the input change by MHL is allowed.
@GuardedBy("mLock")
private boolean mMhlInputChangeEnabled;
@GuardedBy("mLock")
private List<HdmiDeviceInfo> mMhlDevices;
// List of records for system audio mode change to handle the the caller killed in action.
private final ArrayList<SystemAudioModeChangeListenerRecord>
mSystemAudioModeChangeListenerRecords = new ArrayList<>();
@@ -223,9 +211,6 @@ public final class HdmiControlService extends SystemService {
@Nullable
private HdmiCecController mCecController;
@Nullable
private HdmiMhlController mMhlController;
// HDMI port information. Stored in the unmodifiable list to keep the static information
// from being modified.
private List<HdmiPortInfo> mPortInfo;
@@ -256,8 +241,23 @@ public final class HdmiControlService extends SystemService {
@ServiceThreadOnly
private int mActivePortId = Constants.INVALID_PORT_ID;
// Last input port before switching to the MHL port by way of incoming request RAP[ContentOn].
// Should switch back to this port when the device sends RAP[ContentOff].
// Set to true while the input change by MHL is allowed.
@GuardedBy("mLock")
private boolean mMhlInputChangeEnabled;
// List of records for MHL Scratchpad command listener to handle the caller killed in action.
@GuardedBy("mLock")
private final ArrayList<HdmiMhlScratchpadCommandListenerRecord>
mScratchpadCommandListenerRecords = new ArrayList<>();
@GuardedBy("mLock")
private List<HdmiDeviceInfo> mMhlDevices;
@Nullable
private HdmiMhlController mMhlController;
// Last input port before switching to the MHL port. Should switch back to this port
// when the mobile device sends the request one touch play with off.
// Gets invalidated if we go to other port/input.
@ServiceThreadOnly
private int mLastInputMhl = Constants.INVALID_PORT_ID;
@@ -304,16 +304,17 @@ public final class HdmiControlService extends SystemService {
}
mMhlController = HdmiMhlController.create(this);
if (mMhlController == null) {
if (!mMhlController.isReady()) {
Slog.i(TAG, "Device does not support MHL-control.");
}
initPortInfo();
mMhlDevices = Collections.emptyList();
initPortInfo();
mMessageValidator = new HdmiCecMessageValidator(this);
publishBinderService(Context.HDMI_CONTROL_SERVICE, new BinderService());
// Register broadcast receiver for power state change.
if (mCecController != null || mMhlController != null) {
if (mCecController != null) {
IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_SCREEN_OFF);
filter.addAction(Intent.ACTION_SCREEN_ON);
@@ -378,9 +379,7 @@ public final class HdmiControlService extends SystemService {
setMhlInputChangeEnabled(enabled);
break;
case Global.MHL_POWER_CHARGE_ENABLED:
if (mMhlController != null) {
mMhlController.setOption(OPTION_MHL_POWER_CHARGE, toInt(enabled));
}
mMhlController.setOption(OPTION_MHL_POWER_CHARGE, toInt(enabled));
break;
}
}
@@ -484,30 +483,30 @@ public final class HdmiControlService extends SystemService {
mPortInfoMap = new UnmodifiableSparseArray<>(portInfoMap);
mPortDeviceMap = new UnmodifiableSparseArray<>(portDeviceMap);
if (mMhlController == null) {
HdmiPortInfo[] mhlPortInfo = mMhlController.getPortInfos();
ArraySet<Integer> mhlSupportedPorts = new ArraySet<Integer>(mhlPortInfo.length);
for (HdmiPortInfo info : mhlPortInfo) {
if (info.isMhlSupported()) {
mhlSupportedPorts.add(info.getId());
}
}
// Build HDMI port info list with CEC port info plus MHL supported flag. We can just use
// cec port info if we do not have have port that supports MHL.
if (mhlSupportedPorts.isEmpty()) {
mPortInfo = Collections.unmodifiableList(Arrays.asList(cecPortInfo));
return;
} else {
HdmiPortInfo[] mhlPortInfo = mMhlController.getPortInfos();
ArraySet<Integer> mhlSupportedPorts = new ArraySet<Integer>(mhlPortInfo.length);
for (HdmiPortInfo info : mhlPortInfo) {
if (info.isMhlSupported()) {
mhlSupportedPorts.add(info.getId());
}
}
// Build HDMI port info list with CEC port info plus MHL supported flag.
ArrayList<HdmiPortInfo> result = new ArrayList<>(cecPortInfo.length);
for (HdmiPortInfo info : cecPortInfo) {
if (mhlSupportedPorts.contains(info.getId())) {
result.add(new HdmiPortInfo(info.getId(), info.getType(), info.getAddress(),
info.isCecSupported(), true, info.isArcSupported()));
} else {
result.add(info);
}
}
mPortInfo = Collections.unmodifiableList(result);
}
ArrayList<HdmiPortInfo> result = new ArrayList<>(cecPortInfo.length);
for (HdmiPortInfo info : cecPortInfo) {
if (mhlSupportedPorts.contains(info.getId())) {
result.add(new HdmiPortInfo(info.getId(), info.getType(), info.getAddress(),
info.isCecSupported(), true, info.isArcSupported()));
} else {
result.add(info);
}
}
mPortInfo = Collections.unmodifiableList(result);
}
List<HdmiPortInfo> getPortInfo() {
@@ -652,18 +651,6 @@ public final class HdmiControlService extends SystemService {
sendCecCommand(command, null);
}
@ServiceThreadOnly
void sendMhlSubcommand(int portId, HdmiMhlSubcommand command) {
assertRunOnServiceThread();
sendMhlSubcommand(portId, command, null);
}
@ServiceThreadOnly
void sendMhlSubcommand(int portId, HdmiMhlSubcommand command, SendMessageCallback callback) {
assertRunOnServiceThread();
mMhlController.sendSubcommand(portId, command, callback);
}
/**
* Send <Feature Abort> command on the given CEC message if possible.
* If the aborted message is invalid, then it wont send the message.
@@ -795,6 +782,18 @@ public final class HdmiControlService extends SystemService {
getVendorId(), displayName);
}
@ServiceThreadOnly
void sendMhlSubcommand(int portId, HdmiMhlSubcommand command) {
assertRunOnServiceThread();
sendMhlSubcommand(portId, command, null);
}
@ServiceThreadOnly
void sendMhlSubcommand(int portId, HdmiMhlSubcommand command, SendMessageCallback callback) {
assertRunOnServiceThread();
mMhlController.sendSubcommand(portId, command, callback);
}
@ServiceThreadOnly
boolean handleMhlSubcommand(int portId, HdmiMhlSubcommand message) {
assertRunOnServiceThread();
@@ -895,6 +894,19 @@ public final class HdmiControlService extends SystemService {
return mMhlDevices;
}
private class HdmiMhlScratchpadCommandListenerRecord implements IBinder.DeathRecipient {
private final IHdmiMhlScratchpadCommandListener mListener;
public HdmiMhlScratchpadCommandListenerRecord(IHdmiMhlScratchpadCommandListener listener) {
mListener = listener;
}
@Override
public void binderDied() {
mScratchpadCommandListenerRecords.remove(this);
}
}
// Record class that monitors the event of the caller of being killed. Used to clean up
// the listener list and record list accordingly.
private final class HotplugEventListenerRecord implements IBinder.DeathRecipient {
@@ -974,19 +986,6 @@ public final class HdmiControlService extends SystemService {
}
}
private class HdmiMhlScratchpadCommandListenerRecord implements IBinder.DeathRecipient {
private final IHdmiMhlScratchpadCommandListener mListener;
public HdmiMhlScratchpadCommandListenerRecord(IHdmiMhlScratchpadCommandListener listener) {
mListener = listener;
}
@Override
public void binderDied() {
mScratchpadCommandListenerRecords.remove(this);
}
}
private void enforceAccessPermission() {
getContext().enforceCallingOrSelfPermission(PERMISSION, TAG);
}
@@ -1039,20 +1038,18 @@ public final class HdmiControlService extends SystemService {
invokeCallback(callback, HdmiControlManager.RESULT_SOURCE_NOT_AVAILABLE);
return;
}
if (mMhlController != null) {
HdmiMhlLocalDevice device = mMhlController.getLocalDeviceById(deviceId);
if (device != null) {
if (device.getPortId() == tv.getActivePortId()) {
invokeCallback(callback, HdmiControlManager.RESULT_SUCCESS);
return;
}
// Upon selecting MHL device, we send RAP[Content On] to wake up
// the connected mobile device, start routing control to switch ports.
// callback is handled by MHL action.
device.turnOn(callback);
tv.doManualPortSwitching(device.getInfo().getPortId(), null);
HdmiMhlLocalDevice device = mMhlController.getLocalDeviceById(deviceId);
if (device != null) {
if (device.getPortId() == tv.getActivePortId()) {
invokeCallback(callback, HdmiControlManager.RESULT_SUCCESS);
return;
}
// Upon selecting MHL device, we send RAP[Content On] to wake up
// the connected mobile device, start routing control to switch ports.
// callback is handled by MHL action.
device.turnOn(callback);
tv.doManualPortSwitching(device.getInfo().getPortId(), null);
return;
}
tv.deviceSelect(deviceId, callback);
}
@@ -1086,12 +1083,10 @@ public final class HdmiControlService extends SystemService {
runOnServiceThread(new Runnable() {
@Override
public void run() {
if (mMhlController != null) {
HdmiMhlLocalDevice device = mMhlController.getLocalDevice(mActivePortId);
if (device != null) {
device.sendKeyEvent(keyCode, isPressed);
return;
}
HdmiMhlLocalDevice device = mMhlController.getLocalDevice(mActivePortId);
if (device != null) {
device.sendKeyEvent(keyCode, isPressed);
return;
}
if (mCecController != null) {
HdmiCecLocalDevice localDevice = mCecController.getLocalDevice(deviceType);
@@ -1380,10 +1375,6 @@ public final class HdmiControlService extends SystemService {
runOnServiceThread(new Runnable() {
@Override
public void run() {
if (mMhlController == null) {
Slog.w(TAG, "No Mhl controller available.");
return;
}
if (!isControlEnabled()) {
Slog.w(TAG, "Hdmi control is disabled.");
return ;
@@ -1775,9 +1766,7 @@ public final class HdmiControlService extends SystemService {
}
}
if (mMhlController != null) {
mMhlController.clearAllLocalDevices();
}
mMhlController.clearAllLocalDevices();
}
@ServiceThreadOnly
@@ -1887,9 +1876,7 @@ public final class HdmiControlService extends SystemService {
int value = toInt(enabled);
mCecController.setOption(OPTION_CEC_ENABLE, value);
if (mMhlController != null) {
mMhlController.setOption(OPTION_MHL_ENABLE, value);
}
mMhlController.setOption(OPTION_MHL_ENABLE, value);
synchronized (mLock) {
mHdmiControlEnabled = enabled;
@@ -1955,7 +1942,7 @@ public final class HdmiControlService extends SystemService {
tv().setActivePortId(portId);
// The port is either the MHL-enabled port where the mobile device is connected, or
// the last port to go back to when RAP[ContentOff] is received. Note that the last port
// the last port to go back to when turnoff command is received. Note that the last port
// may not be the MHL-enabled one. In this case the device info to be passed to
// input change listener should be the one describing the corresponding HDMI port.
HdmiMhlLocalDevice device = mMhlController.getLocalDevice(portId);
@@ -1966,9 +1953,7 @@ public final class HdmiControlService extends SystemService {
}
void setMhlInputChangeEnabled(boolean enabled) {
if (mMhlController != null) {
mMhlController.setOption(OPTION_MHL_INPUT_SWITCHING, toInt(enabled));
}
mMhlController.setOption(OPTION_MHL_INPUT_SWITCHING, toInt(enabled));
synchronized (mLock) {
mMhlInputChangeEnabled = enabled;