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

Commit 726a71c0 authored by Shubang Lu's avatar Shubang Lu Committed by Android (Google) Code Review
Browse files

Merge changes Iac5d191d,Ia090bd70,I61f7bf38,Ibc9b7071,I889b6cdc, ...

* changes:
  Add launchDeviceDiscovery when devices just plugged into the current device or the current device just conneted to a TV.
  Fix pathToPort logic in HdmiControlService
  Update the power status of an existing hdmi device with TIF once receive Report Power Status or Active Source from the existing device.
  Add HDMI device info into TIF once receive report Physical Address or Set Osd Name from a new device.
  Change the pathToPort(int path) method in HdmiControlService to apply to not only TV device.
  Modify on hotPlug logic for Audio devices
  Add array and add/remove methods to track connected device info
  Modify doManualPortSwitching logic in Audio System
  Add HdmiSwitchClient and move isSwitch property to system ro property
  Wake up device when device is in dozing but CEC power status is on.
parents 9114be68 c00cd4e0
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";
+12 −5
Original line number Diff line number Diff line
@@ -28,7 +28,7 @@ import java.util.List;

/**
 * Feature action that handles device discovery sequences.
 * Device discovery is launched when TV device is woken from "Standby" state
 * Device discovery is launched when device is woken from "Standby" state
 * or enabled "Control for Hdmi" from disabled state.
 *
 * <p>Device discovery goes through the following steps.
@@ -89,6 +89,7 @@ final class DeviceDiscoveryAction extends HdmiCecFeatureAction {
    private final DeviceDiscoveryCallback mCallback;
    private int mProcessedDeviceCount = 0;
    private int mTimeoutRetry = 0;
    private boolean mIsTvDevice = source().mService.isTvDevice();

    /**
     * Constructor.
@@ -266,15 +267,19 @@ final class DeviceDiscoveryAction extends HdmiCecFeatureAction {
        current.mPortId = getPortId(current.mPhysicalAddress);
        current.mDeviceType = params[2] & 0xFF;

        // TODO(amyjojo): check if non-TV device needs to update cec switch info.
        // This is to manager CEC device separately in case they don't have address.
        if (mIsTvDevice) {
            tv().updateCecSwitchInfo(current.mLogicalAddress, current.mDeviceType,
                    current.mPhysicalAddress);

        }
        increaseProcessedDeviceCount();
        checkAndProceedStage();
    }

    private int getPortId(int physicalAddress) {
        return tv().getPortId(physicalAddress);
        return mIsTvDevice ? tv().getPortId(physicalAddress)
            : source().getPortId(physicalAddress);
    }

    private void handleSetOsdName(HdmiCecMessage cmd) {
@@ -345,8 +350,10 @@ final class DeviceDiscoveryAction extends HdmiCecFeatureAction {
        mCallback.onDeviceDiscoveryDone(result);
        finish();
        // Process any commands buffered while device discovery action was in progress.
        if (mIsTvDevice) {
            tv().processAllDelayedMessages();
        }
    }

    private void checkAndProceedStage() {
        if (mDevices.isEmpty()) {
Loading