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 26import java.util.ArrayList; 27import java.util.List; 28 29/** 30 * Feature action that queries the power status of other device. This action is initiated via 31 * {@link HdmiPlaybackClient#queryDisplayStatus(DisplayStatusCallback)} from the Android system 32 * working as playback device to get the power status of TV device. 33 * <p> 34 * Package-private, accessed by {@link HdmiControlService} only. 35 */ 36final class DevicePowerStatusAction extends HdmiCecFeatureAction { 37 private static final String TAG = "DevicePowerStatusAction"; 38 39 // State in which the action is waiting for <Report Power Status>. 40 private static final int STATE_WAITING_FOR_REPORT_POWER_STATUS = 1; 41 42 private final int mTargetAddress; 43 private final List<IHdmiControlCallback> mCallbacks = new ArrayList<>(); 44 45 static DevicePowerStatusAction create(HdmiCecLocalDevice source, 46 int targetAddress, IHdmiControlCallback callback) { 47 if (source == null || callback == null) { 48 Slog.e(TAG, "Wrong arguments"); 49 return null; 50 } 51 return new DevicePowerStatusAction(source, targetAddress, callback); 52 } 53 54 private DevicePowerStatusAction(HdmiCecLocalDevice localDevice, 55 int targetAddress, IHdmiControlCallback callback) { 56 super(localDevice); 57 mTargetAddress = targetAddress; 58 addCallback(callback); 59 } 60 61 @Override 62 boolean start() { 63 queryDevicePowerStatus(); 64 mState = STATE_WAITING_FOR_REPORT_POWER_STATUS; 65 addTimer(mState, HdmiConfig.TIMEOUT_MS); 66 return true; 67 } 68 69 private void queryDevicePowerStatus() { 70 sendCommand(HdmiCecMessageBuilder.buildGiveDevicePowerStatus(getSourceAddress(), 71 mTargetAddress)); 72 } 73 74 @Override 75 boolean processCommand(HdmiCecMessage cmd) { 76 if (mState != STATE_WAITING_FOR_REPORT_POWER_STATUS 77 || mTargetAddress != cmd.getSource()) { 78 return false; 79 } 80 if (cmd.getOpcode() == Constants.MESSAGE_REPORT_POWER_STATUS) { 81 int status = cmd.getParams()[0]; 82 invokeCallback(status); 83 finish(); 84 return true; 85 } 86 return false; 87 } 88 89 @Override 90 void handleTimerEvent(int state) { 91 if (mState != state) { 92 return; 93 } 94 if (state == STATE_WAITING_FOR_REPORT_POWER_STATUS) { 95 // Got no response from TV. Report status 'unknown'. 96 invokeCallback(HdmiControlManager.POWER_STATUS_UNKNOWN); 97 finish(); 98 } 99 } 100 101 public void addCallback(IHdmiControlCallback callback) { 102 mCallbacks.add(callback); 103 } 104 105 private void invokeCallback(int result) { 106 try { 107 for (IHdmiControlCallback callback : mCallbacks) { 108 callback.onComplete(result); 109 } 110 } catch (RemoteException e) { 111 Slog.e(TAG, "Callback failed:" + e); 112 } 113 } 114} 115