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

Commit 17ee20fc authored by Amy's avatar Amy Committed by shubang
Browse files

Add HdmiSwitchClient and move isSwitch property to system ro property

ag/5246742

Test: local tested
Bug:112478040
Change-Id: I62b33b0a4c69a0c4b3760706b48b63cf858e435b
parent ae4ee34d
Loading
Loading
Loading
Loading
+31 −0
Original line number Diff line number Diff line
@@ -16,6 +16,8 @@

package android.hardware.hdmi;

import static com.android.internal.os.RoSystemProperties.PROPERTY_HDMI_IS_DEVICE_HDMI_CEC_SWITCH;

import android.annotation.Nullable;
import android.annotation.RequiresFeature;
import android.annotation.RequiresPermission;
@@ -27,6 +29,7 @@ import android.annotation.SystemService;
import android.content.Context;
import android.content.pm.PackageManager;
import android.os.RemoteException;
import android.os.SystemProperties;
import android.util.ArrayMap;
import android.util.Log;

@@ -264,6 +267,10 @@ public final class HdmiControlManager {
    private final boolean mHasTvDevice;
    // True if we have a logical device of type audio system hosted in the system.
    private final boolean mHasAudioSystemDevice;
    // True if we have a logical device of type audio system hosted in the system.
    private final boolean mHasSwitchDevice;
    // True if it's a switch device.
    private final boolean mIsSwitchDevice;

    /**
     * {@hide} - hide this constructor because it has a parameter of type IHdmiControlService,
@@ -283,6 +290,9 @@ public final class HdmiControlManager {
        mHasTvDevice = hasDeviceType(types, HdmiDeviceInfo.DEVICE_TV);
        mHasPlaybackDevice = hasDeviceType(types, HdmiDeviceInfo.DEVICE_PLAYBACK);
        mHasAudioSystemDevice = hasDeviceType(types, HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM);
        mHasSwitchDevice = hasDeviceType(types, HdmiDeviceInfo.DEVICE_PURE_CEC_SWITCH);
        mIsSwitchDevice = SystemProperties.getBoolean(
            PROPERTY_HDMI_IS_DEVICE_HDMI_CEC_SWITCH, false);
    }

    private static boolean hasDeviceType(int[] types, int type) {
@@ -319,6 +329,9 @@ public final class HdmiControlManager {
                return mHasPlaybackDevice ? new HdmiPlaybackClient(mService) : null;
            case HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM:
                return mHasAudioSystemDevice ? new HdmiAudioSystemClient(mService) : null;
            case HdmiDeviceInfo.DEVICE_PURE_CEC_SWITCH:
                return (mHasSwitchDevice || mIsSwitchDevice)
                    ? new HdmiSwitchClient(mService) : null;
            default:
                return null;
        }
@@ -372,6 +385,24 @@ public final class HdmiControlManager {
        return (HdmiAudioSystemClient) getClient(HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM);
    }

    /**
     * Gets an object that represents an HDMI-CEC logical device of type switch on the system.
     *
     * <p>Used to send HDMI control messages to other devices like TV through HDMI bus. It is also
     * possible to communicate with other logical devices hosted in the same system if the system is
     * configured to host more than one type of HDMI-CEC logical devices.
     *
     * @return {@link HdmiSwitchClient} instance. {@code null} on failure.
     *
     * TODO(b/110094868): unhide for Q
     * @hide
     */
    @Nullable
    @SuppressLint("Doclava125")
    public HdmiSwitchClient getSwitchClient() {
        return (HdmiSwitchClient) getClient(HdmiDeviceInfo.DEVICE_PURE_CEC_SWITCH);
    }

    /**
     * Controls standby mode of the system. It will also try to turn on/off the connected devices if
     * necessary.
+137 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2018 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package android.hardware.hdmi;

import android.annotation.NonNull;
import android.os.RemoteException;
import android.util.Log;

import java.util.Collections;
import java.util.List;

/**
 * HdmiSwitchClient represents HDMI-CEC logical device of type Switch in the Android system which
 * acts as switch.
 *
 * <p>HdmiSwitchClient has a CEC device type of HdmiDeviceInfo.DEVICE_PURE_CEC_SWITCH,
 * but it is used by all Android TV devices that have multiple HDMI inputs,
 * even if it is not a "pure" swicth and has another device type like TV or Player.
 *
 * @hide
 * TODO(b/110094868): unhide and add @SystemApi for Q
 */
public class HdmiSwitchClient extends HdmiClient {

    private static final String TAG = "HdmiSwitchClient";

    /* package */ HdmiSwitchClient(IHdmiControlService service) {
        super(service);
    }

    private static IHdmiControlCallback getCallbackWrapper(final SelectCallback callback) {
        return new IHdmiControlCallback.Stub() {
            @Override
            public void onComplete(int result) {
                callback.onComplete(result);
            }
        };
    }

    /** @hide */
    // TODO(b/110094868): unhide for Q
    @Override
    public int getDeviceType() {
        return HdmiDeviceInfo.DEVICE_PURE_CEC_SWITCH;
    }

    /**
     * Selects a CEC logical device to be a new active source.
     *
     * @param logicalAddress logical address of the device to select
     * @param callback callback to get the result with
     * @throws {@link IllegalArgumentException} if the {@code callback} is null
     *
     * @hide
     * TODO(b/110094868): unhide and add @SystemApi for Q
     */
    public void deviceSelect(int logicalAddress, @NonNull SelectCallback callback) {
        if (callback == null) {
            throw new IllegalArgumentException("callback must not be null.");
        }
        try {
            mService.deviceSelect(logicalAddress, getCallbackWrapper(callback));
        } catch (RemoteException e) {
            Log.e(TAG, "failed to select device: ", e);
        }
    }

    /**
     * Selects a HDMI port to be a new route path.
     *
     * @param portId HDMI port to select
     * @param callback callback to get the result with
     * @throws {@link IllegalArgumentException} if the {@code callback} is null
     *
     * @hide
     * TODO(b/110094868): unhide and add @SystemApi for Q
     */
    public void portSelect(int portId, @NonNull SelectCallback callback) {
        if (callback == null) {
            throw new IllegalArgumentException("Callback must not be null");
        }
        try {
            mService.portSelect(portId, getCallbackWrapper(callback));
        } catch (RemoteException e) {
            Log.e(TAG, "failed to select port: ", e);
        }
    }

    /**
     * Returns all the CEC devices connected to the device.
     *
     * <p>This only applies to device with multiple HDMI inputs
     *
     * @return list of {@link HdmiDeviceInfo} for connected CEC devices. Empty list is returned if
     * there is none.
     *
     * @hide
     * TODO(b/110094868): unhide and add @SystemApi for Q
     */
    public List<HdmiDeviceInfo> getDeviceList() {
        try {
            return mService.getDeviceList();
        } catch (RemoteException e) {
            Log.e("TAG", "Failed to call getDeviceList():", e);
            return Collections.<HdmiDeviceInfo>emptyList();
        }
    }

    /**
     * Callback interface used to get the result of {@link #deviceSelect} or {@link #portSelect}.
     *
     * @hide
     * TODO(b/110094868): unhide and add @SystemApi for Q
     */
    public interface SelectCallback {

        /**
         * Called when the operation is finished.
         *
         * @param result the result value of {@link #deviceSelect} or {@link #portSelect}.
         */
        void onComplete(int result);
    }
}
+9 −0
Original line number Diff line number Diff line
@@ -30,6 +30,7 @@ public class RoSystemProperties {
    public static final String CONTROL_PRIVAPP_PERMISSIONS =
            SystemProperties.get("ro.control_privapp_permissions");

    // ------ ro.hdmi.* -------- //
    /**
     * Property to indicate if a CEC audio device should forward volume keys when system audio
     * mode is off.
@@ -38,6 +39,14 @@ public class RoSystemProperties {
            SystemProperties.getBoolean(
                    "ro.hdmi.cec_audio_device_forward_volume_keys_system_audio_mode_off", false);

    /**
     * Property to indicate if the current device is a cec switch device.
     *
     * <p> Default is false.
     */
    public static final String PROPERTY_HDMI_IS_DEVICE_HDMI_CEC_SWITCH =
            "ro.hdmi.property_is_device_hdmi_cec_switch";

    // ------ ro.config.* -------- //
    public static final boolean CONFIG_AVOID_GFX_ACCEL =
            SystemProperties.getBoolean("ro.config.avoid_gfx_accel", false);
+0 −8
Original line number Diff line number Diff line
@@ -343,14 +343,6 @@ final class Constants {
    static final String PROPERTY_HDMI_CEC_NEVER_ASSIGN_LOGICAL_ADDRESSES =
            "ro.hdmi.property_hdmi_cec_never_assign_logical_addresses";

    /**
     * Property to indicate if the current device is a cec switch device.
     *
     * <p> Default is false.
     */
    static final String PROPERTY_HDMI_IS_DEVICE_HDMI_CEC_SWITCH =
            "ro.hdmi.property_is_device_hdmi_cec_switch";

    // Set to false to allow playback device to go to suspend mode even
    // when it's an active source. True by default.
    static final String PROPERTY_KEEP_AWAKE = "persist.sys.hdmi.keep_awake";
+3 −1
Original line number Diff line number Diff line
@@ -16,6 +16,8 @@

package com.android.server.hdmi;

import static com.android.internal.os.RoSystemProperties.PROPERTY_HDMI_IS_DEVICE_HDMI_CEC_SWITCH;

import android.hardware.hdmi.HdmiControlManager;
import android.hardware.hdmi.IHdmiControlCallback;
import android.os.SystemProperties;
@@ -42,7 +44,7 @@ abstract class HdmiCecLocalDeviceSource extends HdmiCecLocalDevice {
    // Device has cec switch functionality or not.
    // Default is false.
    protected boolean mIsSwitchDevice = SystemProperties.getBoolean(
            Constants.PROPERTY_HDMI_IS_DEVICE_HDMI_CEC_SWITCH, false);
            PROPERTY_HDMI_IS_DEVICE_HDMI_CEC_SWITCH, false);

    // Routing port number used for Routing Control.
    // This records the default routing port or the previous valid routing port.
Loading