HdmiCecLocalDevicePlayback.java revision a9f10629f4bc1a82761917645ff4d2b6d42e47b3
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.HdmiCecDeviceInfo; 20import android.hardware.hdmi.HdmiControlManager; 21import android.hardware.hdmi.IHdmiControlCallback; 22import android.os.RemoteException; 23import android.util.Slog; 24 25import com.android.server.hdmi.HdmiAnnotations.ServiceThreadOnly; 26 27/** 28 * Represent a logical device of type Playback residing in Android system. 29 */ 30final class HdmiCecLocalDevicePlayback extends HdmiCecLocalDevice { 31 private static final String TAG = "HdmiCecLocalDevicePlayback"; 32 33 private boolean mIsActiveSource = false; 34 35 HdmiCecLocalDevicePlayback(HdmiControlService service) { 36 super(service, HdmiCecDeviceInfo.DEVICE_PLAYBACK); 37 } 38 39 @Override 40 @ServiceThreadOnly 41 protected void onAddressAllocated(int logicalAddress, boolean fromBootup) { 42 assertRunOnServiceThread(); 43 mService.sendCecCommand(HdmiCecMessageBuilder.buildReportPhysicalAddressCommand( 44 mAddress, mService.getPhysicalAddress(), mDeviceType)); 45 } 46 47 @ServiceThreadOnly 48 void oneTouchPlay(IHdmiControlCallback callback) { 49 assertRunOnServiceThread(); 50 if (hasAction(OneTouchPlayAction.class)) { 51 Slog.w(TAG, "oneTouchPlay already in progress"); 52 invokeCallback(callback, HdmiControlManager.RESULT_ALREADY_IN_PROGRESS); 53 return; 54 } 55 56 // TODO: Consider the case of multiple TV sets. For now we always direct the command 57 // to the primary one. 58 OneTouchPlayAction action = OneTouchPlayAction.create(this, Constants.ADDR_TV, 59 callback); 60 if (action == null) { 61 Slog.w(TAG, "Cannot initiate oneTouchPlay"); 62 invokeCallback(callback, HdmiControlManager.RESULT_EXCEPTION); 63 return; 64 } 65 addAndStartAction(action); 66 } 67 68 @ServiceThreadOnly 69 void queryDisplayStatus(IHdmiControlCallback callback) { 70 assertRunOnServiceThread(); 71 if (hasAction(DevicePowerStatusAction.class)) { 72 Slog.w(TAG, "queryDisplayStatus already in progress"); 73 invokeCallback(callback, HdmiControlManager.RESULT_ALREADY_IN_PROGRESS); 74 return; 75 } 76 DevicePowerStatusAction action = DevicePowerStatusAction.create(this, 77 Constants.ADDR_TV, callback); 78 if (action == null) { 79 Slog.w(TAG, "Cannot initiate queryDisplayStatus"); 80 invokeCallback(callback, HdmiControlManager.RESULT_EXCEPTION); 81 return; 82 } 83 addAndStartAction(action); 84 } 85 86 @ServiceThreadOnly 87 private void invokeCallback(IHdmiControlCallback callback, int result) { 88 assertRunOnServiceThread(); 89 try { 90 callback.onComplete(result); 91 } catch (RemoteException e) { 92 Slog.e(TAG, "Invoking callback failed:" + e); 93 } 94 } 95 96 @Override 97 @ServiceThreadOnly 98 void onHotplug(int portId, boolean connected) { 99 assertRunOnServiceThread(); 100 mCecMessageCache.flushAll(); 101 mIsActiveSource = false; 102 if (connected && mService.isPowerStandbyOrTransient()) { 103 mService.wakeUp(); 104 } 105 } 106 107 @ServiceThreadOnly 108 void markActiveSource() { 109 assertRunOnServiceThread(); 110 mIsActiveSource = true; 111 } 112 113 @Override 114 @ServiceThreadOnly 115 protected boolean handleActiveSource(HdmiCecMessage message) { 116 assertRunOnServiceThread(); 117 int physicalAddress = HdmiUtils.twoBytesToInt(message.getParams()); 118 if (physicalAddress != mService.getPhysicalAddress()) { 119 mIsActiveSource = false; 120 if (mService.isPowerOnOrTransient()) { 121 mService.standby(); 122 } 123 return true; 124 } 125 return false; 126 } 127 128 @Override 129 @ServiceThreadOnly 130 protected boolean handleSetStreamPath(HdmiCecMessage message) { 131 assertRunOnServiceThread(); 132 int physicalAddress = HdmiUtils.twoBytesToInt(message.getParams()); 133 if (physicalAddress == mService.getPhysicalAddress()) { 134 if (mService.isPowerStandbyOrTransient()) { 135 mService.wakeUp(); 136 } 137 return true; 138 } 139 return false; 140 } 141 142 @Override 143 @ServiceThreadOnly 144 protected void disableDevice(boolean initiatedByCec, PendingActionClearedCallback callback) { 145 super.disableDevice(initiatedByCec, callback); 146 147 assertRunOnServiceThread(); 148 if (!initiatedByCec && mIsActiveSource) { 149 mService.sendCecCommand(HdmiCecMessageBuilder.buildInactiveSource( 150 mAddress, mService.getPhysicalAddress())); 151 } 152 mIsActiveSource = false; 153 checkIfPendingActionsCleared(); 154 } 155} 156