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

Commit f5fee3be authored by Nick Chalko's avatar Nick Chalko Committed by Automerger Merge Worker
Browse files

Merge "CEC: Add listener for HDMI CEC volume control feature" into rvc-dev am:...

Merge "CEC: Add listener for HDMI CEC volume control feature" into rvc-dev am: 75ef06da am: 1ce1702e am: df05db45

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/11246196

Change-Id: I6f435a7ca1bc098d69cab6694f4a9d43626a9506
parents 8e3bf54e df05db45
Loading
Loading
Loading
Loading
+93 −0
Original line number Original line Diff line number Diff line
@@ -18,6 +18,7 @@ package android.hardware.hdmi;


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


import android.annotation.CallbackExecutor;
import android.annotation.IntDef;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.Nullable;
@@ -30,6 +31,7 @@ import android.annotation.SystemApi;
import android.annotation.SystemService;
import android.annotation.SystemService;
import android.content.Context;
import android.content.Context;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager;
import android.os.Binder;
import android.os.RemoteException;
import android.os.RemoteException;
import android.os.SystemProperties;
import android.os.SystemProperties;
import android.util.ArrayMap;
import android.util.ArrayMap;
@@ -40,6 +42,7 @@ import com.android.internal.annotations.GuardedBy;
import java.util.ArrayList;
import java.util.ArrayList;
import java.util.List;
import java.util.List;
import java.util.Objects;
import java.util.Objects;
import java.util.concurrent.Executor;


/**
/**
 * The {@link HdmiControlManager} class is used to send HDMI control messages
 * The {@link HdmiControlManager} class is used to send HDMI control messages
@@ -817,6 +820,24 @@ public final class HdmiControlManager {
    private final ArrayMap<HdmiControlStatusChangeListener, IHdmiControlStatusChangeListener>
    private final ArrayMap<HdmiControlStatusChangeListener, IHdmiControlStatusChangeListener>
            mHdmiControlStatusChangeListeners = new ArrayMap<>();
            mHdmiControlStatusChangeListeners = new ArrayMap<>();


    /**
     * Listener used to get the status of the HDMI CEC volume control feature (enabled/disabled).
     * @hide
     */
    public interface HdmiCecVolumeControlFeatureListener {
        /**
         * Called when the HDMI Control (CEC) volume control feature is enabled/disabled.
         *
         * @param enabled status of HDMI CEC volume control feature
         * @see {@link HdmiControlManager#setHdmiCecVolumeControlEnabled(boolean)} ()}
         **/
        void onHdmiCecVolumeControlFeature(boolean enabled);
    }

    private final ArrayMap<HdmiCecVolumeControlFeatureListener,
            IHdmiCecVolumeControlFeatureListener>
            mHdmiCecVolumeControlFeatureListeners = new ArrayMap<>();

    /**
    /**
     * Listener used to get vendor-specific commands.
     * Listener used to get vendor-specific commands.
     */
     */
