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

Commit cb802870 authored by Jinsuk Kim's avatar Jinsuk Kim
Browse files

CEC: Queue up callbacks to handle on final result

While one party calls oneTouchPlay() to initiate the action and
put it in progress, the other parties making the same call gets
an error 'operation in progress'. This is not really an error,
but there was no other choice for them but just to wait till
the action is completed and the service is ready to accept
the API call again.

This CL resolves the inconvenice by allowing multiple callbacks
rather than returning IN_PROGRESS for those joining later. Same
was applied to queryDisplayStatus().

Change-Id: I5fc9aba4aa73e76a25f8fdec37e11cd961a3d35f
(cherry picked from commit 98a25f1ee27c1b4362a23981edc17fc92199a876)
parent c854c95b
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -14491,7 +14491,7 @@ package android.hardware.hdmi {
    field public static final int POWER_STATUS_TRANSIENT_TO_ON = 2; // 0x2
    field public static final int POWER_STATUS_TRANSIENT_TO_STANDBY = 3; // 0x3
    field public static final int POWER_STATUS_UNKNOWN = -1; // 0xffffffff
    field public static final int RESULT_ALREADY_IN_PROGRESS = 4; // 0x4
    field public static final deprecated int RESULT_ALREADY_IN_PROGRESS = 4; // 0x4
    field public static final int RESULT_COMMUNICATION_FAILED = 7; // 0x7
    field public static final int RESULT_EXCEPTION = 5; // 0x5
    field public static final int RESULT_INCORRECT_MODE = 6; // 0x6
+2 −1
Original line number Diff line number Diff line
@@ -93,7 +93,8 @@ public final class HdmiControlManager {
    public static final int RESULT_TIMEOUT = 1;
    public static final int RESULT_SOURCE_NOT_AVAILABLE = 2;
    public static final int RESULT_TARGET_NOT_AVAILABLE = 3;
    public static final int RESULT_ALREADY_IN_PROGRESS = 4;

    @Deprecated public static final int RESULT_ALREADY_IN_PROGRESS = 4;
    public static final int RESULT_EXCEPTION = 5;
    public static final int RESULT_INCORRECT_MODE = 6;
    public static final int RESULT_COMMUNICATION_FAILED = 7;
+12 −3
Original line number Diff line number Diff line
@@ -23,6 +23,9 @@ import android.hardware.hdmi.IHdmiControlCallback;
import android.os.RemoteException;
import android.util.Slog;

import java.util.ArrayList;
import java.util.List;

/**
 * Feature action that queries the power status of other device. This action is initiated via
 * {@link HdmiPlaybackClient#queryDisplayStatus(DisplayStatusCallback)} from the Android system
@@ -37,7 +40,7 @@ final class DevicePowerStatusAction extends HdmiCecFeatureAction {
    private static final int STATE_WAITING_FOR_REPORT_POWER_STATUS = 1;

    private final int mTargetAddress;
    private final IHdmiControlCallback mCallback;
    private final List<IHdmiControlCallback> mCallbacks = new ArrayList<>();

    static DevicePowerStatusAction create(HdmiCecLocalDevice source,
            int targetAddress, IHdmiControlCallback callback) {
@@ -52,7 +55,7 @@ final class DevicePowerStatusAction extends HdmiCecFeatureAction {
            int targetAddress, IHdmiControlCallback callback) {
        super(localDevice);
        mTargetAddress = targetAddress;
        mCallback = callback;
        addCallback(callback);
    }

    @Override
@@ -95,9 +98,15 @@ final class DevicePowerStatusAction extends HdmiCecFeatureAction {
        }
    }

    public void addCallback(IHdmiControlCallback callback) {
        mCallbacks.add(callback);
    }

    private void invokeCallback(int result) {
        try {
            mCallback.onComplete(result);
            for (IHdmiControlCallback callback : mCallbacks) {
                callback.onComplete(result);
            }
        } catch (RemoteException e) {
            Slog.e(TAG, "Callback failed:" + e);
        }
+12 −11
Original line number Diff line number Diff line
@@ -35,6 +35,8 @@ import java.io.UnsupportedEncodingException;
import java.util.List;
import java.util.Locale;

import java.util.List;

/**
 * Represent a logical device of type Playback residing in Android system.
 */
@@ -97,14 +99,12 @@ final class HdmiCecLocalDevicePlayback extends HdmiCecLocalDevice {
    @ServiceThreadOnly
    void oneTouchPlay(IHdmiControlCallback callback) {
        assertRunOnServiceThread();
        if (hasAction(OneTouchPlayAction.class)) {
            Slog.w(TAG, "oneTouchPlay already in progress");
            invokeCallback(callback, HdmiControlManager.RESULT_ALREADY_IN_PROGRESS);
        List<OneTouchPlayAction> actions = getActions(OneTouchPlayAction.class);
        if (!actions.isEmpty()) {
            Slog.i(TAG, "oneTouchPlay already in progress");
            actions.get(0).addCallback(callback);
            return;
        }

        // TODO: Consider the case of multiple TV sets. For now we always direct the command
        //       to the primary one.
        OneTouchPlayAction action = OneTouchPlayAction.create(this, Constants.ADDR_TV,
                callback);
        if (action == null) {
@@ -118,13 +118,14 @@ final class HdmiCecLocalDevicePlayback extends HdmiCecLocalDevice {
    @ServiceThreadOnly
    void queryDisplayStatus(IHdmiControlCallback callback) {
        assertRunOnServiceThread();
        if (hasAction(DevicePowerStatusAction.class)) {
            Slog.w(TAG, "queryDisplayStatus already in progress");
            invokeCallback(callback, HdmiControlManager.RESULT_ALREADY_IN_PROGRESS);
        List<DevicePowerStatusAction> actions = getActions(DevicePowerStatusAction.class);
        if (!actions.isEmpty()) {
            Slog.i(TAG, "queryDisplayStatus already in progress");
            actions.get(0).addCallback(callback);
            return;
        }
        DevicePowerStatusAction action = DevicePowerStatusAction.create(this,
                Constants.ADDR_TV, callback);
        DevicePowerStatusAction action = DevicePowerStatusAction.create(this, Constants.ADDR_TV,
                callback);
        if (action == null) {
            Slog.w(TAG, "Cannot initiate queryDisplayStatus");
            invokeCallback(callback, HdmiControlManager.RESULT_EXCEPTION);
+12 −3
Original line number Diff line number Diff line
@@ -21,6 +21,9 @@ import android.hardware.hdmi.HdmiPlaybackClient.OneTouchPlayCallback;
import android.os.RemoteException;
import android.util.Slog;

import java.util.ArrayList;
import java.util.List;

/**
 * Feature action that performs one touch play against TV/Display device. This action is initiated
 * via {@link android.hardware.hdmi.HdmiPlaybackClient#oneTouchPlay(OneTouchPlayCallback)} from the
@@ -47,7 +50,7 @@ final class OneTouchPlayAction extends HdmiCecFeatureAction {
    private static final int LOOP_COUNTER_MAX = 10;

    private final int mTargetAddress;
    private final IHdmiControlCallback mCallback;
    private final List<IHdmiControlCallback> mCallbacks = new ArrayList<>();

    private int mPowerStatusCounter = 0;

@@ -66,7 +69,7 @@ final class OneTouchPlayAction extends HdmiCecFeatureAction {
            IHdmiControlCallback callback) {
        super(localDevice);
        mTargetAddress = targetAddress;
        mCallback = callback;
        addCallback(callback);
    }

    @Override
@@ -125,9 +128,15 @@ final class OneTouchPlayAction extends HdmiCecFeatureAction {
        }
    }

    public void addCallback(IHdmiControlCallback callback) {
        mCallbacks.add(callback);
    }

    private void invokeCallback(int result) {
        try {
            mCallback.onComplete(result);
            for (IHdmiControlCallback callback : mCallbacks) {
                callback.onComplete(result);
            }
        } catch (RemoteException e) {
            Slog.e(TAG, "Callback failed:" + e);
        }