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