178d695d8ba532214b02e7f18e0ccf89cf099163dJinsuk Kimpackage com.android.server.hdmi;
278d695d8ba532214b02e7f18e0ccf89cf099163dJinsuk Kim
378d695d8ba532214b02e7f18e0ccf89cf099163dJinsuk Kim/*
478d695d8ba532214b02e7f18e0ccf89cf099163dJinsuk Kim * Copyright (C) 2014 The Android Open Source Project
578d695d8ba532214b02e7f18e0ccf89cf099163dJinsuk Kim *
678d695d8ba532214b02e7f18e0ccf89cf099163dJinsuk Kim * Licensed under the Apache License, Version 2.0 (the "License");
778d695d8ba532214b02e7f18e0ccf89cf099163dJinsuk Kim * you may not use this file except in compliance with the License.
878d695d8ba532214b02e7f18e0ccf89cf099163dJinsuk Kim * You may obtain a copy of the License at
978d695d8ba532214b02e7f18e0ccf89cf099163dJinsuk Kim *
1078d695d8ba532214b02e7f18e0ccf89cf099163dJinsuk Kim *      http://www.apache.org/licenses/LICENSE-2.0
1178d695d8ba532214b02e7f18e0ccf89cf099163dJinsuk Kim *
1278d695d8ba532214b02e7f18e0ccf89cf099163dJinsuk Kim * Unless required by applicable law or agreed to in writing, software
1378d695d8ba532214b02e7f18e0ccf89cf099163dJinsuk Kim * distributed under the License is distributed on an "AS IS" BASIS,
1478d695d8ba532214b02e7f18e0ccf89cf099163dJinsuk Kim * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1578d695d8ba532214b02e7f18e0ccf89cf099163dJinsuk Kim * See the License for the specific language governing permissions and
1678d695d8ba532214b02e7f18e0ccf89cf099163dJinsuk Kim * limitations under the License.
1778d695d8ba532214b02e7f18e0ccf89cf099163dJinsuk Kim */
1878d695d8ba532214b02e7f18e0ccf89cf099163dJinsuk Kim
1979c58a4b97f27ede6a1b680d2fece9c2a0edf7b7Jungshik Jangimport android.hardware.hdmi.HdmiControlManager;
208e93c84739902f5adaa499b474f39e3c4807bc1cJungshik Jangimport android.hardware.hdmi.HdmiPlaybackClient;
218e93c84739902f5adaa499b474f39e3c4807bc1cJungshik Jangimport android.hardware.hdmi.HdmiPlaybackClient.DisplayStatusCallback;
2279c58a4b97f27ede6a1b680d2fece9c2a0edf7b7Jungshik Jangimport android.hardware.hdmi.IHdmiControlCallback;
2378d695d8ba532214b02e7f18e0ccf89cf099163dJinsuk Kimimport android.os.RemoteException;
2478d695d8ba532214b02e7f18e0ccf89cf099163dJinsuk Kimimport android.util.Slog;
2578d695d8ba532214b02e7f18e0ccf89cf099163dJinsuk Kim
2678d695d8ba532214b02e7f18e0ccf89cf099163dJinsuk Kim/**
278e93c84739902f5adaa499b474f39e3c4807bc1cJungshik Jang * Feature action that queries the power status of other device. This action is initiated via
288e93c84739902f5adaa499b474f39e3c4807bc1cJungshik Jang * {@link HdmiPlaybackClient#queryDisplayStatus(DisplayStatusCallback)} from the Android system
298e93c84739902f5adaa499b474f39e3c4807bc1cJungshik Jang * working as playback device to get the power status of TV device.
308e93c84739902f5adaa499b474f39e3c4807bc1cJungshik Jang * <p>
318e93c84739902f5adaa499b474f39e3c4807bc1cJungshik Jang * Package-private, accessed by {@link HdmiControlService} only.
3278d695d8ba532214b02e7f18e0ccf89cf099163dJinsuk Kim */
33b509c2ecd99619248b7a07fb0fa978bb27f25cc3Jungshik Jangfinal class DevicePowerStatusAction extends HdmiCecFeatureAction {
3478d695d8ba532214b02e7f18e0ccf89cf099163dJinsuk Kim    private static final String TAG = "DevicePowerStatusAction";
3578d695d8ba532214b02e7f18e0ccf89cf099163dJinsuk Kim
3678d695d8ba532214b02e7f18e0ccf89cf099163dJinsuk Kim    // State in which the action is waiting for <Report Power Status>.
3778d695d8ba532214b02e7f18e0ccf89cf099163dJinsuk Kim    private static final int STATE_WAITING_FOR_REPORT_POWER_STATUS = 1;
3878d695d8ba532214b02e7f18e0ccf89cf099163dJinsuk Kim
3978d695d8ba532214b02e7f18e0ccf89cf099163dJinsuk Kim    private final int mTargetAddress;
4078d695d8ba532214b02e7f18e0ccf89cf099163dJinsuk Kim    private final IHdmiControlCallback mCallback;
4178d695d8ba532214b02e7f18e0ccf89cf099163dJinsuk Kim
4279c58a4b97f27ede6a1b680d2fece9c2a0edf7b7Jungshik Jang    static DevicePowerStatusAction create(HdmiCecLocalDevice source,
4378d695d8ba532214b02e7f18e0ccf89cf099163dJinsuk Kim            int targetAddress, IHdmiControlCallback callback) {
4479c58a4b97f27ede6a1b680d2fece9c2a0edf7b7Jungshik Jang        if (source == null || callback == null) {
4578d695d8ba532214b02e7f18e0ccf89cf099163dJinsuk Kim            Slog.e(TAG, "Wrong arguments");
4678d695d8ba532214b02e7f18e0ccf89cf099163dJinsuk Kim            return null;
4778d695d8ba532214b02e7f18e0ccf89cf099163dJinsuk Kim        }
4879c58a4b97f27ede6a1b680d2fece9c2a0edf7b7Jungshik Jang        return new DevicePowerStatusAction(source, targetAddress, callback);
4978d695d8ba532214b02e7f18e0ccf89cf099163dJinsuk Kim    }
5078d695d8ba532214b02e7f18e0ccf89cf099163dJinsuk Kim
5179c58a4b97f27ede6a1b680d2fece9c2a0edf7b7Jungshik Jang    private DevicePowerStatusAction(HdmiCecLocalDevice localDevice,
5278d695d8ba532214b02e7f18e0ccf89cf099163dJinsuk Kim            int targetAddress, IHdmiControlCallback callback) {
5379c58a4b97f27ede6a1b680d2fece9c2a0edf7b7Jungshik Jang        super(localDevice);
5478d695d8ba532214b02e7f18e0ccf89cf099163dJinsuk Kim        mTargetAddress = targetAddress;
5578d695d8ba532214b02e7f18e0ccf89cf099163dJinsuk Kim        mCallback = callback;
5678d695d8ba532214b02e7f18e0ccf89cf099163dJinsuk Kim    }
5778d695d8ba532214b02e7f18e0ccf89cf099163dJinsuk Kim
5878d695d8ba532214b02e7f18e0ccf89cf099163dJinsuk Kim    @Override
5978d695d8ba532214b02e7f18e0ccf89cf099163dJinsuk Kim    boolean start() {
6078d695d8ba532214b02e7f18e0ccf89cf099163dJinsuk Kim        queryDevicePowerStatus();
6178d695d8ba532214b02e7f18e0ccf89cf099163dJinsuk Kim        mState = STATE_WAITING_FOR_REPORT_POWER_STATUS;
625fba96df30b6b50b3cb9fe1d783320b1cc3bd6eaJinsuk Kim        addTimer(mState, HdmiConfig.TIMEOUT_MS);
6378d695d8ba532214b02e7f18e0ccf89cf099163dJinsuk Kim        return true;
6478d695d8ba532214b02e7f18e0ccf89cf099163dJinsuk Kim    }
6578d695d8ba532214b02e7f18e0ccf89cf099163dJinsuk Kim
6678d695d8ba532214b02e7f18e0ccf89cf099163dJinsuk Kim    private void queryDevicePowerStatus() {
6779c58a4b97f27ede6a1b680d2fece9c2a0edf7b7Jungshik Jang        sendCommand(HdmiCecMessageBuilder.buildGiveDevicePowerStatus(getSourceAddress(),
6879c58a4b97f27ede6a1b680d2fece9c2a0edf7b7Jungshik Jang                mTargetAddress));
6978d695d8ba532214b02e7f18e0ccf89cf099163dJinsuk Kim    }
7078d695d8ba532214b02e7f18e0ccf89cf099163dJinsuk Kim
7178d695d8ba532214b02e7f18e0ccf89cf099163dJinsuk Kim    @Override
7278d695d8ba532214b02e7f18e0ccf89cf099163dJinsuk Kim    boolean processCommand(HdmiCecMessage cmd) {
735352081c662299b618335bf3024058fa04ef2dfdJungshik Jang        if (mState != STATE_WAITING_FOR_REPORT_POWER_STATUS
745352081c662299b618335bf3024058fa04ef2dfdJungshik Jang               || mTargetAddress != cmd.getSource()) {
7578d695d8ba532214b02e7f18e0ccf89cf099163dJinsuk Kim            return false;
7678d695d8ba532214b02e7f18e0ccf89cf099163dJinsuk Kim        }
77c0c20d0522d7756d80f011e7a54bf3b51c78df41Jinsuk Kim        if (cmd.getOpcode() == Constants.MESSAGE_REPORT_POWER_STATUS) {
7878d695d8ba532214b02e7f18e0ccf89cf099163dJinsuk Kim            int status = cmd.getParams()[0];
7978d695d8ba532214b02e7f18e0ccf89cf099163dJinsuk Kim            invokeCallback(status);
8078d695d8ba532214b02e7f18e0ccf89cf099163dJinsuk Kim            finish();
8178d695d8ba532214b02e7f18e0ccf89cf099163dJinsuk Kim            return true;
8278d695d8ba532214b02e7f18e0ccf89cf099163dJinsuk Kim        }
8378d695d8ba532214b02e7f18e0ccf89cf099163dJinsuk Kim        return false;
8478d695d8ba532214b02e7f18e0ccf89cf099163dJinsuk Kim    }
8578d695d8ba532214b02e7f18e0ccf89cf099163dJinsuk Kim
8678d695d8ba532214b02e7f18e0ccf89cf099163dJinsuk Kim    @Override
8778d695d8ba532214b02e7f18e0ccf89cf099163dJinsuk Kim    void handleTimerEvent(int state) {
8878d695d8ba532214b02e7f18e0ccf89cf099163dJinsuk Kim        if (mState != state) {
8978d695d8ba532214b02e7f18e0ccf89cf099163dJinsuk Kim            return;
9078d695d8ba532214b02e7f18e0ccf89cf099163dJinsuk Kim        }
9178d695d8ba532214b02e7f18e0ccf89cf099163dJinsuk Kim        if (state == STATE_WAITING_FOR_REPORT_POWER_STATUS) {
9278d695d8ba532214b02e7f18e0ccf89cf099163dJinsuk Kim            // Got no response from TV. Report status 'unknown'.
93c0c20d0522d7756d80f011e7a54bf3b51c78df41Jinsuk Kim            invokeCallback(HdmiControlManager.POWER_STATUS_UNKNOWN);
9478d695d8ba532214b02e7f18e0ccf89cf099163dJinsuk Kim            finish();
9578d695d8ba532214b02e7f18e0ccf89cf099163dJinsuk Kim        }
9678d695d8ba532214b02e7f18e0ccf89cf099163dJinsuk Kim    }
9778d695d8ba532214b02e7f18e0ccf89cf099163dJinsuk Kim
9878d695d8ba532214b02e7f18e0ccf89cf099163dJinsuk Kim    private void invokeCallback(int result) {
9978d695d8ba532214b02e7f18e0ccf89cf099163dJinsuk Kim        try {
10078d695d8ba532214b02e7f18e0ccf89cf099163dJinsuk Kim            mCallback.onComplete(result);
10178d695d8ba532214b02e7f18e0ccf89cf099163dJinsuk Kim        } catch (RemoteException e) {
10278d695d8ba532214b02e7f18e0ccf89cf099163dJinsuk Kim            Slog.e(TAG, "Callback failed:" + e);
10378d695d8ba532214b02e7f18e0ccf89cf099163dJinsuk Kim        }
10478d695d8ba532214b02e7f18e0ccf89cf099163dJinsuk Kim    }
10578d695d8ba532214b02e7f18e0ccf89cf099163dJinsuk Kim}
106