HdmiCecFeatureAction.java revision 5352081c662299b618335bf3024058fa04ef2dfd
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.os.Handler; 19c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kimimport android.os.Looper; 20c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kimimport android.os.Message; 21c516d65fd96cdc39f9935ddb80d26ee6499a77bfYuncheol Heoimport android.util.Pair; 22c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kimimport android.util.Slog; 23c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim 24c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kimimport com.android.internal.annotations.VisibleForTesting; 2579c58a4b97f27ede6a1b680d2fece9c2a0edf7b7Jungshik Jangimport com.android.server.hdmi.HdmiControlService.DevicePollingCallback; 2679c58a4b97f27ede6a1b680d2fece9c2a0edf7b7Jungshik Jang 27c516d65fd96cdc39f9935ddb80d26ee6499a77bfYuncheol Heoimport java.util.ArrayList; 2879c58a4b97f27ede6a1b680d2fece9c2a0edf7b7Jungshik Jangimport java.util.List; 29c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim 30c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim/** 317df52862dae1fa33c84725c613b0d9b88c1b28b6Jungshik Jang * Encapsulates a sequence of CEC command exchange for a certain feature. 32b509c2ecd99619248b7a07fb0fa978bb27f25cc3Jungshik Jang * <p> 337df52862dae1fa33c84725c613b0d9b88c1b28b6Jungshik Jang * Many CEC features are accomplished by CEC devices on the bus exchanging more than one 34b509c2ecd99619248b7a07fb0fa978bb27f25cc3Jungshik Jang * command. {@link HdmiCecFeatureAction} represents the life cycle of the communication, manages the 35b509c2ecd99619248b7a07fb0fa978bb27f25cc3Jungshik Jang * state as the process progresses, and if necessary, returns the result to the caller which 36b509c2ecd99619248b7a07fb0fa978bb27f25cc3Jungshik Jang * initiates the action, through the callback given at the creation of the object. All the actual 37b509c2ecd99619248b7a07fb0fa978bb27f25cc3Jungshik Jang * action classes inherit FeatureAction. 38b509c2ecd99619248b7a07fb0fa978bb27f25cc3Jungshik Jang * <p> 39b509c2ecd99619248b7a07fb0fa978bb27f25cc3Jungshik Jang * More than one FeatureAction objects can be up and running simultaneously, maintained by 40b509c2ecd99619248b7a07fb0fa978bb27f25cc3Jungshik Jang * {@link HdmiCecLocalDevice}. Each action is passed a new command arriving from the bus, and either 41b509c2ecd99619248b7a07fb0fa978bb27f25cc3Jungshik Jang * consumes it if the command is what the action expects, or yields it to other action. Declared as 42b509c2ecd99619248b7a07fb0fa978bb27f25cc3Jungshik Jang * package private, accessed by {@link HdmiControlService} only. 43c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim */ 44b509c2ecd99619248b7a07fb0fa978bb27f25cc3Jungshik Jangabstract class HdmiCecFeatureAction { 457df52862dae1fa33c84725c613b0d9b88c1b28b6Jungshik Jang private static final String TAG = "HdmiCecFeatureAction"; 46c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim 47c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim // Timer handler message used for timeout event 48c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim protected static final int MSG_TIMEOUT = 100; 49c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim 50c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim // Default state used in common by all the feature actions. 51c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim protected static final int STATE_NONE = 0; 52c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim 53c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim // Internal state indicating the progress of action. 54c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim protected int mState = STATE_NONE; 55c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim 5679c58a4b97f27ede6a1b680d2fece9c2a0edf7b7Jungshik Jang private final HdmiControlService mService; 5779c58a4b97f27ede6a1b680d2fece9c2a0edf7b7Jungshik Jang private final HdmiCecLocalDevice mSource; 58c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim 59c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim // Timer that manages timeout events. 60c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim protected ActionTimer mActionTimer; 61c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim 62b509c2ecd99619248b7a07fb0fa978bb27f25cc3Jungshik Jang private ArrayList<Pair<HdmiCecFeatureAction, Runnable>> mOnFinishedCallbacks; 63c516d65fd96cdc39f9935ddb80d26ee6499a77bfYuncheol Heo 64b509c2ecd99619248b7a07fb0fa978bb27f25cc3Jungshik Jang HdmiCecFeatureAction(HdmiCecLocalDevice source) { 6579c58a4b97f27ede6a1b680d2fece9c2a0edf7b7Jungshik Jang mSource = source; 6679c58a4b97f27ede6a1b680d2fece9c2a0edf7b7Jungshik Jang mService = mSource.getService(); 6779c58a4b97f27ede6a1b680d2fece9c2a0edf7b7Jungshik Jang mActionTimer = createActionTimer(mService.getServiceLooper()); 68c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim } 69c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim 70c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim @VisibleForTesting 71c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim void setActionTimer(ActionTimer actionTimer) { 72c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim mActionTimer = actionTimer; 73c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim } 74c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim 75c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim /** 76c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim * Called right after the action is created. Initialization or first step to take 77c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim * for the action can be done in this method. 78c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim * 79c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim * @return true if the operation is successful; otherwise false. 80c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim */ 81c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim abstract boolean start(); 82c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim 83c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim /** 84c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim * Process the command. Called whenever a new command arrives. 85c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim * 86c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim * @param cmd command to process 875352081c662299b618335bf3024058fa04ef2dfdJungshik Jang * @return true if the command was consumed in the process; Otherwise false. 88c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim */ 89c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim abstract boolean processCommand(HdmiCecMessage cmd); 90c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim 91c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim /** 92c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim * Called when the action should handle the timer event it created before. 93c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim * 94c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim * <p>CEC standard mandates each command transmission should be responded within 95c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim * certain period of time. The method is called when the timer it created as it transmitted 96c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim * a command gets expired. Inner logic should take an appropriate action. 97c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim * 98c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim * @param state the state associated with the time when the timer was created 99c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim */ 100c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim abstract void handleTimerEvent(int state); 101c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim 102c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim /** 103c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim * Timer handler interface used for FeatureAction classes. 104c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim */ 105c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim interface ActionTimer { 106c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim /** 107c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim * Send a timer message. 108c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim * 109c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim * Also carries the state of the action when the timer is created. Later this state is 110c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim * compared to the one the action is in when it receives the timer to let the action tell 111c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim * the right timer to handle. 112c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim * 113c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim * @param state state of the action is in 114c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim * @param delayMillis amount of delay for the timer 115c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim */ 116c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim void sendTimerMessage(int state, long delayMillis); 11767ea521d14f366fe5aac09e512865d31bfa0ee53Jungshik Jang 11867ea521d14f366fe5aac09e512865d31bfa0ee53Jungshik Jang /** 11967ea521d14f366fe5aac09e512865d31bfa0ee53Jungshik Jang * Removes any pending timer message. 12067ea521d14f366fe5aac09e512865d31bfa0ee53Jungshik Jang */ 12167ea521d14f366fe5aac09e512865d31bfa0ee53Jungshik Jang void clearTimerMessage(); 122c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim } 123c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim 124c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim private class ActionTimerHandler extends Handler implements ActionTimer { 125c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim 126c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim public ActionTimerHandler(Looper looper) { 127c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim super(looper); 128c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim } 129c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim 130c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim @Override 131c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim public void sendTimerMessage(int state, long delayMillis) { 132b0674f0f7c04b707ca7b11f5700bdb9e51b61872Jinsuk Kim // The third argument(0) is not used. 133b0674f0f7c04b707ca7b11f5700bdb9e51b61872Jinsuk Kim sendMessageDelayed(obtainMessage(MSG_TIMEOUT, state, 0), delayMillis); 134c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim } 135c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim 136c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim @Override 13767ea521d14f366fe5aac09e512865d31bfa0ee53Jungshik Jang public void clearTimerMessage() { 13867ea521d14f366fe5aac09e512865d31bfa0ee53Jungshik Jang removeMessages(MSG_TIMEOUT); 13967ea521d14f366fe5aac09e512865d31bfa0ee53Jungshik Jang } 14067ea521d14f366fe5aac09e512865d31bfa0ee53Jungshik Jang 14167ea521d14f366fe5aac09e512865d31bfa0ee53Jungshik Jang @Override 142c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim public void handleMessage(Message msg) { 143c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim switch (msg.what) { 144c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim case MSG_TIMEOUT: 145c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim handleTimerEvent(msg.arg1); 146c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim break; 147c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim default: 148c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim Slog.w(TAG, "Unsupported message:" + msg.what); 149c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim break; 150c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim } 151c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim } 152c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim } 153c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim 154c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim private ActionTimer createActionTimer(Looper looper) { 155c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim return new ActionTimerHandler(looper); 156c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim } 157c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim 158c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim // Add a new timer. The timer event will come to mActionTimer.handleMessage() in 159c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim // delayMillis. 160c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim protected void addTimer(int state, int delayMillis) { 161c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim mActionTimer.sendTimerMessage(state, delayMillis); 162c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim } 163c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim 164d643f764f72efc1e7aa67392bf9ac40720ae14c3Jungshik Jang protected final void sendCommand(HdmiCecMessage cmd) { 165d643f764f72efc1e7aa67392bf9ac40720ae14c3Jungshik Jang mService.sendCecCommand(cmd); 166d643f764f72efc1e7aa67392bf9ac40720ae14c3Jungshik Jang } 167d643f764f72efc1e7aa67392bf9ac40720ae14c3Jungshik Jang 168d643f764f72efc1e7aa67392bf9ac40720ae14c3Jungshik Jang protected final void sendCommand(HdmiCecMessage cmd, 169d643f764f72efc1e7aa67392bf9ac40720ae14c3Jungshik Jang HdmiControlService.SendMessageCallback callback) { 170d643f764f72efc1e7aa67392bf9ac40720ae14c3Jungshik Jang mService.sendCecCommand(cmd, callback); 17167ea521d14f366fe5aac09e512865d31bfa0ee53Jungshik Jang } 17267ea521d14f366fe5aac09e512865d31bfa0ee53Jungshik Jang 173b509c2ecd99619248b7a07fb0fa978bb27f25cc3Jungshik Jang protected final void addAndStartAction(HdmiCecFeatureAction action) { 17479c58a4b97f27ede6a1b680d2fece9c2a0edf7b7Jungshik Jang mSource.addAndStartAction(action); 17579c58a4b97f27ede6a1b680d2fece9c2a0edf7b7Jungshik Jang } 17679c58a4b97f27ede6a1b680d2fece9c2a0edf7b7Jungshik Jang 177b509c2ecd99619248b7a07fb0fa978bb27f25cc3Jungshik Jang protected final <T extends HdmiCecFeatureAction> List<T> getActions(final Class<T> clazz) { 17879c58a4b97f27ede6a1b680d2fece9c2a0edf7b7Jungshik Jang return mSource.getActions(clazz); 17979c58a4b97f27ede6a1b680d2fece9c2a0edf7b7Jungshik Jang } 18079c58a4b97f27ede6a1b680d2fece9c2a0edf7b7Jungshik Jang 18179c58a4b97f27ede6a1b680d2fece9c2a0edf7b7Jungshik Jang protected final HdmiCecMessageCache getCecMessageCache() { 18279c58a4b97f27ede6a1b680d2fece9c2a0edf7b7Jungshik Jang return mSource.getCecMessageCache(); 18379c58a4b97f27ede6a1b680d2fece9c2a0edf7b7Jungshik Jang } 18479c58a4b97f27ede6a1b680d2fece9c2a0edf7b7Jungshik Jang 18579c58a4b97f27ede6a1b680d2fece9c2a0edf7b7Jungshik Jang /** 18679c58a4b97f27ede6a1b680d2fece9c2a0edf7b7Jungshik Jang * Remove the action from the action queue. This is called after the action finishes 18779c58a4b97f27ede6a1b680d2fece9c2a0edf7b7Jungshik Jang * its role. 18879c58a4b97f27ede6a1b680d2fece9c2a0edf7b7Jungshik Jang * 18979c58a4b97f27ede6a1b680d2fece9c2a0edf7b7Jungshik Jang * @param action 19079c58a4b97f27ede6a1b680d2fece9c2a0edf7b7Jungshik Jang */ 191b509c2ecd99619248b7a07fb0fa978bb27f25cc3Jungshik Jang protected final void removeAction(HdmiCecFeatureAction action) { 19279c58a4b97f27ede6a1b680d2fece9c2a0edf7b7Jungshik Jang mSource.removeAction(action); 19379c58a4b97f27ede6a1b680d2fece9c2a0edf7b7Jungshik Jang } 19479c58a4b97f27ede6a1b680d2fece9c2a0edf7b7Jungshik Jang 195b509c2ecd99619248b7a07fb0fa978bb27f25cc3Jungshik Jang protected final <T extends HdmiCecFeatureAction> void removeAction(final Class<T> clazz) { 19679c58a4b97f27ede6a1b680d2fece9c2a0edf7b7Jungshik Jang mSource.removeActionExcept(clazz, null); 19779c58a4b97f27ede6a1b680d2fece9c2a0edf7b7Jungshik Jang } 19879c58a4b97f27ede6a1b680d2fece9c2a0edf7b7Jungshik Jang 199b509c2ecd99619248b7a07fb0fa978bb27f25cc3Jungshik Jang protected final <T extends HdmiCecFeatureAction> void removeActionExcept(final Class<T> clazz, 200b509c2ecd99619248b7a07fb0fa978bb27f25cc3Jungshik Jang final HdmiCecFeatureAction exception) { 20179c58a4b97f27ede6a1b680d2fece9c2a0edf7b7Jungshik Jang mSource.removeActionExcept(clazz, exception); 20279c58a4b97f27ede6a1b680d2fece9c2a0edf7b7Jungshik Jang } 20379c58a4b97f27ede6a1b680d2fece9c2a0edf7b7Jungshik Jang 20479c58a4b97f27ede6a1b680d2fece9c2a0edf7b7Jungshik Jang protected final void pollDevices(DevicePollingCallback callback, int pickStrategy, 20579c58a4b97f27ede6a1b680d2fece9c2a0edf7b7Jungshik Jang int retryCount) { 2061de514256fd3015cf45256f3198ab5472024af9bJungshik Jang mService.pollDevices(callback, getSourceAddress(), pickStrategy, retryCount); 20779c58a4b97f27ede6a1b680d2fece9c2a0edf7b7Jungshik Jang } 20879c58a4b97f27ede6a1b680d2fece9c2a0edf7b7Jungshik Jang 20967ea521d14f366fe5aac09e512865d31bfa0ee53Jungshik Jang /** 21067ea521d14f366fe5aac09e512865d31bfa0ee53Jungshik Jang * Clean up action's state. 21167ea521d14f366fe5aac09e512865d31bfa0ee53Jungshik Jang * 21267ea521d14f366fe5aac09e512865d31bfa0ee53Jungshik Jang * <p>Declared as package-private. Only {@link HdmiControlService} can access it. 21367ea521d14f366fe5aac09e512865d31bfa0ee53Jungshik Jang */ 21467ea521d14f366fe5aac09e512865d31bfa0ee53Jungshik Jang void clear() { 21567ea521d14f366fe5aac09e512865d31bfa0ee53Jungshik Jang mState = STATE_NONE; 21667ea521d14f366fe5aac09e512865d31bfa0ee53Jungshik Jang // Clear all timers. 21767ea521d14f366fe5aac09e512865d31bfa0ee53Jungshik Jang mActionTimer.clearTimerMessage(); 218c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim } 219c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim 220c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim /** 221c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim * Finish up the action. Reset the state, and remove itself from the action queue. 222c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim */ 223c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim protected void finish() { 224c516d65fd96cdc39f9935ddb80d26ee6499a77bfYuncheol Heo finish(true); 225c516d65fd96cdc39f9935ddb80d26ee6499a77bfYuncheol Heo } 226c516d65fd96cdc39f9935ddb80d26ee6499a77bfYuncheol Heo 227c516d65fd96cdc39f9935ddb80d26ee6499a77bfYuncheol Heo void finish(boolean removeSelf) { 22867ea521d14f366fe5aac09e512865d31bfa0ee53Jungshik Jang clear(); 229c516d65fd96cdc39f9935ddb80d26ee6499a77bfYuncheol Heo if (removeSelf) { 230c516d65fd96cdc39f9935ddb80d26ee6499a77bfYuncheol Heo removeAction(this); 231c516d65fd96cdc39f9935ddb80d26ee6499a77bfYuncheol Heo } 232c516d65fd96cdc39f9935ddb80d26ee6499a77bfYuncheol Heo if (mOnFinishedCallbacks != null) { 233b509c2ecd99619248b7a07fb0fa978bb27f25cc3Jungshik Jang for (Pair<HdmiCecFeatureAction, Runnable> actionCallbackPair: mOnFinishedCallbacks) { 234c516d65fd96cdc39f9935ddb80d26ee6499a77bfYuncheol Heo if (actionCallbackPair.first.mState != STATE_NONE) { 235c516d65fd96cdc39f9935ddb80d26ee6499a77bfYuncheol Heo actionCallbackPair.second.run(); 236c516d65fd96cdc39f9935ddb80d26ee6499a77bfYuncheol Heo } 237c516d65fd96cdc39f9935ddb80d26ee6499a77bfYuncheol Heo } 238c516d65fd96cdc39f9935ddb80d26ee6499a77bfYuncheol Heo mOnFinishedCallbacks = null; 239c516d65fd96cdc39f9935ddb80d26ee6499a77bfYuncheol Heo } 240c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim } 241c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim 24279c58a4b97f27ede6a1b680d2fece9c2a0edf7b7Jungshik Jang protected final HdmiCecLocalDevice localDevice() { 24379c58a4b97f27ede6a1b680d2fece9c2a0edf7b7Jungshik Jang return mSource; 24479c58a4b97f27ede6a1b680d2fece9c2a0edf7b7Jungshik Jang } 24579c58a4b97f27ede6a1b680d2fece9c2a0edf7b7Jungshik Jang 24679c58a4b97f27ede6a1b680d2fece9c2a0edf7b7Jungshik Jang protected final HdmiCecLocalDevicePlayback playback() { 24779c58a4b97f27ede6a1b680d2fece9c2a0edf7b7Jungshik Jang return (HdmiCecLocalDevicePlayback) mSource; 24879c58a4b97f27ede6a1b680d2fece9c2a0edf7b7Jungshik Jang } 24979c58a4b97f27ede6a1b680d2fece9c2a0edf7b7Jungshik Jang 25079c58a4b97f27ede6a1b680d2fece9c2a0edf7b7Jungshik Jang protected final HdmiCecLocalDeviceTv tv() { 25179c58a4b97f27ede6a1b680d2fece9c2a0edf7b7Jungshik Jang return (HdmiCecLocalDeviceTv) mSource; 25279c58a4b97f27ede6a1b680d2fece9c2a0edf7b7Jungshik Jang } 25379c58a4b97f27ede6a1b680d2fece9c2a0edf7b7Jungshik Jang 25479c58a4b97f27ede6a1b680d2fece9c2a0edf7b7Jungshik Jang protected final int getSourceAddress() { 25579c58a4b97f27ede6a1b680d2fece9c2a0edf7b7Jungshik Jang return mSource.getDeviceInfo().getLogicalAddress(); 25679c58a4b97f27ede6a1b680d2fece9c2a0edf7b7Jungshik Jang } 25779c58a4b97f27ede6a1b680d2fece9c2a0edf7b7Jungshik Jang 25879c58a4b97f27ede6a1b680d2fece9c2a0edf7b7Jungshik Jang protected final int getSourcePath() { 25979c58a4b97f27ede6a1b680d2fece9c2a0edf7b7Jungshik Jang return mSource.getDeviceInfo().getPhysicalAddress(); 260c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim } 2618fa36b110be29d92a9aba070fa4666eefb14b584Jungshik Jang 262c516d65fd96cdc39f9935ddb80d26ee6499a77bfYuncheol Heo protected final void sendUserControlPressedAndReleased(int targetAddress, int uiCommand) { 2632e8f1b6399089626b4f0249427626ba6e63a62efJungshik Jang mSource.sendUserControlPressedAndReleased(targetAddress, uiCommand); 2648fa36b110be29d92a9aba070fa4666eefb14b584Jungshik Jang } 265c516d65fd96cdc39f9935ddb80d26ee6499a77bfYuncheol Heo 266b509c2ecd99619248b7a07fb0fa978bb27f25cc3Jungshik Jang protected final void addOnFinishedCallback(HdmiCecFeatureAction action, Runnable runnable) { 267c516d65fd96cdc39f9935ddb80d26ee6499a77bfYuncheol Heo if (mOnFinishedCallbacks == null) { 268c516d65fd96cdc39f9935ddb80d26ee6499a77bfYuncheol Heo mOnFinishedCallbacks = new ArrayList<>(); 269c516d65fd96cdc39f9935ddb80d26ee6499a77bfYuncheol Heo } 270c516d65fd96cdc39f9935ddb80d26ee6499a77bfYuncheol Heo mOnFinishedCallbacks.add(Pair.create(action, runnable)); 271c516d65fd96cdc39f9935ddb80d26ee6499a77bfYuncheol Heo } 272c70d2295dd3fb87ce8c81c704688d1ad05043b4dJinsuk Kim} 273