am 0608b932: CEC: Add a callback for vendor when HDMI control setting is changed.
* commit '0608b9328b1c2f804ffb2d4165c34383d34bde2a': CEC: Add a callback for vendor when HDMI control setting is changed.
This commit is contained in:
@@ -3,7 +3,6 @@ package android.hardware.hdmi;
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.SystemApi;
|
||||
import android.hardware.hdmi.HdmiControlManager.VendorCommandListener;
|
||||
import android.hardware.hdmi.IHdmiVendorCommandListener;
|
||||
import android.os.RemoteException;
|
||||
import android.util.Log;
|
||||
|
||||
@@ -91,8 +90,13 @@ public abstract class HdmiClient {
|
||||
final VendorCommandListener listener) {
|
||||
return new IHdmiVendorCommandListener.Stub() {
|
||||
@Override
|
||||
public void onReceived(int srcAddress, byte[] params, boolean hasVendorId) {
|
||||
listener.onReceived(srcAddress, params, hasVendorId);
|
||||
public void onReceived(int srcAddress, int destAddress, byte[] params,
|
||||
boolean hasVendorId) {
|
||||
listener.onReceived(srcAddress, destAddress, params, hasVendorId);
|
||||
}
|
||||
@Override
|
||||
public void onControlStateChanged(boolean enabled, int reason) {
|
||||
listener.onControlStateChanged(enabled, reason);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -236,6 +236,15 @@ public final class HdmiControlManager {
|
||||
/** Clear timer error - CEC is disabled. */
|
||||
public static final int CLEAR_TIMER_STATUS_CEC_DISABLE = 0xA2;
|
||||
|
||||
/** The HdmiControlService is started. */
|
||||
public static final int CONTROL_STATE_CHANGED_REASON_START = 0;
|
||||
/** The state of HdmiControlService is changed by changing of settings. */
|
||||
public static final int CONTROL_STATE_CHANGED_REASON_SETTING = 1;
|
||||
/** The HdmiControlService is enabled to wake up. */
|
||||
public static final int CONTROL_STATE_CHANGED_REASON_WAKEUP = 2;
|
||||
/** The HdmiControlService will be disabled to standby. */
|
||||
public static final int CONTROL_STATE_CHANGED_REASON_STANDBY = 3;
|
||||
|
||||
// True if we have a logical device of type playback hosted in the system.
|
||||
private final boolean mHasPlaybackDevice;
|
||||
// True if we have a logical device of type TV hosted in the system.
|
||||
@@ -339,11 +348,29 @@ public final class HdmiControlManager {
|
||||
* Called when a vendor command is received.
|
||||
*
|
||||
* @param srcAddress source logical address
|
||||
* @param destAddress destination logical address
|
||||
* @param params vendor-specific parameters
|
||||
* @param hasVendorId {@code true} if the command is <Vendor Command
|
||||
* With ID>. The first 3 bytes of params is vendor id.
|
||||
*/
|
||||
void onReceived(int srcAddress, byte[] params, boolean hasVendorId);
|
||||
void onReceived(int srcAddress, int destAddress, byte[] params, boolean hasVendorId);
|
||||
|
||||
/**
|
||||
* The callback is called:
|
||||
* <ul>
|
||||
* <li> before HdmiControlService is disabled.
|
||||
* <li> after HdmiControlService is enabled and the local address is assigned.
|
||||
* </ul>
|
||||
* The client shouldn't hold the thread too long since this is a blocking call.
|
||||
*
|
||||
* @param enabled {@code true} if HdmiControlService is enabled.
|
||||
* @param reason the reason code why the state of HdmiControlService is changed.
|
||||
* @see #CONTROL_STATE_CHANGED_REASON_START
|
||||
* @see #CONTROL_STATE_CHANGED_REASON_SETTING
|
||||
* @see #CONTROL_STATE_CHANGED_REASON_WAKEUP
|
||||
* @see #CONTROL_STATE_CHANGED_REASON_STANDBY
|
||||
*/
|
||||
void onControlStateChanged(boolean enabled, int reason);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -23,5 +23,6 @@ package android.hardware.hdmi;
|
||||
* @hide
|
||||
*/
|
||||
oneway interface IHdmiVendorCommandListener {
|
||||
void onReceived(int logicalAddress, in byte[] operands, boolean hasVendorId);
|
||||
void onReceived(int logicalAddress, int destAddress, in byte[] operands, boolean hasVendorId);
|
||||
void onControlStateChanged(boolean enabled, int reason);
|
||||
}
|
||||
|
||||
@@ -516,8 +516,8 @@ abstract class HdmiCecLocalDevice {
|
||||
}
|
||||
|
||||
protected boolean handleVendorCommand(HdmiCecMessage message) {
|
||||
if (!mService.invokeVendorCommandListeners(mDeviceType, message.getSource(),
|
||||
message.getParams(), false)) {
|
||||
if (!mService.invokeVendorCommandListenersOnReceived(mDeviceType, message.getSource(),
|
||||
message.getDestination(), message.getParams(), false)) {
|
||||
// Vendor command listener may not have been registered yet. Respond with
|
||||
// <Feature Abort> [NOT_IN_CORRECT_MODE] so that the sender can try again later.
|
||||
mService.maySendFeatureAbortCommand(message, Constants.ABORT_NOT_IN_CORRECT_MODE);
|
||||
@@ -529,8 +529,8 @@ abstract class HdmiCecLocalDevice {
|
||||
byte[] params = message.getParams();
|
||||
int vendorId = HdmiUtils.threeBytesToInt(params);
|
||||
if (vendorId == mService.getVendorId()) {
|
||||
if (!mService.invokeVendorCommandListeners(mDeviceType, message.getSource(), params,
|
||||
true)) {
|
||||
if (!mService.invokeVendorCommandListenersOnReceived(mDeviceType, message.getSource(),
|
||||
message.getDestination(), params, true)) {
|
||||
mService.maySendFeatureAbortCommand(message, Constants.ABORT_NOT_IN_CORRECT_MODE);
|
||||
}
|
||||
} else if (message.getDestination() != Constants.ADDR_BROADCAST &&
|
||||
|
||||
@@ -316,20 +316,23 @@ public final class HdmiControlService extends SystemService {
|
||||
mMessageValidator = new HdmiCecMessageValidator(this);
|
||||
publishBinderService(Context.HDMI_CONTROL_SERVICE, new BinderService());
|
||||
|
||||
// Register broadcast receiver for power state change.
|
||||
if (mCecController != null) {
|
||||
// Register broadcast receiver for power state change.
|
||||
IntentFilter filter = new IntentFilter();
|
||||
filter.addAction(Intent.ACTION_SCREEN_OFF);
|
||||
filter.addAction(Intent.ACTION_SCREEN_ON);
|
||||
filter.addAction(Intent.ACTION_CONFIGURATION_CHANGED);
|
||||
getContext().registerReceiver(mHdmiControlBroadcastReceiver, filter);
|
||||
|
||||
// Register ContentObserver to monitor the settings change.
|
||||
registerContentObserver();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the initialization of local devices is complete.
|
||||
*/
|
||||
private void onInitializeCecComplete() {
|
||||
private void onInitializeCecComplete(int initiatedBy) {
|
||||
if (mPowerStatus == HdmiControlManager.POWER_STATUS_TRANSIENT_TO_ON) {
|
||||
mPowerStatus = HdmiControlManager.POWER_STATUS_ON;
|
||||
}
|
||||
@@ -337,7 +340,22 @@ public final class HdmiControlService extends SystemService {
|
||||
|
||||
if (isTvDevice()) {
|
||||
mCecController.setOption(OPTION_CEC_AUTO_WAKEUP, toInt(tv().getAutoWakeup()));
|
||||
registerContentObserver();
|
||||
}
|
||||
int reason = -1;
|
||||
switch (initiatedBy) {
|
||||
case INITIATED_BY_BOOT_UP:
|
||||
reason = HdmiControlManager.CONTROL_STATE_CHANGED_REASON_START;
|
||||
break;
|
||||
case INITIATED_BY_ENABLE_CEC:
|
||||
reason = HdmiControlManager.CONTROL_STATE_CHANGED_REASON_SETTING;
|
||||
break;
|
||||
case INITIATED_BY_SCREEN_ON:
|
||||
case INITIATED_BY_WAKE_UP_MESSAGE:
|
||||
reason = HdmiControlManager.CONTROL_STATE_CHANGED_REASON_WAKEUP;
|
||||
break;
|
||||
}
|
||||
if (reason != -1) {
|
||||
invokeVendorCommandListenersOnControlStateChanged(true, reason);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -402,10 +420,6 @@ public final class HdmiControlService extends SystemService {
|
||||
Global.putInt(cr, key, toInt(value));
|
||||
}
|
||||
|
||||
private void unregisterSettingsObserver() {
|
||||
getContext().getContentResolver().unregisterContentObserver(mSettingsObserver);
|
||||
}
|
||||
|
||||
private void initializeCec(int initiatedBy) {
|
||||
mCecController.setOption(OPTION_CEC_SERVICE_CONTROL, ENABLED);
|
||||
initializeLocalDevices(initiatedBy);
|
||||
@@ -460,7 +474,7 @@ public final class HdmiControlService extends SystemService {
|
||||
if (initiatedBy != INITIATED_BY_HOTPLUG) {
|
||||
// In case of the hotplug we don't call onInitializeCecComplete()
|
||||
// since we reallocate the logical address only.
|
||||
onInitializeCecComplete();
|
||||
onInitializeCecComplete(initiatedBy);
|
||||
}
|
||||
notifyAddressAllocated(allocatedDevices, initiatedBy);
|
||||
}
|
||||
@@ -1789,6 +1803,8 @@ public final class HdmiControlService extends SystemService {
|
||||
private void onStandby() {
|
||||
assertRunOnServiceThread();
|
||||
mPowerStatus = HdmiControlManager.POWER_STATUS_TRANSIENT_TO_STANDBY;
|
||||
invokeVendorCommandListenersOnControlStateChanged(false,
|
||||
HdmiControlManager.CONTROL_STATE_CHANGED_REASON_STANDBY);
|
||||
|
||||
final List<HdmiCecLocalDevice> devices = getAllLocalDevices();
|
||||
disableDevices(new PendingActionClearedCallback() {
|
||||
@@ -1827,9 +1843,6 @@ public final class HdmiControlService extends SystemService {
|
||||
for (HdmiCecLocalDevice device : mCecController.getLocalDeviceList()) {
|
||||
device.disableDevice(mStandbyMessageReceived, callback);
|
||||
}
|
||||
if (isTvDevice()) {
|
||||
unregisterSettingsObserver();
|
||||
}
|
||||
}
|
||||
|
||||
mMhlController.clearAllLocalDevices();
|
||||
@@ -1874,8 +1887,8 @@ public final class HdmiControlService extends SystemService {
|
||||
}
|
||||
}
|
||||
|
||||
boolean invokeVendorCommandListeners(int deviceType, int srcAddress, byte[] params,
|
||||
boolean hasVendorId) {
|
||||
boolean invokeVendorCommandListenersOnReceived(int deviceType, int srcAddress, int destAddress,
|
||||
byte[] params, boolean hasVendorId) {
|
||||
synchronized (mLock) {
|
||||
if (mVendorCommandListenerRecords.isEmpty()) {
|
||||
return false;
|
||||
@@ -1885,7 +1898,7 @@ public final class HdmiControlService extends SystemService {
|
||||
continue;
|
||||
}
|
||||
try {
|
||||
record.mListener.onReceived(srcAddress, params, hasVendorId);
|
||||
record.mListener.onReceived(srcAddress, destAddress, params, hasVendorId);
|
||||
} catch (RemoteException e) {
|
||||
Slog.e(TAG, "Failed to notify vendor command reception", e);
|
||||
}
|
||||
@@ -1894,6 +1907,22 @@ public final class HdmiControlService extends SystemService {
|
||||
}
|
||||
}
|
||||
|
||||
boolean invokeVendorCommandListenersOnControlStateChanged(boolean enabled, int reason) {
|
||||
synchronized (mLock) {
|
||||
if (mVendorCommandListenerRecords.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
for (VendorCommandListenerRecord record : mVendorCommandListenerRecords) {
|
||||
try {
|
||||
record.mListener.onControlStateChanged(enabled, reason);
|
||||
} catch (RemoteException e) {
|
||||
Slog.e(TAG, "Failed to notify control-state-changed to vendor handler", e);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
private void addHdmiMhlVendorCommandListener(IHdmiMhlVendorCommandListener listener) {
|
||||
HdmiMhlVendorCommandListenerRecord record =
|
||||
new HdmiMhlVendorCommandListenerRecord(listener);
|
||||
@@ -1943,6 +1972,11 @@ public final class HdmiControlService extends SystemService {
|
||||
void setControlEnabled(boolean enabled) {
|
||||
assertRunOnServiceThread();
|
||||
|
||||
if (!enabled) {
|
||||
// Call the vendor handler before the service is disabled.
|
||||
invokeVendorCommandListenersOnControlStateChanged(false,
|
||||
HdmiControlManager.CONTROL_STATE_CHANGED_REASON_SETTING);
|
||||
}
|
||||
int value = toInt(enabled);
|
||||
mCecController.setOption(OPTION_CEC_ENABLE, value);
|
||||
mMhlController.setOption(OPTION_MHL_ENABLE, value);
|
||||
|
||||
Reference in New Issue
Block a user