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