Merge "Hook up native mhl api to HdmiControl Service." into lmp-dev

This commit is contained in:
Jungshik Jang
2014-08-12 02:21:31 +00:00
committed by Android (Google) Code Review
4 changed files with 112 additions and 11 deletions

View File

@@ -244,5 +244,26 @@ final class Constants {
static final int DISABLED = 0;
static final int ENABLED = 1;
// --------------------------------------------------
// MHL sub command message types.
static final int MHL_MSG_MSGE = 0x02;
static final int MHL_MSG_RCP = 0x10;
static final int MHL_MSG_RCPK = 0x11;
static final int MHL_MSG_RCPE = 0x12;
static final int MHL_MSG_RAP = 0x20;
static final int MHL_MSG_RAPK = 0x21;
// MHL RAP messages.
static final int MHL_RAP_ACTION_POLL = 0x00;
static final int MHL_RAP_ACTION_CONTENT_ON = 0x10;
static final int MHL_RAP_ACTION_CONTENT_OFF = 0x11;
static final int MHL_INVALID_ADOPTER_ID = -1;
static final int MHL_INVALID_DEVICE_ID = -1;
static final int MHL_CBUS_MODE_OCBUS = 1;
static final int MHL_CBUS_MODE_ECBUS_S = 2;
static final int MHL_CBUS_MODE_ECBUS_D = 3;
private Constants() { /* cannot be instantiated */ }
}

View File

@@ -94,13 +94,14 @@ final class HdmiCecController {
// interacts with HAL.
private volatile long mNativePtr;
private HdmiControlService mService;
private final HdmiControlService mService;
// Stores the local CEC devices in the system. Device type is used for key.
private final SparseArray<HdmiCecLocalDevice> mLocalDevices = new SparseArray<>();
// Private constructor. Use HdmiCecController.create().
private HdmiCecController() {
private HdmiCecController(HdmiControlService service) {
mService = service;
}
/**
@@ -114,21 +115,20 @@ final class HdmiCecController {
* returns {@code null}.
*/
static HdmiCecController create(HdmiControlService service) {
HdmiCecController controller = new HdmiCecController();
HdmiCecController controller = new HdmiCecController(service);
long nativePtr = nativeInit(controller, service.getServiceLooper().getQueue());
if (nativePtr == 0L) {
controller = null;
return null;
}
controller.init(service, nativePtr);
controller.init(nativePtr);
return controller;
}
private void init(HdmiControlService service, long nativePtr) {
mService = service;
mIoHandler = new Handler(service.getServiceLooper());
mControlHandler = new Handler(service.getServiceLooper());
private void init(long nativePtr) {
mIoHandler = new Handler(mService.getServiceLooper());
mControlHandler = new Handler(mService.getServiceLooper());
mNativePtr = nativePtr;
}

View File

@@ -28,9 +28,9 @@ import java.util.ArrayList;
import java.util.List;
/**
* Encapsulates a sequence of CEC/MHL command exchange for a certain feature.
* Encapsulates a sequence of CEC command exchange for a certain feature.
* <p>
* Many CEC/MHL features are accomplished by CEC devices on the bus exchanging more than one
* Many CEC features are accomplished by CEC devices on the bus exchanging more than one
* command. {@link HdmiCecFeatureAction} represents the life cycle of the communication, manages the
* state as the process progresses, and if necessary, returns the result to the caller which
* initiates the action, through the callback given at the creation of the object. All the actual
@@ -42,7 +42,7 @@ import java.util.List;
* package private, accessed by {@link HdmiControlService} only.
*/
abstract class HdmiCecFeatureAction {
private static final String TAG = "FeatureAction";
private static final String TAG = "HdmiCecFeatureAction";
// Timer handler message used for timeout event
protected static final int MSG_TIMEOUT = 100;

View File

@@ -604,6 +604,18 @@ 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.
@@ -732,6 +744,74 @@ public final class HdmiControlService extends SystemService {
getVendorId(), displayName);
}
@ServiceThreadOnly
boolean handleMhlSubcommand(int portId, HdmiMhlSubcommand message) {
assertRunOnServiceThread();
HdmiMhlLocalDevice device = mMhlController.getLocalDevice(portId);
if (device != null) {
return device.handleSubcommand(message);
}
Slog.w(TAG, "No mhl device exists[portId:" + portId + ", message:" + message);
return false;
}
@ServiceThreadOnly
void handleMhlHotplugEvent(int portId, boolean connected) {
assertRunOnServiceThread();
if (connected) {
HdmiMhlLocalDevice newDevice = new HdmiMhlLocalDevice(this, portId);
HdmiMhlLocalDevice oldDevice = mMhlController.addLocalDevice(newDevice);
if (oldDevice != null) {
oldDevice.onDeviceRemoved();
Slog.i(TAG, "Old device of port " + portId + " is removed");
}
} else {
HdmiMhlLocalDevice device = mMhlController.removeLocalDevice(portId);
if (device != null) {
device.onDeviceRemoved();
} else {
Slog.w(TAG, "No device to remove:[portId=" + portId);
}
}
}
@ServiceThreadOnly
void handleMhlCbusModeChanged(int portId, int cbusmode) {
assertRunOnServiceThread();
HdmiMhlLocalDevice device = mMhlController.getLocalDevice(portId);
if (device != null) {
device.setCbusMode(cbusmode);
} else {
Slog.w(TAG, "No mhl device exists for cbus mode change[portId:" + portId +
", cbusmode:" + cbusmode + "]");
}
}
@ServiceThreadOnly
void handleMhlVbusOvercurrent(int portId, boolean on) {
assertRunOnServiceThread();
HdmiMhlLocalDevice device = mMhlController.getLocalDevice(portId);
if (device != null) {
device.onVbusOvercurrentDetected(on);
} else {
Slog.w(TAG, "No mhl device exists for vbus overcurrent event[portId:" + portId + "]");
}
}
@ServiceThreadOnly
void handleCapabilityRegisterChanged(int portId, int adopterId, int deviceId) {
assertRunOnServiceThread();
HdmiMhlLocalDevice device = mMhlController.getLocalDevice(portId);
// Hot plug event should be called before capability register change event.
if (device != null) {
device.setCapabilityRegister(adopterId, deviceId);
} else {
Slog.w(TAG, "No mhl device exists for capability register change event[portId:"
+ portId + ", adopterId:" + adopterId + ", deviceId:" + deviceId + "]");
}
}
// 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 {