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

Commit 1ffe68c9 authored by Jungshik Jang's avatar Jungshik Jang Committed by Android (Google) Code Review
Browse files

Merge "Move message handling logic to local device instead of service."

parents f980c53f 092b445e
Loading
Loading
Loading
Loading
+2 −4
Original line number Diff line number Diff line
@@ -259,7 +259,7 @@ final class DeviceDiscoveryAction extends FeatureAction {

        byte params[] = cmd.getParams();
        if (params.length == 3) {
            current.mPhysicalAddress = ((params[0] & 0xFF) << 8) | (params[1] & 0xFF);
            current.mPhysicalAddress = HdmiUtils.twoBytesToInt(params);
            current.mDeviceType = params[2] & 0xFF;

            increaseProcessedDeviceCount();
@@ -307,9 +307,7 @@ final class DeviceDiscoveryAction extends FeatureAction {

        byte[] params = cmd.getParams();
        if (params.length == 3) {
            int vendorId = ((params[0] & 0xFF) << 16)
                    | ((params[1] & 0xFF) << 8)
                    | (params[2] & 0xFF);
            int vendorId = HdmiUtils.threeBytesToInt(params);
            current.mVendorId = vendorId;
        } else {
            Slog.w(TAG, "Invalid vendor id: " + cmd.toString());
+39 −0
Original line number Diff line number Diff line
@@ -386,6 +386,41 @@ final class HdmiCecController {
        return nativeGetVendorId(mNativePtr);
    }

    /**
     * Pass a option to CEC HAL.
     *
     * @param flag a key of option. For more details, look at
     *        {@link HdmiConstants#FLAG_HDMI_OPTION_WAKEUP} to
     *        {@link HdmiConstants#FLAG_HDMI_OPTION_SYSTEM_CEC_CONTROL}
     * @param value a value of option. Actual value varies flag. For more
     *        details, look at description of flags
     */
    void setOption(int flag, int value) {
        assertRunOnServiceThread();
        nativeSetOption(mNativePtr, flag, value);
    }

    /**
     * Configure ARC circuit in the hardware logic to start or stop the feature.
     *
     * @param enabled whether to enable/disable ARC
     */
    void setAudioReturnChannel(boolean enabled) {
        assertRunOnServiceThread();
        nativeSetAudioReturnChannel(mNativePtr, enabled);
    }

    /**
     * Return the connection status of the specified port
     *
     * @param port port number to check connection status
     * @return true if connected; otherwise, return false
     */
    boolean isConnected(int port) {
        assertRunOnServiceThread();
        return nativeIsConnected(mNativePtr, port);
    }

    /**
     * Poll all remote devices. It sends &lt;Polling Message&gt; to all remote
     * devices.
@@ -606,4 +641,8 @@ final class HdmiCecController {
    private static native int nativeGetPhysicalAddress(long controllerPtr);
    private static native int nativeGetVersion(long controllerPtr);
    private static native int nativeGetVendorId(long controllerPtr);
    private static native void nativeSetOption(long controllerPtr, int flag, int value);
    private static native void nativeSetAudioReturnChannel(long controllerPtr, boolean flag);
    private static native boolean nativeIsConnected(long controllerPtr, int port);

}
+80 −0
Original line number Diff line number Diff line
@@ -18,12 +18,15 @@ package com.android.server.hdmi;

import android.hardware.hdmi.HdmiCec;
import android.hardware.hdmi.HdmiCecDeviceInfo;
import android.hardware.hdmi.HdmiCecMessage;
import android.util.Slog;

/**
 * Class that models a logical CEC device hosted in this system. Handles initialization,
 * CEC commands that call for actions customized per device type.
 */
abstract class HdmiCecLocalDevice {
    private static final String TAG = "HdmiCecLocalDevice";

    protected final HdmiControlService mService;
    protected final int mDeviceType;
@@ -59,6 +62,83 @@ abstract class HdmiCecLocalDevice {
     */
    protected abstract void onAddressAllocated(int logicalAddress);

    /**
     * Dispatch incoming message.
     *
     * @param message incoming message
     * @return true if consumed a message; otherwise, return false.
     */
    final boolean dispatchMessage(HdmiCecMessage message) {
        int dest = message.getDestination();
        if (dest != mAddress && dest != HdmiCec.ADDR_BROADCAST) {
            return false;
        }
        return onMessage(message);
    }

    protected boolean onMessage(HdmiCecMessage message) {
        switch (message.getOpcode()) {
            case HdmiCec.MESSAGE_GET_MENU_LANGUAGE:
                return handleGetMenuLanguage(message);
            case HdmiCec.MESSAGE_GIVE_PHYSICAL_ADDRESS:
                return handleGivePhysicalAddress();
            case HdmiCec.MESSAGE_GIVE_OSD_NAME:
                return handleGiveOsdName(message);
            case HdmiCec.MESSAGE_GIVE_DEVICE_VENDOR_ID:
                return handleGiveDeviceVendorId();
            case HdmiCec.MESSAGE_GET_CEC_VERSION:
                return handleGetCecVersion(message);
            default:
                return false;
        }
    }

    protected boolean handleGivePhysicalAddress() {
        int physicalAddress = mService.getPhysicalAddress();
        HdmiCecMessage cecMessage = HdmiCecMessageBuilder.buildReportPhysicalAddressCommand(
                mAddress, physicalAddress, mDeviceType);
        mService.sendCecCommand(cecMessage);
        return true;
    }

    protected boolean handleGiveDeviceVendorId() {
        int vendorId = mService.getVendorId();
        HdmiCecMessage cecMessage = HdmiCecMessageBuilder.buildDeviceVendorIdCommand(
                mAddress, vendorId);
        mService.sendCecCommand(cecMessage);
        return true;
    }

    protected boolean handleGetCecVersion(HdmiCecMessage message) {
        int version = mService.getCecVersion();
        HdmiCecMessage cecMessage = HdmiCecMessageBuilder.buildCecVersion(message.getDestination(),
                message.getSource(), version);
        mService.sendCecCommand(cecMessage);
        return true;
    }

    protected boolean handleGetMenuLanguage(HdmiCecMessage message) {
        Slog.w(TAG, "Only TV can handle <Get Menu Language>:" + message.toString());
        mService.sendCecCommand(
                HdmiCecMessageBuilder.buildFeatureAbortCommand(mAddress,
                        message.getSource(), HdmiCec.MESSAGE_GET_MENU_LANGUAGE,
                        HdmiConstants.ABORT_UNRECOGNIZED_MODE));
        return true;
    }

    protected boolean handleGiveOsdName(HdmiCecMessage message) {
        // Note that since this method is called after logical address allocation is done,
        // mDeviceInfo should not be null.
        HdmiCecMessage cecMessage = HdmiCecMessageBuilder.buildSetOsdNameCommand(
                mAddress, message.getSource(), mDeviceInfo.getDisplayName());
        if (cecMessage != null) {
            mService.sendCecCommand(cecMessage);
        } else {
            Slog.w(TAG, "Failed to build <Get Osd Name>:" + mDeviceInfo.getDisplayName());
        }
        return true;
    }

    final void handleAddressAllocated(int logicalAddress) {
        mAddress = mPreferredAddress = logicalAddress;
        onAddressAllocated(logicalAddress);
+43 −0
Original line number Diff line number Diff line
@@ -17,11 +17,16 @@
package com.android.server.hdmi;

import android.hardware.hdmi.HdmiCec;
import android.hardware.hdmi.HdmiCecMessage;
import android.util.Slog;

import java.util.Locale;

/**
 * Represent a logical device of type TV residing in Android system.
 */
final class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice {
    private static final String TAG = "HdmiCecLocalDeviceTv";

    HdmiCecLocalDeviceTv(HdmiControlService service) {
        super(service, HdmiCec.DEVICE_TV);
@@ -39,4 +44,42 @@ final class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice {
        mService.launchDeviceDiscovery(mAddress);
        // TODO: Start routing control action, device discovery action.
    }

    @Override
    protected boolean onMessage(HdmiCecMessage message) {
        switch (message.getOpcode()) {
            case HdmiCec.MESSAGE_REPORT_PHYSICAL_ADDRESS:
                return handleReportPhysicalAddress(message);
            default:
                return super.onMessage(message);
        }
    }

    @Override
    protected boolean handleGetMenuLanguage(HdmiCecMessage message) {
        HdmiCecMessage command = HdmiCecMessageBuilder.buildSetMenuLanguageCommand(
                mAddress, Locale.getDefault().getISO3Language());
        // TODO: figure out how to handle failed to get language code.
        if (command != null) {
            mService.sendCecCommand(command);
        } else {
            Slog.w(TAG, "Failed to respond to <Get Menu Language>: " + message.toString());
        }
        return true;
    }

    private boolean handleReportPhysicalAddress(HdmiCecMessage message) {
        // Ignore if [Device Discovery Action] is going on.
        if (mService.hasAction(DeviceDiscoveryAction.class)) {
            Slog.i(TAG, "Ignore unrecognizable <Report Physical Address> "
                    + "because Device Discovery Action is on-going:" + message);
            return true;
        }

        int physicalAddress = HdmiUtils.twoBytesToInt(message.getParams());
        mService.addAndStartAction(new NewDeviceAction(mService,
                mAddress, message.getSource(), physicalAddress));

        return true;
    }
}
+26 −0
Original line number Diff line number Diff line
@@ -43,5 +43,31 @@ final class HdmiConstants {
    static final int UI_COMMAND_MUTE_FUNCTION = 0x65;
    static final int UI_COMMAND_RESTORE_VOLUME_FUNCTION = 0x66;

    // Flags used for setOption to CEC HAL.
    /**
     * When set to false, HAL does not wake up the system upon receiving
     * <Image View On> or <Text View On>. Used when user changes the TV
     * settings to disable the auto TV on functionality.
     * True by default.
     */
    static final int FLAG_HDMI_OPTION_WAKEUP = 1;
    /**
     * When set to false, all the CEC commands are discarded. Used when
     * user changes the TV settings to disable CEC functionality.
     * True by default.
     */
    static final int FLAG_HDMI_OPTION_ENABLE_CEC = 2;
    /**
     * Setting this flag to false means Android system will stop handling
     * CEC service and yield the control over to the microprocessor that is
     * powered on through the standby mode. When set to true, the system
     * will gain the control over, hence telling the microprocessor to stop
     * handling the cec commands. This is called when system goes
     * in and out of standby mode to notify the microprocessor that it should
     * start/stop handling CEC commands on behalf of the system.
     * False by default.
     */
    static final int FLAG_HDMI_OPTION_SYSTEM_CEC_CONTROL = 3;

    private HdmiConstants() { /* cannot be instantiated */ }
}
Loading