DevicePowerStatusAction.java revision 78d695d8ba532214b02e7f18e0ccf89cf099163d
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.IHdmiControlCallback;
20import android.hardware.hdmi.HdmiCec;
21import android.hardware.hdmi.HdmiCecMessage;
22import android.os.RemoteException;
23import android.util.Slog;
24
25/**
26 * Feature action that queries the power status of other device.
27 *
28 * This action is initiated via {@link HdmiControlManager#queryDisplayStatus()} from
29 * the Android system working as playback device to get the power status of TV device.
30 *
31 * <p>Package-private, accessed by {@link HdmiControlService} only.
32 */
33
34final class DevicePowerStatusAction extends FeatureAction {
35    private static final String TAG = "DevicePowerStatusAction";
36
37    // State in which the action is waiting for <Report Power Status>.
38    private static final int STATE_WAITING_FOR_REPORT_POWER_STATUS = 1;
39
40    private final int mTargetAddress;
41    private final IHdmiControlCallback mCallback;
42
43    static DevicePowerStatusAction create(HdmiControlService service, int sourceAddress,
44            int targetAddress, IHdmiControlCallback callback) {
45        if (service == null || callback == null) {
46            Slog.e(TAG, "Wrong arguments");
47            return null;
48        }
49        return new DevicePowerStatusAction(service, sourceAddress, targetAddress, callback);
50    }
51
52    private DevicePowerStatusAction(HdmiControlService service, int sourceAddress,
53            int targetAddress, IHdmiControlCallback callback) {
54        super(service, sourceAddress);
55        mTargetAddress = targetAddress;
56        mCallback = callback;
57    }
58
59    @Override
60    boolean start() {
61        queryDevicePowerStatus();
62        mState = STATE_WAITING_FOR_REPORT_POWER_STATUS;
63        addTimer(mState, FeatureAction.TIMEOUT_MS);
64        return true;
65    }
66
67    private void queryDevicePowerStatus() {
68        mService.sendCecCommand(
69                HdmiCecMessageBuilder.buildGiveDevicePowerStatus(mSourceAddress, mTargetAddress));
70    }
71
72    @Override
73    boolean processCommand(HdmiCecMessage cmd) {
74        if (mState != STATE_WAITING_FOR_REPORT_POWER_STATUS) {
75            return false;
76        }
77        if (cmd.getOpcode() == HdmiCec.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(HdmiCec.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