ActiveSourceHandler.java revision 61f4fbd2e8436a1ecd478c2a1f516d064a24d43b
1a6ce7708d6124224399241503fadcafe0c4684d4Jinsuk Kim/* 2a6ce7708d6124224399241503fadcafe0c4684d4Jinsuk Kim * Copyright (C) 2014 The Android Open Source Project 3a6ce7708d6124224399241503fadcafe0c4684d4Jinsuk Kim * 4a6ce7708d6124224399241503fadcafe0c4684d4Jinsuk Kim * Licensed under the Apache License, Version 2.0 (the "License"); 5a6ce7708d6124224399241503fadcafe0c4684d4Jinsuk Kim * you may not use this file except in compliance with the License. 6a6ce7708d6124224399241503fadcafe0c4684d4Jinsuk Kim * You may obtain a copy of the License at 7a6ce7708d6124224399241503fadcafe0c4684d4Jinsuk Kim * 8a6ce7708d6124224399241503fadcafe0c4684d4Jinsuk Kim * http://www.apache.org/licenses/LICENSE-2.0 9a6ce7708d6124224399241503fadcafe0c4684d4Jinsuk Kim * 10a6ce7708d6124224399241503fadcafe0c4684d4Jinsuk Kim * Unless required by applicable law or agreed to in writing, software 11a6ce7708d6124224399241503fadcafe0c4684d4Jinsuk Kim * distributed under the License is distributed on an "AS IS" BASIS, 12a6ce7708d6124224399241503fadcafe0c4684d4Jinsuk Kim * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13a6ce7708d6124224399241503fadcafe0c4684d4Jinsuk Kim * See the License for the specific language governing permissions and 14a6ce7708d6124224399241503fadcafe0c4684d4Jinsuk Kim * limitations under the License. 15a6ce7708d6124224399241503fadcafe0c4684d4Jinsuk Kim */ 16a6ce7708d6124224399241503fadcafe0c4684d4Jinsuk Kim 17a6ce7708d6124224399241503fadcafe0c4684d4Jinsuk Kimpackage com.android.server.hdmi; 18a6ce7708d6124224399241503fadcafe0c4684d4Jinsuk Kim 19a6ce7708d6124224399241503fadcafe0c4684d4Jinsuk Kimimport android.annotation.Nullable; 20a6ce7708d6124224399241503fadcafe0c4684d4Jinsuk Kimimport android.hardware.hdmi.IHdmiControlCallback; 2161f4fbd2e8436a1ecd478c2a1f516d064a24d43bJungshik Jangimport android.hardware.hdmi.HdmiDeviceInfo; 22c0c20d0522d7756d80f011e7a54bf3b51c78df41Jinsuk Kimimport android.hardware.hdmi.HdmiControlManager; 23a6ce7708d6124224399241503fadcafe0c4684d4Jinsuk Kimimport android.os.RemoteException; 24a6ce7708d6124224399241503fadcafe0c4684d4Jinsuk Kimimport android.util.Slog; 25a6ce7708d6124224399241503fadcafe0c4684d4Jinsuk Kim 2672b7d738d5b9254594726304cdb1777b54d95631Jinsuk Kimimport com.android.server.hdmi.HdmiCecLocalDevice.ActiveSource; 2772b7d738d5b9254594726304cdb1777b54d95631Jinsuk Kim 28a6ce7708d6124224399241503fadcafe0c4684d4Jinsuk Kim/** 29a6ce7708d6124224399241503fadcafe0c4684d4Jinsuk Kim * Handles CEC command <Active Source>. 3079c58a4b97f27ede6a1b680d2fece9c2a0edf7b7Jungshik Jang * <p> 318333571bd5e0a08773a1679964f8d96227af3356Jinsuk Kim * Used by feature actions that need to handle the command in their flow. Only for TV 328333571bd5e0a08773a1679964f8d96227af3356Jinsuk Kim * local device. 33a6ce7708d6124224399241503fadcafe0c4684d4Jinsuk Kim */ 34a6ce7708d6124224399241503fadcafe0c4684d4Jinsuk Kimfinal class ActiveSourceHandler { 35a6ce7708d6124224399241503fadcafe0c4684d4Jinsuk Kim private static final String TAG = "ActiveSourceHandler"; 36a6ce7708d6124224399241503fadcafe0c4684d4Jinsuk Kim 378333571bd5e0a08773a1679964f8d96227af3356Jinsuk Kim private final HdmiCecLocalDeviceTv mSource; 38a6ce7708d6124224399241503fadcafe0c4684d4Jinsuk Kim private final HdmiControlService mService; 3979c58a4b97f27ede6a1b680d2fece9c2a0edf7b7Jungshik Jang @Nullable 4079c58a4b97f27ede6a1b680d2fece9c2a0edf7b7Jungshik Jang private final IHdmiControlCallback mCallback; 41a6ce7708d6124224399241503fadcafe0c4684d4Jinsuk Kim 428333571bd5e0a08773a1679964f8d96227af3356Jinsuk Kim static ActiveSourceHandler create(HdmiCecLocalDeviceTv source, IHdmiControlCallback callback) { 4379c58a4b97f27ede6a1b680d2fece9c2a0edf7b7Jungshik Jang if (source == null) { 44a6ce7708d6124224399241503fadcafe0c4684d4Jinsuk Kim Slog.e(TAG, "Wrong arguments"); 45a6ce7708d6124224399241503fadcafe0c4684d4Jinsuk Kim return null; 46a6ce7708d6124224399241503fadcafe0c4684d4Jinsuk Kim } 4779c58a4b97f27ede6a1b680d2fece9c2a0edf7b7Jungshik Jang return new ActiveSourceHandler(source, callback); 48a6ce7708d6124224399241503fadcafe0c4684d4Jinsuk Kim } 49a6ce7708d6124224399241503fadcafe0c4684d4Jinsuk Kim 508333571bd5e0a08773a1679964f8d96227af3356Jinsuk Kim private ActiveSourceHandler(HdmiCecLocalDeviceTv source, IHdmiControlCallback callback) { 5179c58a4b97f27ede6a1b680d2fece9c2a0edf7b7Jungshik Jang mSource = source; 5279c58a4b97f27ede6a1b680d2fece9c2a0edf7b7Jungshik Jang mService = mSource.getService(); 53a6ce7708d6124224399241503fadcafe0c4684d4Jinsuk Kim mCallback = callback; 54a6ce7708d6124224399241503fadcafe0c4684d4Jinsuk Kim } 55a6ce7708d6124224399241503fadcafe0c4684d4Jinsuk Kim 56a6ce7708d6124224399241503fadcafe0c4684d4Jinsuk Kim /** 57a6ce7708d6124224399241503fadcafe0c4684d4Jinsuk Kim * Handles the incoming active source command. 58a6ce7708d6124224399241503fadcafe0c4684d4Jinsuk Kim * 5972b7d738d5b9254594726304cdb1777b54d95631Jinsuk Kim * @param newActive new active source information 60a6ce7708d6124224399241503fadcafe0c4684d4Jinsuk Kim */ 6172b7d738d5b9254594726304cdb1777b54d95631Jinsuk Kim void process(ActiveSource newActive) { 628333571bd5e0a08773a1679964f8d96227af3356Jinsuk Kim // Seq #17 638333571bd5e0a08773a1679964f8d96227af3356Jinsuk Kim HdmiCecLocalDeviceTv tv = mSource; 6472b7d738d5b9254594726304cdb1777b54d95631Jinsuk Kim ActiveSource activeSource = tv.getActiveSource(); 6572b7d738d5b9254594726304cdb1777b54d95631Jinsuk Kim if (activeSource.equals(newActive)) { 66c0c20d0522d7756d80f011e7a54bf3b51c78df41Jinsuk Kim invokeCallback(HdmiControlManager.RESULT_SUCCESS); 67a6ce7708d6124224399241503fadcafe0c4684d4Jinsuk Kim return; 68a6ce7708d6124224399241503fadcafe0c4684d4Jinsuk Kim } 6961f4fbd2e8436a1ecd478c2a1f516d064a24d43bJungshik Jang HdmiDeviceInfo device = mService.getDeviceInfo(newActive.logicalAddress); 70a6ce7708d6124224399241503fadcafe0c4684d4Jinsuk Kim if (device == null) { 7172b7d738d5b9254594726304cdb1777b54d95631Jinsuk Kim tv.startNewDeviceAction(newActive); 72a6ce7708d6124224399241503fadcafe0c4684d4Jinsuk Kim } 73a6ce7708d6124224399241503fadcafe0c4684d4Jinsuk Kim 744d43d93743222311c6377d4904c19ccb93699d3bJinsuk Kim if (!tv.isProhibitMode()) { 7572b7d738d5b9254594726304cdb1777b54d95631Jinsuk Kim tv.updateActiveSource(newActive); 767c3a95633d307c4be30c9dbbf1071063aa7a3c64Jinsuk Kim boolean notifyInputChange = (mCallback == null); 777c3a95633d307c4be30c9dbbf1071063aa7a3c64Jinsuk Kim tv.updateActiveInput(newActive.physicalAddress, notifyInputChange); 78c0c20d0522d7756d80f011e7a54bf3b51c78df41Jinsuk Kim invokeCallback(HdmiControlManager.RESULT_SUCCESS); 79a6ce7708d6124224399241503fadcafe0c4684d4Jinsuk Kim } else { 80a6ce7708d6124224399241503fadcafe0c4684d4Jinsuk Kim // TV is in a mode that should keep its current source/input from 81a6ce7708d6124224399241503fadcafe0c4684d4Jinsuk Kim // being changed for its operation. Reclaim the active source 82a6ce7708d6124224399241503fadcafe0c4684d4Jinsuk Kim // or switch the port back to the one used for the current mode. 837c3a95633d307c4be30c9dbbf1071063aa7a3c64Jinsuk Kim ActiveSource current = tv.getActiveSource(); 8472b7d738d5b9254594726304cdb1777b54d95631Jinsuk Kim if (current.logicalAddress == getSourceAddress()) { 8572b7d738d5b9254594726304cdb1777b54d95631Jinsuk Kim HdmiCecMessage activeSourceCommand = HdmiCecMessageBuilder.buildActiveSource( 8672b7d738d5b9254594726304cdb1777b54d95631Jinsuk Kim current.logicalAddress, current.physicalAddress); 8772b7d738d5b9254594726304cdb1777b54d95631Jinsuk Kim mService.sendCecCommand(activeSourceCommand); 8872b7d738d5b9254594726304cdb1777b54d95631Jinsuk Kim tv.updateActiveSource(current); 89c0c20d0522d7756d80f011e7a54bf3b51c78df41Jinsuk Kim invokeCallback(HdmiControlManager.RESULT_SUCCESS); 90a6ce7708d6124224399241503fadcafe0c4684d4Jinsuk Kim } else { 918333571bd5e0a08773a1679964f8d96227af3356Jinsuk Kim HdmiCecMessage routingChange = HdmiCecMessageBuilder.buildRoutingChange( 9272b7d738d5b9254594726304cdb1777b54d95631Jinsuk Kim getSourceAddress(), newActive.physicalAddress, current.physicalAddress); 938333571bd5e0a08773a1679964f8d96227af3356Jinsuk Kim mService.sendCecCommand(routingChange); 9472b7d738d5b9254594726304cdb1777b54d95631Jinsuk Kim tv.addAndStartAction( 9572b7d738d5b9254594726304cdb1777b54d95631Jinsuk Kim new RoutingControlAction(tv, current.physicalAddress, true, mCallback)); 96a6ce7708d6124224399241503fadcafe0c4684d4Jinsuk Kim } 97a6ce7708d6124224399241503fadcafe0c4684d4Jinsuk Kim } 98a6ce7708d6124224399241503fadcafe0c4684d4Jinsuk Kim } 99a6ce7708d6124224399241503fadcafe0c4684d4Jinsuk Kim 10079c58a4b97f27ede6a1b680d2fece9c2a0edf7b7Jungshik Jang private final int getSourceAddress() { 10179c58a4b97f27ede6a1b680d2fece9c2a0edf7b7Jungshik Jang return mSource.getDeviceInfo().getLogicalAddress(); 10279c58a4b97f27ede6a1b680d2fece9c2a0edf7b7Jungshik Jang } 10379c58a4b97f27ede6a1b680d2fece9c2a0edf7b7Jungshik Jang 104a6ce7708d6124224399241503fadcafe0c4684d4Jinsuk Kim private void invokeCallback(int result) { 105a6ce7708d6124224399241503fadcafe0c4684d4Jinsuk Kim if (mCallback == null) { 106a6ce7708d6124224399241503fadcafe0c4684d4Jinsuk Kim return; 107a6ce7708d6124224399241503fadcafe0c4684d4Jinsuk Kim } 108a6ce7708d6124224399241503fadcafe0c4684d4Jinsuk Kim try { 109a6ce7708d6124224399241503fadcafe0c4684d4Jinsuk Kim mCallback.onComplete(result); 110a6ce7708d6124224399241503fadcafe0c4684d4Jinsuk Kim } catch (RemoteException e) { 111a6ce7708d6124224399241503fadcafe0c4684d4Jinsuk Kim Slog.e(TAG, "Callback failed:" + e); 112a6ce7708d6124224399241503fadcafe0c4684d4Jinsuk Kim } 113a6ce7708d6124224399241503fadcafe0c4684d4Jinsuk Kim } 114a6ce7708d6124224399241503fadcafe0c4684d4Jinsuk Kim} 115