@@ -979,4 +1000,76 @@ public final class HdmiControlManager {
        };
        };
    }
    }


    /**
     * Adds a listener to get informed of changes to the state of the HDMI CEC volume control
     * feature.
     *
     * Upon adding a listener, the current state of the HDMI CEC volume control feature will be
     * sent immediately.
     *
     * <p>To stop getting the notification,
     * use {@link #removeHdmiCecVolumeControlFeatureListener(HdmiCecVolumeControlFeatureListener)}.
     *
     * @param listener {@link HdmiCecVolumeControlFeatureListener} instance
     * @hide
     * @see #removeHdmiCecVolumeControlFeatureListener(HdmiCecVolumeControlFeatureListener)
     */
    @RequiresPermission(android.Manifest.permission.HDMI_CEC)
    public void addHdmiCecVolumeControlFeatureListener(@NonNull @CallbackExecutor Executor executor,
            @NonNull HdmiCecVolumeControlFeatureListener listener) {
        if (mService == null) {
            Log.e(TAG, "HdmiControlService is not available");
            return;
        }
        if (mHdmiCecVolumeControlFeatureListeners.containsKey(listener)) {
            Log.e(TAG, "listener is already registered");
            return;
        }
        IHdmiCecVolumeControlFeatureListener wrappedListener =
                createHdmiCecVolumeControlFeatureListenerWrapper(executor, listener);
        mHdmiCecVolumeControlFeatureListeners.put(listener, wrappedListener);
        try {
            mService.addHdmiCecVolumeControlFeatureListener(wrappedListener);
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }

    /**
     * Removes a listener to stop getting informed of changes to the state of the HDMI CEC volume
     * control feature.
     *
     * @param listener {@link HdmiCecVolumeControlFeatureListener} instance to be removed
     * @hide
     */
    @RequiresPermission(android.Manifest.permission.HDMI_CEC)
    public void removeHdmiCecVolumeControlFeatureListener(
            HdmiCecVolumeControlFeatureListener listener) {
        if (mService == null) {
            Log.e(TAG, "HdmiControlService is not available");
            return;
        }
        IHdmiCecVolumeControlFeatureListener wrappedListener =
                mHdmiCecVolumeControlFeatureListeners.remove(listener);
        if (wrappedListener == null) {
            Log.e(TAG, "tried to remove not-registered listener");
            return;
        }
        try {
            mService.removeHdmiCecVolumeControlFeatureListener(wrappedListener);
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }

    private IHdmiCecVolumeControlFeatureListener createHdmiCecVolumeControlFeatureListenerWrapper(
            Executor executor, final HdmiCecVolumeControlFeatureListener listener) {
        return new android.hardware.hdmi.IHdmiCecVolumeControlFeatureListener.Stub() {
            @Override
            public void onHdmiCecVolumeControlFeature(boolean enabled) {
                Binder.clearCallingIdentity();
                executor.execute(() -> listener.onHdmiCecVolumeControlFeature(enabled));
            }
        };
    }
}
}
+32 −0
Original line number Original line Diff line number Diff line
/*
 * Copyright (C) 2020 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;

/**
 * Listener used to get the status of the HDMI CEC volume control feature (enabled/disabled).
 * @hide
 */
oneway interface IHdmiCecVolumeControlFeatureListener {

    /**
     * Called when the HDMI Control (CEC) volume control feature is enabled/disabled.
     *
     * @param enabled status of HDMI CEC volume control feature
     * @see {@link HdmiControlManager#setHdmiCecVolumeControlEnabled(boolean)} ()}
     **/
    void onHdmiCecVolumeControlFeature(boolean enabled);
}
+3 −0
Original line number Original line Diff line number Diff line
@@ -18,6 +18,7 @@ package android.hardware.hdmi;


