ActiveSourceHandler.java revision 04fd28046acc2ac74339ed94cec76a0bfda846f7
1/* 2 * Copyright (C) 2014 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.server.hdmi; 18 19import android.annotation.Nullable; 20import android.hardware.hdmi.IHdmiControlCallback; 21import android.hardware.hdmi.HdmiCec; 22import android.hardware.hdmi.HdmiCecDeviceInfo; 23import android.hardware.hdmi.HdmiCecMessage; 24import android.os.RemoteException; 25import android.util.Slog; 26 27/** 28 * Handles CEC command <Active Source>. 29 * <p> 30 * Used by feature actions that need to handle the command in their flow. Only for TV 31 * local device. 32 */ 33final class ActiveSourceHandler { 34 private static final String TAG = "ActiveSourceHandler"; 35 36 private final HdmiCecLocalDeviceTv mSource; 37 private final HdmiControlService mService; 38 @Nullable 39 private final IHdmiControlCallback mCallback; 40 41 static ActiveSourceHandler create(HdmiCecLocalDeviceTv source, IHdmiControlCallback callback) { 42 if (source == null) { 43 Slog.e(TAG, "Wrong arguments"); 44 return null; 45 } 46 return new ActiveSourceHandler(source, callback); 47 } 48 49 private ActiveSourceHandler(HdmiCecLocalDeviceTv source, IHdmiControlCallback callback) { 50 mSource = source; 51 mService = mSource.getService(); 52 mCallback = callback; 53 } 54 55 /** 56 * Handles the incoming active source command. 57 * 58 * @param activeAddress logical address of the device to be the active source 59 * @param activePath routing path of the device to be the active source 60 */ 61 void process(int activeAddress, int activePath) { 62 // Seq #17 63 HdmiCecLocalDeviceTv tv = mSource; 64 if (getSourcePath() == activePath && tv.getActiveSource() == getSourceAddress()) { 65 invokeCallback(HdmiCec.RESULT_SUCCESS); 66 return; 67 } 68 HdmiCecDeviceInfo device = mService.getDeviceInfo(activeAddress); 69 if (device == null) { 70 tv.addAndStartAction(new NewDeviceAction(tv, activeAddress, activePath)); 71 } 72 73 int currentActive = tv.getActiveSource(); 74 int currentPath = tv.getActivePath(); 75 if (!tv.isInPresetInstallationMode()) { 76 tv.updateActiveSource(activeAddress, activePath); 77 if (currentActive != activeAddress && currentPath != activePath) { 78 tv.updateActivePortId(mService.pathToPortId(activePath)); 79 } 80 invokeCallback(HdmiCec.RESULT_SUCCESS); 81 } else { 82 // TV is in a mode that should keep its current source/input from 83 // being changed for its operation. Reclaim the active source 84 // or switch the port back to the one used for the current mode. 85 if (currentActive == getSourceAddress()) { 86 HdmiCecMessage activeSource = 87 HdmiCecMessageBuilder.buildActiveSource(currentActive, currentPath); 88 mService.sendCecCommand(activeSource); 89 tv.updateActiveSource(currentActive, currentPath); 90 invokeCallback(HdmiCec.RESULT_SUCCESS); 91 } else { 92 HdmiCecMessage routingChange = HdmiCecMessageBuilder.buildRoutingChange( 93 getSourceAddress(), activePath, currentPath); 94 mService.sendCecCommand(routingChange); 95 tv.addAndStartAction(new RoutingControlAction(tv, currentPath, true, mCallback)); 96 } 97 } 98 } 99 100 private final int getSourceAddress() { 101 return mSource.getDeviceInfo().getLogicalAddress(); 102 } 103 104 private final int getSourcePath() { 105 return mSource.getDeviceInfo().getPhysicalAddress(); 106 } 107 108 private void invokeCallback(int result) { 109 if (mCallback == null) { 110 return; 111 } 112 try { 113 mCallback.onComplete(result); 114 } catch (RemoteException e) { 115 Slog.e(TAG, "Callback failed:" + e); 116 } 117 } 118} 119