Loading core/java/android/hardware/hdmi/HdmiClient.java +7 −3 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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); } }; } Loading core/java/android/hardware/hdmi/HdmiControlManager.java +28 −1 Original line number Diff line number Diff line Loading @@ -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. Loading Loading @@ -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); } /** Loading core/java/android/hardware/hdmi/IHdmiVendorCommandListener.aidl +2 −1 Original line number Diff line number Diff line Loading @@ -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); } services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java +4 −4 Original line number Diff line number Diff line Loading @@ -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); Loading @@ -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 && Loading services/core/java/com/android/server/hdmi/HdmiControlService.java +48 −14 Original line number Diff line number Diff line Loading @@ -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; } Loading @@ -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); } } Loading Loading @@ -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); Loading Loading @@ -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); } Loading Loading @@ -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() { Loading Loading @@ -1827,9 +1843,6 @@ public final class HdmiControlService extends SystemService { for (HdmiCecLocalDevice device : mCecController.getLocalDeviceList()) { device.disableDevice(mStandbyMessageReceived, callback); } if (isTvDevice()) { unregisterSettingsObserver(); } } mMhlController.clearAllLocalDevices(); Loading Loading @@ -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; Loading @@ -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); } Loading @@ -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); Loading Loading @@ -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); Loading Loading
core/java/android/hardware/hdmi/HdmiClient.java +7 −3 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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); } }; } Loading
core/java/android/hardware/hdmi/HdmiControlManager.java +28 −1 Original line number Diff line number Diff line Loading @@ -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. Loading Loading @@ -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); } /** Loading
core/java/android/hardware/hdmi/IHdmiVendorCommandListener.aidl +2 −1 Original line number Diff line number Diff line Loading @@ -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); }
services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java +4 −4 Original line number Diff line number Diff line Loading @@ -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); Loading @@ -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 && Loading
services/core/java/com/android/server/hdmi/HdmiControlService.java +48 −14 Original line number Diff line number Diff line Loading @@ -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; } Loading @@ -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); } } Loading Loading @@ -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); Loading Loading @@ -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); } Loading Loading @@ -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() { Loading Loading @@ -1827,9 +1843,6 @@ public final class HdmiControlService extends SystemService { for (HdmiCecLocalDevice device : mCecController.getLocalDeviceList()) { device.disableDevice(mStandbyMessageReceived, callback); } if (isTvDevice()) { unregisterSettingsObserver(); } } mMhlController.clearAllLocalDevices(); Loading Loading @@ -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; Loading @@ -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); } Loading @@ -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); Loading Loading @@ -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); Loading