import android.hardware.hdmi.HdmiDeviceInfo;
import android.hardware.hdmi.HdmiDeviceInfo;
import android.hardware.hdmi.HdmiPortInfo;
import android.hardware.hdmi.HdmiPortInfo;
import android.hardware.hdmi.IHdmiCecVolumeControlFeatureListener;
import android.hardware.hdmi.IHdmiControlCallback;
import android.hardware.hdmi.IHdmiControlCallback;
import android.hardware.hdmi.IHdmiControlStatusChangeListener;
import android.hardware.hdmi.IHdmiControlStatusChangeListener;
import android.hardware.hdmi.IHdmiDeviceEventListener;
import android.hardware.hdmi.IHdmiDeviceEventListener;
@@ -44,6 +45,8 @@ interface IHdmiControlService {
    void queryDisplayStatus(IHdmiControlCallback callback);
    void queryDisplayStatus(IHdmiControlCallback callback);
    void addHdmiControlStatusChangeListener(IHdmiControlStatusChangeListener listener);
    void addHdmiControlStatusChangeListener(IHdmiControlStatusChangeListener listener);
    void removeHdmiControlStatusChangeListener(IHdmiControlStatusChangeListener listener);
    void removeHdmiControlStatusChangeListener(IHdmiControlStatusChangeListener listener);
    void addHdmiCecVolumeControlFeatureListener(IHdmiCecVolumeControlFeatureListener listener);
    void removeHdmiCecVolumeControlFeatureListener(IHdmiCecVolumeControlFeatureListener listener);
    void addHotplugEventListener(IHdmiHotplugEventListener listener);
    void addHotplugEventListener(IHdmiHotplugEventListener listener);
    void removeHotplugEventListener(IHdmiHotplugEventListener listener);
    void removeHotplugEventListener(IHdmiHotplugEventListener listener);
    void addDeviceEventListener(IHdmiDeviceEventListener listener);
    void addDeviceEventListener(IHdmiDeviceEventListener listener);
+10 −0
Original line number Original line Diff line number Diff line
@@ -363,6 +363,16 @@ public class HdmiAudioSystemClientTest {
        public boolean isHdmiCecVolumeControlEnabled() {
        public boolean isHdmiCecVolumeControlEnabled() {
            return true;
            return true;
        }
        }

        @Override
        public void addHdmiCecVolumeControlFeatureListener(
                IHdmiCecVolumeControlFeatureListener listener) {
        }

        @Override
        public void removeHdmiCecVolumeControlFeatureListener(
                IHdmiCecVolumeControlFeatureListener listener) {
        }
    }
    }


}
}
+63 −0
Original line number Original line Diff line number Diff line
@@ -40,6 +40,7 @@ import android.hardware.hdmi.HdmiControlManager;
import android.hardware.hdmi.HdmiDeviceInfo;
import android.hardware.hdmi.HdmiDeviceInfo;
import android.hardware.hdmi.HdmiHotplugEvent;
import android.hardware.hdmi.HdmiHotplugEvent;
import android.hardware.hdmi.HdmiPortInfo;
import android.hardware.hdmi.HdmiPortInfo;
import android.hardware.hdmi.IHdmiCecVolumeControlFeatureListener;
import android.hardware.hdmi.IHdmiControlCallback;
import android.hardware.hdmi.IHdmiControlCallback;
import android.hardware.hdmi.IHdmiControlService;
import android.hardware.hdmi.IHdmiControlService;
import android.hardware.hdmi.IHdmiControlStatusChangeListener;
import android.hardware.hdmi.IHdmiControlStatusChangeListener;
@@ -63,6 +64,7 @@ import android.os.HandlerThread;
import android.os.IBinder;
import android.os.IBinder;
import android.os.Looper;
import android.os.Looper;
import android.os.PowerManager;
import android.os.PowerManager;
import android.os.RemoteCallbackList;
import android.os.RemoteException;
import android.os.RemoteException;
import android.os.SystemClock;
import android.os.SystemClock;
import android.os.SystemProperties;
import android.os.SystemProperties;
@@ -264,6 +266,11 @@ public class HdmiControlService extends SystemService {
    private final ArrayList<HdmiControlStatusChangeListenerRecord>
    private final ArrayList<HdmiControlStatusChangeListenerRecord>
            mHdmiControlStatusChangeListenerRecords = new ArrayList<>();
            mHdmiControlStatusChangeListenerRecords = new ArrayList<>();


    // List of records for HDMI control volume control status change listener for death monitoring.
    @GuardedBy("mLock")
    private final RemoteCallbackList<IHdmiCecVolumeControlFeatureListener>
            mHdmiCecVolumeControlFeatureListenerRecords = new RemoteCallbackList<>();

    // List of records for hotplug event listener to handle the the caller killed in action.
    // List of records for hotplug event listener to handle the the caller killed in action.
    @GuardedBy("mLock")
    @GuardedBy("mLock")
    private final ArrayList<HotplugEventListenerRecord> mHotplugEventListenerRecords =
    private final ArrayList<HotplugEventListenerRecord> mHotplugEventListenerRecords =
@@ -1801,6 +1808,21 @@ public class HdmiControlService extends SystemService {
            HdmiControlService.this.removeHdmiControlStatusChangeListener(listener);
            HdmiControlService.this.removeHdmiControlStatusChangeListener(listener);
        }
        }


        @Override
        public void addHdmiCecVolumeControlFeatureListener(
                final IHdmiCecVolumeControlFeatureListener listener) {
            enforceAccessPermission();
            HdmiControlService.this.addHdmiCecVolumeControlFeatureListener(listener);
        }

        @Override
        public void removeHdmiCecVolumeControlFeatureListener(
                final IHdmiCecVolumeControlFeatureListener listener) {
            enforceAccessPermission();
            HdmiControlService.this.removeHdmiControlVolumeControlStatusChangeListener(listener);
        }


        @Override
        @Override
        public void addHotplugEventListener(final IHdmiHotplugEventListener listener) {
        public void addHotplugEventListener(final IHdmiHotplugEventListener listener) {
            enforceAccessPermission();
            enforceAccessPermission();
@@ -2397,6 +2419,33 @@ public class HdmiControlService extends SystemService {
        }
        }
    }
    }


    @VisibleForTesting
    void addHdmiCecVolumeControlFeatureListener(
            final IHdmiCecVolumeControlFeatureListener listener) {
        mHdmiCecVolumeControlFeatureListenerRecords.register(listener);

        runOnServiceThread(new Runnable() {
            @Override
            public void run() {
                // Return the current status of mHdmiCecVolumeControlEnabled;
                synchronized (mLock) {
                    try {
                        listener.onHdmiCecVolumeControlFeature(mHdmiCecVolumeControlEnabled);
                    } catch (RemoteException e) {
                        Slog.e(TAG, "Failed to report HdmiControlVolumeControlStatusChange: "
                                + mHdmiCecVolumeControlEnabled, e);
                    }
                }
            }
        });
    }

    @VisibleForTesting
    void removeHdmiControlVolumeControlStatusChangeListener(
            final IHdmiCecVolumeControlFeatureListener listener) {
        mHdmiCecVolumeControlFeatureListenerRecords.unregister(listener);
    }

    private void addHotplugEventListener(final IHdmiHotplugEventListener listener) {
    private void addHotplugEventListener(final IHdmiHotplugEventListener listener) {
        final HotplugEventListenerRecord record = new HotplugEventListenerRecord(listener);
        final HotplugEventListenerRecord record = new HotplugEventListenerRecord(listener);
        try {
        try {
@@ -2670,6 +2719,19 @@ public class HdmiControlService extends SystemService {
        }
        }
    }
    }


    private void announceHdmiCecVolumeControlFeatureChange(boolean isEnabled) {
        assertRunOnServiceThread();
        mHdmiCecVolumeControlFeatureListenerRecords.broadcast(listener -> {
            try {
                listener.onHdmiCecVolumeControlFeature(isEnabled);
            } catch (RemoteException e) {
                Slog.e(TAG,
                        "Failed to report HdmiControlVolumeControlStatusChange: "
                                + isEnabled);
            }
        });
    }

    public HdmiCecLocalDeviceTv tv() {
    public HdmiCecLocalDeviceTv tv() {
        return (HdmiCecLocalDeviceTv) mCecController.getLocalDevice(HdmiDeviceInfo.DEVICE_TV);
        return (HdmiCecLocalDeviceTv) mCecController.getLocalDevice(HdmiDeviceInfo.DEVICE_TV);
    }
    }
@@ -3014,6 +3076,7 @@ public class HdmiControlService extends SystemService {
                        isHdmiCecVolumeControlEnabled);
                        isHdmiCecVolumeControlEnabled);
            }
            }
        }
        }
        announceHdmiCecVolumeControlFeatureChange(isHdmiCecVolumeControlEnabled);
    }
    }


    boolean isHdmiCecVolumeControlEnabled() {
    boolean isHdmiCecVolumeControlEnabled() {
Loading