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

Commit 3aa71cf8 authored by Marvin Ramin's avatar Marvin Ramin
Browse files

Add active source state changes to dumpsys

Keep a list of the last 10 changes to the internal active source state.
Also tracks whether the local device considers itself to be the active source and the caller of the active source change.

Bug: 164340069
Test: dumpsys hdmi_control
Change-Id: I1f2f52b644a093b0d3884aeebdc6436e4d50759d
parent ac0b4868
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -51,7 +51,7 @@ public class ActiveSourceAction extends HdmiCecFeatureAction {
                            Constants.MENU_STATE_ACTIVATED));
        }

        source().setActiveSource(logicalAddress, physicalAddress);
        source().setActiveSource(logicalAddress, physicalAddress, "ActiveSourceAction");
        mState = STATE_FINISHED;
        finish();
        return true;
+4 −4
Original line number Diff line number Diff line
@@ -17,9 +17,9 @@
package com.android.server.hdmi;

import android.annotation.Nullable;
import android.hardware.hdmi.IHdmiControlCallback;
import android.hardware.hdmi.HdmiDeviceInfo;
import android.hardware.hdmi.HdmiControlManager;
import android.hardware.hdmi.HdmiDeviceInfo;
import android.hardware.hdmi.IHdmiControlCallback;
import android.os.RemoteException;
import android.util.Slog;

