ActiveSourceHandler.java revision a062a9339add79a84862a34e363e3e454a6ec435
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. 31 */ 32final class ActiveSourceHandler { 33 private static final String TAG = "ActiveSourceHandler"; 34 35 private final HdmiCecLocalDevice mSource; 36 private final HdmiControlService mService; 37 @Nullable 38 private final IHdmiControlCallback mCallback; 39 40 static ActiveSourceHandler create(HdmiCecLocalDevice source, 41 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(HdmiCecLocalDevice 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 deviceLogicalAddress logical address of the device to be the active source 59 * @param routingPath routing path of the device to be the active source 60 */ 61 void process(int deviceLogicalAddress, int routingPath) { 62 if (getSourcePath() == routingPath && mSource.getActiveSource() == getSourceAddress()) { 63 invokeCallback(HdmiCec.RESULT_SUCCESS); 64 return; 65 } 66 HdmiCecDeviceInfo device = mService.getDeviceInfo(deviceLogicalAddress); 67 if (device == null) { 68 // "New device action" initiated by <Active Source> does not require 69 // "Routing change action". 70 mSource.addAndStartAction(new NewDeviceAction(mSource, deviceLogicalAddress, 71 routingPath, false)); 72 } 73 74 if (!mSource.isInPresetInstallationMode()) { 75 int prevActiveInput = mSource.getActivePortId(); 76 mSource.updateActiveDevice(deviceLogicalAddress, routingPath); 77 if (prevActiveInput != mSource.getActivePortId()) { 78 // TODO: change port input here. 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 (mSource.getActiveSource() == getSourceAddress()) { 86 HdmiCecMessage activeSource = 87 HdmiCecMessageBuilder.buildActiveSource(getSourceAddress(), 88 getSourcePath()); 89 mService.sendCecCommand(activeSource); 90 mSource.updateActiveDevice(deviceLogicalAddress, routingPath); 91 invokeCallback(HdmiCec.RESULT_SUCCESS); 92 } else { 93 int activePath = mSource.getActivePath(); 94 mService.sendCecCommand(HdmiCecMessageBuilder.buildRoutingChange(getSourceAddress(), 95 routingPath, activePath)); 96 // TODO: Start port select action here 97 // PortSelectAction action = new PortSelectAction(mService, getSourceAddress(), 98 // activePath, mCallback); 99 // mService.addActionAndStart(action); 100 } 101 } 102 } 103 104 private final int getSourceAddress() { 105 return mSource.getDeviceInfo().getLogicalAddress(); 106 } 107 108 private final int getSourcePath() { 109 return mSource.getDeviceInfo().getPhysicalAddress(); 110 } 111 112 private void invokeCallback(int result) { 113 if (mCallback == null) { 114 return; 115 } 116 try { 117 mCallback.onComplete(result); 118 } catch (RemoteException e) { 119 Slog.e(TAG, "Callback failed:" + e); 120 } 121 } 122} 123