ActiveSourceHandler.java revision a6ce7708d6124224399241503fadcafe0c4684d4
1/*
2 * Copyright (C) 2014 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.hdmi;
18
19import android.annotation.Nullable;
20import android.hardware.hdmi.IHdmiControlCallback;
21import android.hardware.hdmi.HdmiCec;
22import android.hardware.hdmi.HdmiCecDeviceInfo;
23import android.hardware.hdmi.HdmiCecMessage;
24import android.os.RemoteException;
25import android.util.Slog;
26
27/**
28 * Handles CEC command <Active Source>.
29 *
30 * <p>Used by feature actions that need to handle the command in their flow.
31 */
32final class ActiveSourceHandler {
33    private static final String TAG = "ActiveSourceHandler";
34
35    private final HdmiControlService mService;
36    private final int mSourceAddress;
37    private final int mSourcePath;
38    @Nullable private final IHdmiControlCallback mCallback;
39
40    static ActiveSourceHandler create(HdmiControlService service, int sourceAddress,
41            int sourcePath, IHdmiControlCallback callback) {
42        if (service == null) {
43            Slog.e(TAG, "Wrong arguments");
44            return null;
45        }
46        return new ActiveSourceHandler(service, sourceAddress, sourcePath, callback);
47    }
48
49    private ActiveSourceHandler(HdmiControlService service, int sourceAddress, int sourcePath,
50            IHdmiControlCallback callback) {
51        mService = service;
52        mSourceAddress = sourceAddress;
53        mSourcePath = sourcePath;
54        mCallback = callback;
55    }
56
57    /**
58     * Handles the incoming active source command.
59     *
60     * @param deviceLogicalAddress logical address of the device to be the active source
61     * @param routingPath routing path of the device to be the active source
62     */
63    void process(int deviceLogicalAddress, int routingPath) {
64        if (mSourcePath == routingPath && mService.getActiveSource() == mSourceAddress) {
65            invokeCallback(HdmiCec.RESULT_SUCCESS);
66            return;
67        }
68        HdmiCecDeviceInfo device = mService.getDeviceInfo(deviceLogicalAddress);
69        if (device == null) {
70            // TODO: Start new device action (Device Discovery) sequence 5.
71        }
72
73        if (!mService.isInPresetInstallationMode()) {
74            int prevActiveInput = mService.getActiveInput();
75            mService.updateActiveDevice(deviceLogicalAddress, routingPath);
76            if (prevActiveInput != mService.getActiveInput()) {
77                // TODO: change port input here.
78            }
79            invokeCallback(HdmiCec.RESULT_SUCCESS);
80        } else {
81            // TV is in a mode that should keep its current source/input from
82            // being changed for its operation. Reclaim the active source
83            // or switch the port back to the one used for the current mode.
84            if (mService.getActiveSource() == mSourceAddress) {
85                HdmiCecMessage activeSource =
86                        HdmiCecMessageBuilder.buildActiveSource(mSourceAddress, mSourcePath);
87                mService.sendCecCommand(activeSource);
88                mService.updateActiveDevice(deviceLogicalAddress, routingPath);
89                invokeCallback(HdmiCec.RESULT_SUCCESS);
90            } else {
91                int activePath = mService.getActivePath();
92                mService.sendCecCommand(HdmiCecMessageBuilder.buildRoutingChange(mSourceAddress,
93                        routingPath, activePath));
94                // TODO: Start port select action here
95                // PortSelectAction action = new PortSelectAction(mService, mSourceAddress,
96                //        activePath, mCallback);
97                // mService.addActionAndStart(action);
98            }
99        }
100    }
101
102    private void invokeCallback(int result) {
103        if (mCallback == null) {
104            return;
105        }
106        try {
107            mCallback.onComplete(result);
108        } catch (RemoteException e) {
109            Slog.e(TAG, "Callback failed:" + e);
110        }
111    }
112}
113