HdmiCecFeatureAction.java revision 79c58a4b97f27ede6a1b680d2fece9c2a0edf7b7
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
18c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kimimport android.hardware.hdmi.HdmiCecMessage;
19c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kimimport android.os.Handler;
20c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kimimport android.os.Looper;
21c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kimimport android.os.Message;
22c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kimimport android.util.Slog;
23c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim
24c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kimimport com.android.internal.annotations.VisibleForTesting;
2579c58a4b97f27ede6a1b680d2fece9c2a0edf7b7Jungshik Jangimport com.android.server.hdmi.HdmiControlService.DevicePollingCallback;
2679c58a4b97f27ede6a1b680d2fece9c2a0edf7b7Jungshik Jang
2779c58a4b97f27ede6a1b680d2fece9c2a0edf7b7Jungshik Jangimport java.util.List;
28c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim
29c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim/**
30c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim * Encapsulates a sequence of CEC/MHL command exchange for a certain feature.
31c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim *
32c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim * <p>Many CEC/MHL features are accomplished by CEC devices on the bus exchanging
33c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim * more than one command. {@link FeatureAction} represents the life cycle of the communication,
34c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim * manages the state as the process progresses, and if necessary, returns the result
35c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim * to the caller which initiates the action, through the callback given at the creation
36c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim * of the object. All the actual action classes inherit FeatureAction.
37c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim *
38c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim * <p>More than one FeatureAction objects can be up and running simultaneously,
3979c58a4b97f27ede6a1b680d2fece9c2a0edf7b7Jungshik Jang * maintained by {@link HdmiCecLocalDevice}. Each action is passed a new command
40c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim * arriving from the bus, and either consumes it if the command is what the action expects,
41c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim * or yields it to other action.
42c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim *
43c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim * Declared as package private, accessed by {@link HdmiControlService} only.
44c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim */
45c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kimabstract class FeatureAction {
46c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim    private static final String TAG = "FeatureAction";
47c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim
48c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim    // Timer handler message used for timeout event
49c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim    protected static final int MSG_TIMEOUT = 100;
50c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim
51a6ce7708d6124224399241503fadcafe0c4684d4Jinsuk Kim    // Default timeout for the incoming command to arrive in response to a request.
52a6ce7708d6124224399241503fadcafe0c4684d4Jinsuk Kim    // TODO: Consider reading this value from configuration to allow customization.
53a6ce7708d6124224399241503fadcafe0c4684d4Jinsuk Kim    protected static final int TIMEOUT_MS = 2000;
54c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim
55c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim    // Default state used in common by all the feature actions.
56c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim    protected static final int STATE_NONE = 0;
57c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim
58c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim    // Internal state indicating the progress of action.
59c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim    protected int mState = STATE_NONE;
60c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim
6179c58a4b97f27ede6a1b680d2fece9c2a0edf7b7Jungshik Jang    private final HdmiControlService mService;
6279c58a4b97f27ede6a1b680d2fece9c2a0edf7b7Jungshik Jang    private final HdmiCecLocalDevice mSource;
63c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim
64c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim    // Timer that manages timeout events.
65c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim    protected ActionTimer mActionTimer;
66c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim
6779c58a4b97f27ede6a1b680d2fece9c2a0edf7b7Jungshik Jang    FeatureAction(HdmiCecLocalDevice source) {
6879c58a4b97f27ede6a1b680d2fece9c2a0edf7b7Jungshik Jang        mSource = source;
6979c58a4b97f27ede6a1b680d2fece9c2a0edf7b7Jungshik Jang        mService = mSource.getService();
7079c58a4b97f27ede6a1b680d2fece9c2a0edf7b7Jungshik Jang        mActionTimer = createActionTimer(mService.getServiceLooper());
71c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim    }
72c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim
73c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim    @VisibleForTesting
74c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim    void setActionTimer(ActionTimer actionTimer) {
75c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim        mActionTimer = actionTimer;
76c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim    }
77c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim
78c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim    /**
79c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim     * Called right after the action is created. Initialization or first step to take
80c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim     * for the action can be done in this method.
81c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim     *
82c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim     * @return true if the operation is successful; otherwise false.
83c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim     */
84c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim    abstract boolean start();
85c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim
86c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim    /**
87c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim     * Process the command. Called whenever a new command arrives.
88c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim     *
89c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim     * @param cmd command to process
90c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim     * @return true if the command was consumed in the process; Otherwise false, which
91c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim     *          indicates that the command shall be handled by other actions.
92c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim     */
93c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim    abstract boolean processCommand(HdmiCecMessage cmd);
94c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim
95c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim    /**
96c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim     * Called when the action should handle the timer event it created before.
97c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim     *
98c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim     * <p>CEC standard mandates each command transmission should be responded within
99c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim     * certain period of time. The method is called when the timer it created as it transmitted
100c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim     * a command gets expired. Inner logic should take an appropriate action.
101c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim     *
102c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim     * @param state the state associated with the time when the timer was created
103c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim     */
104c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim    abstract void handleTimerEvent(int state);
105c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim
106c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim    /**
107c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim     * Timer handler interface used for FeatureAction classes.
108c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim     */
109c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim    interface ActionTimer {
110c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim        /**
111c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim         * Send a timer message.
112c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim         *
113c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim         * Also carries the state of the action when the timer is created. Later this state is
114c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim         * compared to the one the action is in when it receives the timer to let the action tell
115c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim         * the right timer to handle.
116c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim         *
117c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim         * @param state state of the action is in
118c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim         * @param delayMillis amount of delay for the timer
119c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim         */
120c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim        void sendTimerMessage(int state, long delayMillis);
12167ea521d14f366fe5aac09e512865d31bfa0ee53Jungshik Jang
12267ea521d14f366fe5aac09e512865d31bfa0ee53Jungshik Jang        /**
12367ea521d14f366fe5aac09e512865d31bfa0ee53Jungshik Jang         * Removes any pending timer message.
12467ea521d14f366fe5aac09e512865d31bfa0ee53Jungshik Jang         */
12567ea521d14f366fe5aac09e512865d31bfa0ee53Jungshik Jang        void clearTimerMessage();
126c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim    }
127c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim
128c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim    private class ActionTimerHandler extends Handler implements ActionTimer {
129c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim
130c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim        public ActionTimerHandler(Looper looper) {
131c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim            super(looper);
132c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim        }
133c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim
134c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim        @Override
135c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim        public void sendTimerMessage(int state, long delayMillis) {
136b0674f0f7c04b707ca7b11f5700bdb9e51b61872Jinsuk Kim            // The third argument(0) is not used.
137b0674f0f7c04b707ca7b11f5700bdb9e51b61872Jinsuk Kim            sendMessageDelayed(obtainMessage(MSG_TIMEOUT, state, 0), delayMillis);
138c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim        }
139c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim
140c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim        @Override
14167ea521d14f366fe5aac09e512865d31bfa0ee53Jungshik Jang        public void clearTimerMessage() {
14267ea521d14f366fe5aac09e512865d31bfa0ee53Jungshik Jang            removeMessages(MSG_TIMEOUT);
14367ea521d14f366fe5aac09e512865d31bfa0ee53Jungshik Jang        }
14467ea521d14f366fe5aac09e512865d31bfa0ee53Jungshik Jang
14567ea521d14f366fe5aac09e512865d31bfa0ee53Jungshik Jang        @Override
146c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim        public void handleMessage(Message msg) {
147c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim            switch (msg.what) {
148c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim            case MSG_TIMEOUT:
149c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim                handleTimerEvent(msg.arg1);
150c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim                break;
151c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim            default:
152c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim                Slog.w(TAG, "Unsupported message:" + msg.what);
153c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim                break;
154c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim            }
155c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim        }
156c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim    }
157c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim
158c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim    private ActionTimer createActionTimer(Looper looper) {
159c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim        return new ActionTimerHandler(looper);
160c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim    }
161c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim
162c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim    // Add a new timer. The timer event will come to mActionTimer.handleMessage() in
163c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim    // delayMillis.
164c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim    protected void addTimer(int state, int delayMillis) {
165c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim        mActionTimer.sendTimerMessage(state, delayMillis);
166c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim    }
167c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim
168d643f764f72efc1e7aa67392bf9ac40720ae14c3Jungshik Jang    protected final void sendCommand(HdmiCecMessage cmd) {
169d643f764f72efc1e7aa67392bf9ac40720ae14c3Jungshik Jang        mService.sendCecCommand(cmd);
170d643f764f72efc1e7aa67392bf9ac40720ae14c3Jungshik Jang    }
171d643f764f72efc1e7aa67392bf9ac40720ae14c3Jungshik Jang
172d643f764f72efc1e7aa67392bf9ac40720ae14c3Jungshik Jang    protected final void sendCommand(HdmiCecMessage cmd,
173d643f764f72efc1e7aa67392bf9ac40720ae14c3Jungshik Jang            HdmiControlService.SendMessageCallback callback) {
174d643f764f72efc1e7aa67392bf9ac40720ae14c3Jungshik Jang        mService.sendCecCommand(cmd, callback);
17567ea521d14f366fe5aac09e512865d31bfa0ee53Jungshik Jang    }
17667ea521d14f366fe5aac09e512865d31bfa0ee53Jungshik Jang
17779c58a4b97f27ede6a1b680d2fece9c2a0edf7b7Jungshik Jang    protected final void addAndStartAction(FeatureAction action) {
17879c58a4b97f27ede6a1b680d2fece9c2a0edf7b7Jungshik Jang        mSource.addAndStartAction(action);
17979c58a4b97f27ede6a1b680d2fece9c2a0edf7b7Jungshik Jang    }
18079c58a4b97f27ede6a1b680d2fece9c2a0edf7b7Jungshik Jang
18179c58a4b97f27ede6a1b680d2fece9c2a0edf7b7Jungshik Jang    protected final <T extends FeatureAction> List<T> getActions(final Class<T> clazz) {
18279c58a4b97f27ede6a1b680d2fece9c2a0edf7b7Jungshik Jang        return mSource.getActions(clazz);
18379c58a4b97f27ede6a1b680d2fece9c2a0edf7b7Jungshik Jang    }
18479c58a4b97f27ede6a1b680d2fece9c2a0edf7b7Jungshik Jang
18579c58a4b97f27ede6a1b680d2fece9c2a0edf7b7Jungshik Jang    protected final HdmiCecMessageCache getCecMessageCache() {
18679c58a4b97f27ede6a1b680d2fece9c2a0edf7b7Jungshik Jang        return mSource.getCecMessageCache();
18779c58a4b97f27ede6a1b680d2fece9c2a0edf7b7Jungshik Jang    }
18879c58a4b97f27ede6a1b680d2fece9c2a0edf7b7Jungshik Jang
18979c58a4b97f27ede6a1b680d2fece9c2a0edf7b7Jungshik Jang    /**
19079c58a4b97f27ede6a1b680d2fece9c2a0edf7b7Jungshik Jang     * Remove the action from the action queue. This is called after the action finishes
19179c58a4b97f27ede6a1b680d2fece9c2a0edf7b7Jungshik Jang     * its role.
19279c58a4b97f27ede6a1b680d2fece9c2a0edf7b7Jungshik Jang     *
19379c58a4b97f27ede6a1b680d2fece9c2a0edf7b7Jungshik Jang     * @param action
19479c58a4b97f27ede6a1b680d2fece9c2a0edf7b7Jungshik Jang     */
19579c58a4b97f27ede6a1b680d2fece9c2a0edf7b7Jungshik Jang    protected final void removeAction(FeatureAction action) {
19679c58a4b97f27ede6a1b680d2fece9c2a0edf7b7Jungshik Jang        mSource.removeAction(action);
19779c58a4b97f27ede6a1b680d2fece9c2a0edf7b7Jungshik Jang    }
19879c58a4b97f27ede6a1b680d2fece9c2a0edf7b7Jungshik Jang
19979c58a4b97f27ede6a1b680d2fece9c2a0edf7b7Jungshik Jang    protected final <T extends FeatureAction> void removeAction(final Class<T> clazz) {
20079c58a4b97f27ede6a1b680d2fece9c2a0edf7b7Jungshik Jang        mSource.removeActionExcept(clazz, null);
20179c58a4b97f27ede6a1b680d2fece9c2a0edf7b7Jungshik Jang    }
20279c58a4b97f27ede6a1b680d2fece9c2a0edf7b7Jungshik Jang
20379c58a4b97f27ede6a1b680d2fece9c2a0edf7b7Jungshik Jang    protected final <T extends FeatureAction> void removeActionExcept(final Class<T> clazz,
20479c58a4b97f27ede6a1b680d2fece9c2a0edf7b7Jungshik Jang            final FeatureAction exception) {
20579c58a4b97f27ede6a1b680d2fece9c2a0edf7b7Jungshik Jang        mSource.removeActionExcept(clazz, exception);
20679c58a4b97f27ede6a1b680d2fece9c2a0edf7b7Jungshik Jang    }
20779c58a4b97f27ede6a1b680d2fece9c2a0edf7b7Jungshik Jang
20879c58a4b97f27ede6a1b680d2fece9c2a0edf7b7Jungshik Jang    protected final void pollDevices(DevicePollingCallback callback, int pickStrategy,
20979c58a4b97f27ede6a1b680d2fece9c2a0edf7b7Jungshik Jang            int retryCount) {
21079c58a4b97f27ede6a1b680d2fece9c2a0edf7b7Jungshik Jang        mService.pollDevices(callback, pickStrategy, retryCount);
21179c58a4b97f27ede6a1b680d2fece9c2a0edf7b7Jungshik Jang    }
21279c58a4b97f27ede6a1b680d2fece9c2a0edf7b7Jungshik Jang
21367ea521d14f366fe5aac09e512865d31bfa0ee53Jungshik Jang    /**
21467ea521d14f366fe5aac09e512865d31bfa0ee53Jungshik Jang     * Clean up action's state.
21567ea521d14f366fe5aac09e512865d31bfa0ee53Jungshik Jang     *
21667ea521d14f366fe5aac09e512865d31bfa0ee53Jungshik Jang     * <p>Declared as package-private. Only {@link HdmiControlService} can access it.
21767ea521d14f366fe5aac09e512865d31bfa0ee53Jungshik Jang     */
21867ea521d14f366fe5aac09e512865d31bfa0ee53Jungshik Jang    void clear() {
21967ea521d14f366fe5aac09e512865d31bfa0ee53Jungshik Jang        mState = STATE_NONE;
22067ea521d14f366fe5aac09e512865d31bfa0ee53Jungshik Jang        // Clear all timers.
22167ea521d14f366fe5aac09e512865d31bfa0ee53Jungshik Jang        mActionTimer.clearTimerMessage();
222c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim    }
223c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim
224c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim    /**
225c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim     * Finish up the action. Reset the state, and remove itself from the action queue.
226c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim     */
227c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim    protected void finish() {
22867ea521d14f366fe5aac09e512865d31bfa0ee53Jungshik Jang        clear();
229c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim        removeAction(this);
230c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim    }
231c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim
23279c58a4b97f27ede6a1b680d2fece9c2a0edf7b7Jungshik Jang    protected final HdmiCecLocalDevice localDevice() {
23379c58a4b97f27ede6a1b680d2fece9c2a0edf7b7Jungshik Jang        return mSource;
23479c58a4b97f27ede6a1b680d2fece9c2a0edf7b7Jungshik Jang    }
23579c58a4b97f27ede6a1b680d2fece9c2a0edf7b7Jungshik Jang
23679c58a4b97f27ede6a1b680d2fece9c2a0edf7b7Jungshik Jang    protected final HdmiCecLocalDevicePlayback playback() {
23779c58a4b97f27ede6a1b680d2fece9c2a0edf7b7Jungshik Jang        return (HdmiCecLocalDevicePlayback) mSource;
23879c58a4b97f27ede6a1b680d2fece9c2a0edf7b7Jungshik Jang    }
23979c58a4b97f27ede6a1b680d2fece9c2a0edf7b7Jungshik Jang
24079c58a4b97f27ede6a1b680d2fece9c2a0edf7b7Jungshik Jang    protected final HdmiCecLocalDeviceTv tv() {
24179c58a4b97f27ede6a1b680d2fece9c2a0edf7b7Jungshik Jang        return (HdmiCecLocalDeviceTv) mSource;
24279c58a4b97f27ede6a1b680d2fece9c2a0edf7b7Jungshik Jang    }
24379c58a4b97f27ede6a1b680d2fece9c2a0edf7b7Jungshik Jang
24479c58a4b97f27ede6a1b680d2fece9c2a0edf7b7Jungshik Jang    protected final int getSourceAddress() {
24579c58a4b97f27ede6a1b680d2fece9c2a0edf7b7Jungshik Jang        return mSource.getDeviceInfo().getLogicalAddress();
24679c58a4b97f27ede6a1b680d2fece9c2a0edf7b7Jungshik Jang    }
24779c58a4b97f27ede6a1b680d2fece9c2a0edf7b7Jungshik Jang
24879c58a4b97f27ede6a1b680d2fece9c2a0edf7b7Jungshik Jang    protected final int getSourcePath() {
24979c58a4b97f27ede6a1b680d2fece9c2a0edf7b7Jungshik Jang        return mSource.getDeviceInfo().getPhysicalAddress();
250c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim    }
251c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim}
252