Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 26ea56b3 authored by Yuncheol Heo's avatar Yuncheol Heo Committed by Android Git Automerger
Browse files

am 5814bf1c: am 0608b932: CEC: Add a callback for vendor when HDMI control setting is changed.

* commit '5814bf1c':
  CEC: Add a callback for vendor when HDMI control setting is changed.
parents dcc80043 5814bf1c
Loading
Loading
Loading
Loading
+7 −3
Original line number Diff line number Diff line
@@ -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);
            }
        };
    }
+28 −1
Original line number Diff line number Diff line
@@ -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);
    }

    /**
+2 −1
Original line number Diff line number Diff line
@@ -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);
}
+4 −4
Original line number Diff line number Diff line
@@ -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 &&
+48 −14
Original line number Diff line number Diff line
@@ -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);