@@ -69,7 +69,7 @@ final class ActiveSourceHandler {

        if (!tv.isProhibitMode()) {
            ActiveSource old = ActiveSource.of(tv.getActiveSource());
            tv.updateActiveSource(newActive);
            tv.updateActiveSource(newActive, "ActiveSourceHandler");
            boolean notifyInputChange = (mCallback == null);
            if (!old.equals(newActive)) {
                tv.setPrevPortId(tv.getActivePortId());
@@ -85,7 +85,7 @@ final class ActiveSourceHandler {
                HdmiCecMessage activeSourceCommand = HdmiCecMessageBuilder.buildActiveSource(
                        current.logicalAddress, current.physicalAddress);
                mService.sendCecCommand(activeSourceCommand);
                tv.updateActiveSource(current);
                tv.updateActiveSource(current, "ActiveSourceHandler");
                invokeCallback(HdmiControlManager.RESULT_SUCCESS);
            } else {
                tv.startRoutingControl(newActive.physicalAddress, current.physicalAddress, true,
+10 −2
Original line number Diff line number Diff line
@@ -688,16 +688,24 @@ final class HdmiCecController {
    }

    void dump(final IndentingPrintWriter pw) {
        final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

        for (int i = 0; i < mLocalDevices.size(); ++i) {
            pw.println("HdmiCecLocalDevice #" + mLocalDevices.keyAt(i) + ":");
            pw.increaseIndent();
            mLocalDevices.valueAt(i).dump(pw);

            pw.println("Active Source history:");
            pw.increaseIndent();
            for (Dumpable activeSourceEvent : mLocalDevices.valueAt(i).getActiveSourceHistory()) {
                activeSourceEvent.dump(pw, sdf);
            }
            pw.decreaseIndent();
            pw.decreaseIndent();
        }

        pw.println("CEC message history:");
        pw.increaseIndent();
        final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        for (Dumpable record : mMessageHistory) {
            record.dump(pw, sdf);
        }
@@ -917,7 +925,7 @@ final class HdmiCecController {
        }
    }

    private abstract static class Dumpable {
    public abstract static class Dumpable {
        protected final long mTime;

        Dumpable() {
+53 −6
Original line number Diff line number Diff line
@@ -38,10 +38,13 @@ import com.android.server.hdmi.Constants.LocalActivePort;
import com.android.server.hdmi.HdmiAnnotations.ServiceThreadOnly;
import com.android.server.hdmi.HdmiControlService.SendMessageCallback;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.ArrayBlockingQueue;

/**
 * Class that models a logical CEC device hosted in this system. Handles initialization, CEC
@@ -50,6 +53,7 @@ import java.util.List;
abstract class HdmiCecLocalDevice {
    private static final String TAG = "HdmiCecLocalDevice";

    private static final int MAX_HDMI_ACTIVE_SOURCE_HISTORY = 10;
    private static final int MSG_DISABLE_DEVICE_TIMEOUT = 1;
    private static final int MSG_USER_CONTROL_RELEASE_TIMEOUT = 2;
    // Timeout in millisecond for device clean up (5s).
@@ -68,6 +72,10 @@ abstract class HdmiCecLocalDevice {
    protected int mLastKeycode = HdmiCecKeycode.UNSUPPORTED_KEYCODE;
    protected int mLastKeyRepeatCount = 0;

    // Stores recent changes to the active source in the CEC network.
    private final ArrayBlockingQueue<HdmiCecController.Dumpable> mActiveSourceHistory =
            new ArrayBlockingQueue<>(MAX_HDMI_ACTIVE_SOURCE_HISTORY);

    static class ActiveSource {
        int logicalAddress;
        int physicalAddress;
@@ -893,16 +901,16 @@ abstract class HdmiCecLocalDevice {
        return mService.getLocalActiveSource();
    }

    void setActiveSource(ActiveSource newActive) {
        setActiveSource(newActive.logicalAddress, newActive.physicalAddress);
    void setActiveSource(ActiveSource newActive, String caller) {
        setActiveSource(newActive.logicalAddress, newActive.physicalAddress, caller);
    }

    void setActiveSource(HdmiDeviceInfo info) {
        setActiveSource(info.getLogicalAddress(), info.getPhysicalAddress());
    void setActiveSource(HdmiDeviceInfo info, String caller) {
        setActiveSource(info.getLogicalAddress(), info.getPhysicalAddress(), caller);
    }

    void setActiveSource(int logicalAddress, int physicalAddress) {
        mService.setActiveSource(logicalAddress, physicalAddress);
    void setActiveSource(int logicalAddress, int physicalAddress, String caller) {
        mService.setActiveSource(logicalAddress, physicalAddress, caller);
        mService.setLastInputForMhl(Constants.INVALID_PORT_ID);
    }

@@ -1120,6 +1128,20 @@ abstract class HdmiCecLocalDevice {
                HdmiCecMessageBuilder.buildUserControlReleased(mAddress, targetAddress));
    }

    void addActiveSourceHistoryItem(ActiveSource activeSource, boolean isActiveSource,
            String caller) {
        ActiveSourceHistoryRecord record = new ActiveSourceHistoryRecord(activeSource,
                isActiveSource, caller);
        if (!mActiveSourceHistory.offer(record)) {
            mActiveSourceHistory.poll();
            mActiveSourceHistory.offer(record);
        }
    }

    public ArrayBlockingQueue<HdmiCecController.Dumpable> getActiveSourceHistory() {
        return this.mActiveSourceHistory;
    }

    /** Dump internal status of HdmiCecLocalDevice object. */
    protected void dump(final IndentingPrintWriter pw) {
        pw.println("mDeviceType: " + mDeviceType);
@@ -1152,4 +1174,29 @@ abstract class HdmiCecLocalDevice {
        }
        return finalMask | myPhysicalAddress;
    }

    private static final class ActiveSourceHistoryRecord extends HdmiCecController.Dumpable {
        private final ActiveSource mActiveSource;
        private final boolean mIsActiveSource;
        private final String mCaller;

        private ActiveSourceHistoryRecord(ActiveSource mActiveSource, boolean mIsActiveSource,
                String caller) {
            this.mActiveSource = mActiveSource;
            this.mIsActiveSource = mIsActiveSource;
            this.mCaller = caller;
        }

        @Override
        void dump(final IndentingPrintWriter pw, SimpleDateFormat sdf) {
            pw.print("time=");
            pw.print(sdf.format(new Date(mTime)));
            pw.print(" active source=");
            pw.print(mActiveSource);
            pw.print(" isActiveSource=");
            pw.print(mIsActiveSource);
            pw.print(" from=");
            pw.println(mCaller);
        }
    }
}
+2 −1
Original line number Diff line number Diff line
@@ -361,7 +361,8 @@ public class HdmiCecLocalDeviceAudioSystem extends HdmiCecLocalDeviceSource {
        assertRunOnServiceThread();
        // Invalidate the internal active source record when goes to standby
        // This set will also update mIsActiveSource
        mService.setActiveSource(Constants.ADDR_INVALID, Constants.INVALID_PHYSICAL_ADDRESS);
        mService.setActiveSource(Constants.ADDR_INVALID, Constants.INVALID_PHYSICAL_ADDRESS,
                "HdmiCecLocalDeviceAudioSystem#onStandby()");
        mTvSystemAudioModeSupport = null;
        // Record the last state of System Audio Control before going to standby
        synchronized (mLock) {
Loading