HdmiCecLocalDeviceTv.java revision a6ce7708d6124224399241503fadcafe0c4684d4
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.hardware.hdmi.IHdmiControlCallback; 20import android.hardware.hdmi.HdmiCec; 21import android.hardware.hdmi.HdmiCecDeviceInfo; 22import android.hardware.hdmi.HdmiCecMessage; 23import android.os.RemoteException; 24import android.util.Slog; 25 26import java.util.Locale; 27 28/** 29 * Represent a logical device of type TV residing in Android system. 30 */ 31final class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice { 32 private static final String TAG = "HdmiCecLocalDeviceTv"; 33 34 HdmiCecLocalDeviceTv(HdmiControlService service) { 35 super(service, HdmiCec.DEVICE_TV); 36 } 37 38 @Override 39 protected void onAddressAllocated(int logicalAddress) { 40 // TODO: vendor-specific initialization here. 41 42 mService.sendCecCommand(HdmiCecMessageBuilder.buildReportPhysicalAddressCommand( 43 mAddress, mService.getPhysicalAddress(), mDeviceType)); 44 mService.sendCecCommand(HdmiCecMessageBuilder.buildDeviceVendorIdCommand( 45 mAddress, mService.getVendorId())); 46 47 mService.launchDeviceDiscovery(mAddress); 48 // TODO: Start routing control action, device discovery action. 49 } 50 51 @Override 52 protected boolean onMessage(HdmiCecMessage message) { 53 switch (message.getOpcode()) { 54 case HdmiCec.MESSAGE_REPORT_PHYSICAL_ADDRESS: 55 return handleReportPhysicalAddress(message); 56 default: 57 return super.onMessage(message); 58 } 59 } 60 61 /** 62 * Performs the action 'device select', or 'one touch play' initiated by TV. 63 * 64 * @param targetAddress logical address of the device to select 65 * @param callback callback object to report the result with 66 */ 67 void deviceSelect(int targetAddress, IHdmiControlCallback callback) { 68 HdmiCecDeviceInfo targetDevice = mService.getDeviceInfo(targetAddress); 69 if (targetDevice == null) { 70 invokeCallback(callback, HdmiCec.RESULT_TARGET_NOT_AVAILABLE); 71 return; 72 } 73 mService.removeAction(DeviceSelectAction.class); 74 mService.addAndStartAction(new DeviceSelectAction(mService, mAddress, 75 mService.getPhysicalAddress(), targetDevice, callback)); 76 } 77 78 private static void invokeCallback(IHdmiControlCallback callback, int result) { 79 try { 80 callback.onComplete(result); 81 } catch (RemoteException e) { 82 Slog.e(TAG, "Invoking callback failed:" + e); 83 } 84 } 85 86 @Override 87 protected boolean handleGetMenuLanguage(HdmiCecMessage message) { 88 HdmiCecMessage command = HdmiCecMessageBuilder.buildSetMenuLanguageCommand( 89 mAddress, Locale.getDefault().getISO3Language()); 90 // TODO: figure out how to handle failed to get language code. 91 if (command != null) { 92 mService.sendCecCommand(command); 93 } else { 94 Slog.w(TAG, "Failed to respond to <Get Menu Language>: " + message.toString()); 95 } 96 return true; 97 } 98 99 private boolean handleReportPhysicalAddress(HdmiCecMessage message) { 100 // Ignore if [Device Discovery Action] is going on. 101 if (mService.hasAction(DeviceDiscoveryAction.class)) { 102 Slog.i(TAG, "Ignore unrecognizable <Report Physical Address> " 103 + "because Device Discovery Action is on-going:" + message); 104 return true; 105 } 106 107 int physicalAddress = HdmiUtils.twoBytesToInt(message.getParams()); 108 mService.addAndStartAction(new NewDeviceAction(mService, 109 mAddress, message.getSource(), physicalAddress)); 110 111 return true; 112 } 113} 114