1package com.android.server.hdmi; 2 3/* 4 * Copyright (C) 2014 The Android Open Source Project 5 * 6 * Licensed under the Apache License, Version 2.0 (the "License"); 7 * you may not use this file except in compliance with the License. 8 * You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, software 13 * distributed under the License is distributed on an "AS IS" BASIS, 14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 * See the License for the specific language governing permissions and 16 * limitations under the License. 17 */ 18 19import android.hardware.hdmi.HdmiControlManager; 20import android.hardware.hdmi.HdmiPlaybackClient; 21import android.hardware.hdmi.HdmiPlaybackClient.DisplayStatusCallback; 22import android.hardware.hdmi.IHdmiControlCallback; 23import android.os.RemoteException; 24import android.util.Slog; 25 26/** 27 * Feature action that queries the power status of other device. This action is initiated via 28 * {@link HdmiPlaybackClient#queryDisplayStatus(DisplayStatusCallback)} from the Android system 29 * working as playback device to get the power status of TV device. 30 * <p> 31 * Package-private, accessed by {@link HdmiControlService} only. 32 */ 33final class DevicePowerStatusAction extends HdmiCecFeatureAction { 34 private static final String TAG = "DevicePowerStatusAction"; 35 36 // State in which the action is waiting for <Report Power Status>. 37 private static final int STATE_WAITING_FOR_REPORT_POWER_STATUS = 1; 38 39 private final int mTargetAddress; 40 private final IHdmiControlCallback mCallback; 41 42 static DevicePowerStatusAction create(HdmiCecLocalDevice source, 43 int targetAddress, IHdmiControlCallback callback) { 44 if (source == null || callback == null) { 45 Slog.e(TAG, "Wrong arguments"); 46 return null; 47 } 48 return new DevicePowerStatusAction(source, targetAddress, callback); 49 } 50 51 private DevicePowerStatusAction(HdmiCecLocalDevice localDevice, 52 int targetAddress, IHdmiControlCallback callback) { 53 super(localDevice); 54 mTargetAddress = targetAddress; 55 mCallback = callback; 56 } 57 58 @Override 59 boolean start() { 60 queryDevicePowerStatus(); 61 mState = STATE_WAITING_FOR_REPORT_POWER_STATUS; 62 addTimer(mState, HdmiConfig.TIMEOUT_MS); 63 return true; 64 } 65 66 private void queryDevicePowerStatus() { 67 sendCommand(HdmiCecMessageBuilder.buildGiveDevicePowerStatus(getSourceAddress(), 68 mTargetAddress)); 69 } 70 71 @Override 72 boolean processCommand(HdmiCecMessage cmd) { 73 if (mState != STATE_WAITING_FOR_REPORT_POWER_STATUS 74 || mTargetAddress != cmd.getSource()) { 75 return false; 76 } 77 if (cmd.getOpcode() == Constants.MESSAGE_REPORT_POWER_STATUS) { 78 int status = cmd.getParams()[0]; 79 invokeCallback(status); 80 finish(); 81 return true; 82 } 83 return false; 84 } 85 86 @Override 87 void handleTimerEvent(int state) { 88 if (mState != state) { 89 return; 90 } 91 if (state == STATE_WAITING_FOR_REPORT_POWER_STATUS) { 92 // Got no response from TV. Report status 'unknown'. 93 invokeCallback(HdmiControlManager.POWER_STATUS_UNKNOWN); 94 finish(); 95 } 96 } 97 98 private void invokeCallback(int result) { 99 try { 100 mCallback.onComplete(result); 101 } catch (RemoteException e) { 102 Slog.e(TAG, "Callback failed:" + e); 103 } 104 } 105} 106