1c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim/*
2c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim * Copyright (C) 2014 The Android Open Source Project
3c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim *
4c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim * Licensed under the Apache License, Version 2.0 (the "License");
5c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim * you may not use this file except in compliance with the License.
6c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim * You may obtain a copy of the License at
7c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim *
8c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim *      http://www.apache.org/licenses/LICENSE-2.0
9c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim *
10c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim * Unless required by applicable law or agreed to in writing, software
11c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim * distributed under the License is distributed on an "AS IS" BASIS,
12c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim * See the License for the specific language governing permissions and
14c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim * limitations under the License.
15c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim */
16c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kimpackage com.android.server.hdmi;
17c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim
1861f4fbd2e8436a1ecd478c2a1f516d064a24d43bJungshik Jangimport android.hardware.hdmi.HdmiDeviceInfo;
19c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kimimport android.util.Slog;
20c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim
2172b7d738d5b9254594726304cdb1777b54d95631Jinsuk Kimimport com.android.server.hdmi.HdmiCecLocalDevice.ActiveSource;
22c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kimimport java.io.UnsupportedEncodingException;
23c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim
24c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim/**
25c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim * Feature action that discovers the information of a newly found logical device.
26c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim *
27c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim * This action is created when receiving <Report Physical Address>, a CEC command a newly
28c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim * connected HDMI-CEC device broadcasts to announce its advent. Additional commands are issued in
29c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim * this action to gather more information on the device such as OSD name and device vendor ID.
30c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim *
3161f4fbd2e8436a1ecd478c2a1f516d064a24d43bJungshik Jang * <p>The result is made in the form of {@link HdmiDeviceInfo} object, and passed to service
32c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim * for the management through its life cycle.
33c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim *
34c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim * <p>Package-private, accessed by {@link HdmiControlService} only.
35c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim */
36b509c2ecd99619248b7a07fb0fa978bb27f25cc3Jungshik Jangfinal class NewDeviceAction extends HdmiCecFeatureAction {
37c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim
38c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim    private static final String TAG = "NewDeviceAction";
39c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim
40c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim    // State in which the action sent <Give OSD Name> and is waiting for <Set OSD Name>
41c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim    // that contains the name of the device for display on screen.
42c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim    static final int STATE_WAITING_FOR_SET_OSD_NAME = 1;
43c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim
44c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim    // State in which the action sent <Give Device Vendor ID> and is waiting for
45c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim    // <Device Vendor ID> that contains the vendor ID of the device.
46c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim    static final int STATE_WAITING_FOR_DEVICE_VENDOR_ID = 2;
47c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim
48c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim    private final int mDeviceLogicalAddress;
49c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim    private final int mDevicePhysicalAddress;
50bdf27fbf746bee11430c4db2ea6dfd026bae77feJinsuk Kim    private final int mDeviceType;
51c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim
52c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim    private int mVendorId;
53c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim    private String mDisplayName;
5446350382ee1974fd635d43c7273dc44854edf7c7Yuncheol Heo    private int mTimeoutRetry;
55c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim
56c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim    /**
57c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim     * Constructor.
58c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim     *
5979c58a4b97f27ede6a1b680d2fece9c2a0edf7b7Jungshik Jang     * @param source {@link HdmiCecLocalDevice} instance
60c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim     * @param deviceLogicalAddress logical address of the device in interest
61c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim     * @param devicePhysicalAddress physical address of the device in interest
62bdf27fbf746bee11430c4db2ea6dfd026bae77feJinsuk Kim     * @param deviceType type of the device
63c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim     */
6479c58a4b97f27ede6a1b680d2fece9c2a0edf7b7Jungshik Jang    NewDeviceAction(HdmiCecLocalDevice source, int deviceLogicalAddress,
65bdf27fbf746bee11430c4db2ea6dfd026bae77feJinsuk Kim            int devicePhysicalAddress, int deviceType) {
6679c58a4b97f27ede6a1b680d2fece9c2a0edf7b7Jungshik Jang        super(source);
67c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim        mDeviceLogicalAddress = deviceLogicalAddress;
68c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim        mDevicePhysicalAddress = devicePhysicalAddress;
69bdf27fbf746bee11430c4db2ea6dfd026bae77feJinsuk Kim        mDeviceType = deviceType;
70c0c20d0522d7756d80f011e7a54bf3b51c78df41Jinsuk Kim        mVendorId = Constants.UNKNOWN_VENDOR_ID;
71c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim    }
72c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim
73c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim    @Override
74c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim    public boolean start() {
7546350382ee1974fd635d43c7273dc44854edf7c7Yuncheol Heo        requestOsdName(true);
7646350382ee1974fd635d43c7273dc44854edf7c7Yuncheol Heo        return true;
7746350382ee1974fd635d43c7273dc44854edf7c7Yuncheol Heo    }
7846350382ee1974fd635d43c7273dc44854edf7c7Yuncheol Heo
7946350382ee1974fd635d43c7273dc44854edf7c7Yuncheol Heo    private void requestOsdName(boolean firstTry) {
8046350382ee1974fd635d43c7273dc44854edf7c7Yuncheol Heo        if (firstTry) {
8146350382ee1974fd635d43c7273dc44854edf7c7Yuncheol Heo            mTimeoutRetry = 0;
8246350382ee1974fd635d43c7273dc44854edf7c7Yuncheol Heo        }
83c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim        mState = STATE_WAITING_FOR_SET_OSD_NAME;
84c0c20d0522d7756d80f011e7a54bf3b51c78df41Jinsuk Kim        if (mayProcessCommandIfCached(mDeviceLogicalAddress, Constants.MESSAGE_SET_OSD_NAME)) {
8546350382ee1974fd635d43c7273dc44854edf7c7Yuncheol Heo            return;
86a466929979a92a578d4ba00093fefa57cfb982b4Jungshik Jang        }
87a466929979a92a578d4ba00093fefa57cfb982b4Jungshik Jang
8879c58a4b97f27ede6a1b680d2fece9c2a0edf7b7Jungshik Jang        sendCommand(HdmiCecMessageBuilder.buildGiveOsdNameCommand(getSourceAddress(),
89a466929979a92a578d4ba00093fefa57cfb982b4Jungshik Jang                mDeviceLogicalAddress));
905fba96df30b6b50b3cb9fe1d783320b1cc3bd6eaJinsuk Kim        addTimer(mState, HdmiConfig.TIMEOUT_MS);
91c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim    }
92c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim
93c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim    @Override
94c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim    public boolean processCommand(HdmiCecMessage cmd) {
95c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim        // For the logical device in interest, we want two more pieces of information -
96c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim        // osd name and vendor id. They are requested in sequence. In case we don't
97c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim        // get the expected responses (either by timeout or by receiving <feature abort> command),
98c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim        // set them to a default osd name and unknown vendor id respectively.
99c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim        int opcode = cmd.getOpcode();
100c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim        int src = cmd.getSource();
101c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim        byte[] params = cmd.getParams();
102c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim
103c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim        if (mDeviceLogicalAddress != src) {
104c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim            return false;
105c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim        }
106c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim
107c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim        if (mState == STATE_WAITING_FOR_SET_OSD_NAME) {
108c0c20d0522d7756d80f011e7a54bf3b51c78df41Jinsuk Kim            if (opcode == Constants.MESSAGE_SET_OSD_NAME) {
109c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim                try {
110c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim                    mDisplayName = new String(params, "US-ASCII");
111c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim                } catch (UnsupportedEncodingException e) {
112c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim                    Slog.e(TAG, "Failed to get OSD name: " + e.getMessage());
113c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim                }
11446350382ee1974fd635d43c7273dc44854edf7c7Yuncheol Heo                requestVendorId(true);
115c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim                return true;
116c0c20d0522d7756d80f011e7a54bf3b51c78df41Jinsuk Kim            } else if (opcode == Constants.MESSAGE_FEATURE_ABORT) {
117339227da7cf025ce4ae0c85ddc52643d63972321Jungshik Jang                int requestOpcode = params[0] & 0xFF;
118339227da7cf025ce4ae0c85ddc52643d63972321Jungshik Jang                if (requestOpcode == Constants.MESSAGE_GIVE_OSD_NAME) {
11946350382ee1974fd635d43c7273dc44854edf7c7Yuncheol Heo                    requestVendorId(true);
120c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim                    return true;
121c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim                }
122c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim            }
123c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim        } else if (mState == STATE_WAITING_FOR_DEVICE_VENDOR_ID) {
124c0c20d0522d7756d80f011e7a54bf3b51c78df41Jinsuk Kim            if (opcode == Constants.MESSAGE_DEVICE_VENDOR_ID) {
12575a77e7d6cbfc287c6126efd28b338b48b7ea70cYuncheol Heo                mVendorId = HdmiUtils.threeBytesToInt(params);
126c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim                addDeviceInfo();
127c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim                finish();
128c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim                return true;
129c0c20d0522d7756d80f011e7a54bf3b51c78df41Jinsuk Kim            } else if (opcode == Constants.MESSAGE_FEATURE_ABORT) {
130339227da7cf025ce4ae0c85ddc52643d63972321Jungshik Jang                int requestOpcode = params[0] & 0xFF;
131339227da7cf025ce4ae0c85ddc52643d63972321Jungshik Jang                if (requestOpcode == Constants.MESSAGE_GIVE_DEVICE_VENDOR_ID) {
132c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim                    addDeviceInfo();
133c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim                    finish();
134c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim                    return true;
135c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim                }
136c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim            }
137c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim        }
138c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim        return false;
139c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim    }
140c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim
141a466929979a92a578d4ba00093fefa57cfb982b4Jungshik Jang    private boolean mayProcessCommandIfCached(int destAddress, int opcode) {
14279c58a4b97f27ede6a1b680d2fece9c2a0edf7b7Jungshik Jang        HdmiCecMessage message = getCecMessageCache().getMessage(destAddress, opcode);
143a466929979a92a578d4ba00093fefa57cfb982b4Jungshik Jang        if (message != null) {
144a466929979a92a578d4ba00093fefa57cfb982b4Jungshik Jang            return processCommand(message);
145a466929979a92a578d4ba00093fefa57cfb982b4Jungshik Jang        }
146a466929979a92a578d4ba00093fefa57cfb982b4Jungshik Jang        return false;
147a466929979a92a578d4ba00093fefa57cfb982b4Jungshik Jang    }
148a466929979a92a578d4ba00093fefa57cfb982b4Jungshik Jang
14946350382ee1974fd635d43c7273dc44854edf7c7Yuncheol Heo    private void requestVendorId(boolean firstTry) {
15046350382ee1974fd635d43c7273dc44854edf7c7Yuncheol Heo        if (firstTry) {
15146350382ee1974fd635d43c7273dc44854edf7c7Yuncheol Heo            mTimeoutRetry = 0;
15246350382ee1974fd635d43c7273dc44854edf7c7Yuncheol Heo        }
153a466929979a92a578d4ba00093fefa57cfb982b4Jungshik Jang        // At first, transit to waiting status for <Device Vendor Id>.
154a466929979a92a578d4ba00093fefa57cfb982b4Jungshik Jang        mState = STATE_WAITING_FOR_DEVICE_VENDOR_ID;
155a466929979a92a578d4ba00093fefa57cfb982b4Jungshik Jang        // If the message is already in cache, process it.
156c0c20d0522d7756d80f011e7a54bf3b51c78df41Jinsuk Kim        if (mayProcessCommandIfCached(mDeviceLogicalAddress,
157c0c20d0522d7756d80f011e7a54bf3b51c78df41Jinsuk Kim                Constants.MESSAGE_DEVICE_VENDOR_ID)) {
158a466929979a92a578d4ba00093fefa57cfb982b4Jungshik Jang            return;
159a466929979a92a578d4ba00093fefa57cfb982b4Jungshik Jang        }
16079c58a4b97f27ede6a1b680d2fece9c2a0edf7b7Jungshik Jang        sendCommand(HdmiCecMessageBuilder.buildGiveDeviceVendorIdCommand(getSourceAddress(),
161a1fa91fe263c483cf13066e2847a440de2cd52a5Jungshik Jang                mDeviceLogicalAddress));
1625fba96df30b6b50b3cb9fe1d783320b1cc3bd6eaJinsuk Kim        addTimer(mState, HdmiConfig.TIMEOUT_MS);
163c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim    }
164c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim
165c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim    private void addDeviceInfo() {
1667cd4a589af7cc6e6880799e86ef6febca5add46dJinsuk Kim        // The device should be in the device list with default information.
1677cd4a589af7cc6e6880799e86ef6febca5add46dJinsuk Kim        if (!tv().isInDeviceList(mDeviceLogicalAddress, mDevicePhysicalAddress)) {
1687cd4a589af7cc6e6880799e86ef6febca5add46dJinsuk Kim            Slog.w(TAG, String.format("Device not found (%02x, %04x)",
1697cd4a589af7cc6e6880799e86ef6febca5add46dJinsuk Kim                    mDeviceLogicalAddress, mDevicePhysicalAddress));
1707cd4a589af7cc6e6880799e86ef6febca5add46dJinsuk Kim            return;
1717cd4a589af7cc6e6880799e86ef6febca5add46dJinsuk Kim        }
172c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim        if (mDisplayName == null) {
173c0c20d0522d7756d80f011e7a54bf3b51c78df41Jinsuk Kim            mDisplayName = HdmiUtils.getDefaultDeviceName(mDeviceLogicalAddress);
174c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim        }
175339227da7cf025ce4ae0c85ddc52643d63972321Jungshik Jang        HdmiDeviceInfo deviceInfo = new HdmiDeviceInfo(
176c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim                mDeviceLogicalAddress, mDevicePhysicalAddress,
1772b152015ff94f20b9ec3ef284fb83105f8b3c831Jinsuk Kim                tv().getPortId(mDevicePhysicalAddress),
178bdf27fbf746bee11430c4db2ea6dfd026bae77feJinsuk Kim                mDeviceType, mVendorId, mDisplayName);
179339227da7cf025ce4ae0c85ddc52643d63972321Jungshik Jang        tv().addCecDevice(deviceInfo);
18097affee67b6d88da40af41b36f02ecb2b823daffJungshik Jang
1817fa3a66470d2133796defd14a0600578758882acJinsuk Kim        // Consume CEC messages we already got for this newly found device.
1827fa3a66470d2133796defd14a0600578758882acJinsuk Kim        tv().processDelayedMessages(mDeviceLogicalAddress);
1837fa3a66470d2133796defd14a0600578758882acJinsuk Kim
18497affee67b6d88da40af41b36f02ecb2b823daffJungshik Jang        if (HdmiUtils.getTypeFromAddress(mDeviceLogicalAddress)
18561f4fbd2e8436a1ecd478c2a1f516d064a24d43bJungshik Jang                == HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM) {
186339227da7cf025ce4ae0c85ddc52643d63972321Jungshik Jang            tv().onNewAvrAdded(deviceInfo);
18797affee67b6d88da40af41b36f02ecb2b823daffJungshik Jang        }
18897affee67b6d88da40af41b36f02ecb2b823daffJungshik Jang    }
18997affee67b6d88da40af41b36f02ecb2b823daffJungshik Jang
190c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim    @Override
191c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim    public void handleTimerEvent(int state) {
192c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim        if (mState == STATE_NONE || mState != state) {
193c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim            return;
194c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim        }
195c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim        if (state == STATE_WAITING_FOR_SET_OSD_NAME) {
19646350382ee1974fd635d43c7273dc44854edf7c7Yuncheol Heo            if (++mTimeoutRetry < HdmiConfig.TIMEOUT_RETRY) {
19746350382ee1974fd635d43c7273dc44854edf7c7Yuncheol Heo                requestOsdName(false);
19846350382ee1974fd635d43c7273dc44854edf7c7Yuncheol Heo                return;
19946350382ee1974fd635d43c7273dc44854edf7c7Yuncheol Heo            }
200c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim            // Osd name request timed out. Try vendor id
20146350382ee1974fd635d43c7273dc44854edf7c7Yuncheol Heo            requestVendorId(true);
202c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim        } else if (state == STATE_WAITING_FOR_DEVICE_VENDOR_ID) {
20346350382ee1974fd635d43c7273dc44854edf7c7Yuncheol Heo            if (++mTimeoutRetry < HdmiConfig.TIMEOUT_RETRY) {
20446350382ee1974fd635d43c7273dc44854edf7c7Yuncheol Heo                requestVendorId(false);
20546350382ee1974fd635d43c7273dc44854edf7c7Yuncheol Heo                return;
20646350382ee1974fd635d43c7273dc44854edf7c7Yuncheol Heo            }
207c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim            // vendor id timed out. Go ahead creating the device info what we've got so far.
208c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim            addDeviceInfo();
209c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim            finish();
210c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim        }
211c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim    }
21297affee67b6d88da40af41b36f02ecb2b823daffJungshik Jang
21372b7d738d5b9254594726304cdb1777b54d95631Jinsuk Kim    boolean isActionOf(ActiveSource activeSource) {
21472b7d738d5b9254594726304cdb1777b54d95631Jinsuk Kim        return (mDeviceLogicalAddress == activeSource.logicalAddress)
21572b7d738d5b9254594726304cdb1777b54d95631Jinsuk Kim                && (mDevicePhysicalAddress == activeSource.physicalAddress);
21697affee67b6d88da40af41b36f02ecb2b823daffJungshik Jang    }
217c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim}
218