ActiveSourceHandler.java revision 61f4fbd2e8436a1ecd478c2a1f516d064a24d43b
1a6ce7708d6124224399241503fadcafe0c4684d4Jinsuk Kim/*
2a6ce7708d6124224399241503fadcafe0c4684d4Jinsuk Kim * Copyright (C) 2014 The Android Open Source Project
3a6ce7708d6124224399241503fadcafe0c4684d4Jinsuk Kim *
4a6ce7708d6124224399241503fadcafe0c4684d4Jinsuk Kim * Licensed under the Apache License, Version 2.0 (the "License");
5a6ce7708d6124224399241503fadcafe0c4684d4Jinsuk Kim * you may not use this file except in compliance with the License.
6a6ce7708d6124224399241503fadcafe0c4684d4Jinsuk Kim * You may obtain a copy of the License at
7a6ce7708d6124224399241503fadcafe0c4684d4Jinsuk Kim *
8a6ce7708d6124224399241503fadcafe0c4684d4Jinsuk Kim *      http://www.apache.org/licenses/LICENSE-2.0
9a6ce7708d6124224399241503fadcafe0c4684d4Jinsuk Kim *
10a6ce7708d6124224399241503fadcafe0c4684d4Jinsuk Kim * Unless required by applicable law or agreed to in writing, software
11a6ce7708d6124224399241503fadcafe0c4684d4Jinsuk Kim * distributed under the License is distributed on an "AS IS" BASIS,
12a6ce7708d6124224399241503fadcafe0c4684d4Jinsuk Kim * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13a6ce7708d6124224399241503fadcafe0c4684d4Jinsuk Kim * See the License for the specific language governing permissions and
14a6ce7708d6124224399241503fadcafe0c4684d4Jinsuk Kim * limitations under the License.
15a6ce7708d6124224399241503fadcafe0c4684d4Jinsuk Kim */
16a6ce7708d6124224399241503fadcafe0c4684d4Jinsuk Kim
17a6ce7708d6124224399241503fadcafe0c4684d4Jinsuk Kimpackage com.android.server.hdmi;
18a6ce7708d6124224399241503fadcafe0c4684d4Jinsuk Kim
19a6ce7708d6124224399241503fadcafe0c4684d4Jinsuk Kimimport android.annotation.Nullable;
20a6ce7708d6124224399241503fadcafe0c4684d4Jinsuk Kimimport android.hardware.hdmi.IHdmiControlCallback;
2161f4fbd2e8436a1ecd478c2a1f516d064a24d43bJungshik Jangimport android.hardware.hdmi.HdmiDeviceInfo;
22c0c20d0522d7756d80f011e7a54bf3b51c78df41Jinsuk Kimimport android.hardware.hdmi.HdmiControlManager;
23a6ce7708d6124224399241503fadcafe0c4684d4Jinsuk Kimimport android.os.RemoteException;
24a6ce7708d6124224399241503fadcafe0c4684d4Jinsuk Kimimport android.util.Slog;
25a6ce7708d6124224399241503fadcafe0c4684d4Jinsuk Kim
2672b7d738d5b9254594726304cdb1777b54d95631Jinsuk Kimimport com.android.server.hdmi.HdmiCecLocalDevice.ActiveSource;
2772b7d738d5b9254594726304cdb1777b54d95631Jinsuk Kim
28a6ce7708d6124224399241503fadcafe0c4684d4Jinsuk Kim/**
29a6ce7708d6124224399241503fadcafe0c4684d4Jinsuk Kim * Handles CEC command <Active Source>.
3079c58a4b97f27ede6a1b680d2fece9c2a0edf7b7Jungshik Jang * <p>
318333571bd5e0a08773a1679964f8d96227af3356Jinsuk Kim * Used by feature actions that need to handle the command in their flow. Only for TV
328333571bd5e0a08773a1679964f8d96227af3356Jinsuk Kim * local device.
33a6ce7708d6124224399241503fadcafe0c4684d4Jinsuk Kim */
34a6ce7708d6124224399241503fadcafe0c4684d4Jinsuk Kimfinal class ActiveSourceHandler {
35a6ce7708d6124224399241503fadcafe0c4684d4Jinsuk Kim    private static final String TAG = "ActiveSourceHandler";
36a6ce7708d6124224399241503fadcafe0c4684d4Jinsuk Kim
378333571bd5e0a08773a1679964f8d96227af3356Jinsuk Kim    private final HdmiCecLocalDeviceTv mSource;
38a6ce7708d6124224399241503fadcafe0c4684d4Jinsuk Kim    private final HdmiControlService mService;
3979c58a4b97f27ede6a1b680d2fece9c2a0edf7b7Jungshik Jang    @Nullable
4079c58a4b97f27ede6a1b680d2fece9c2a0edf7b7Jungshik Jang    private final IHdmiControlCallback mCallback;
41a6ce7708d6124224399241503fadcafe0c4684d4Jinsuk Kim
428333571bd5e0a08773a1679964f8d96227af3356Jinsuk Kim    static ActiveSourceHandler create(HdmiCecLocalDeviceTv source, IHdmiControlCallback callback) {
4379c58a4b97f27ede6a1b680d2fece9c2a0edf7b7Jungshik Jang        if (source == null) {
44a6ce7708d6124224399241503fadcafe0c4684d4Jinsuk Kim            Slog.e(TAG, "Wrong arguments");
45a6ce7708d6124224399241503fadcafe0c4684d4Jinsuk Kim            return null;
46a6ce7708d6124224399241503fadcafe0c4684d4Jinsuk Kim        }
4779c58a4b97f27ede6a1b680d2fece9c2a0edf7b7Jungshik Jang        return new ActiveSourceHandler(source, callback);
48a6ce7708d6124224399241503fadcafe0c4684d4Jinsuk Kim    }
49a6ce7708d6124224399241503fadcafe0c4684d4Jinsuk Kim
508333571bd5e0a08773a1679964f8d96227af3356Jinsuk Kim    private ActiveSourceHandler(HdmiCecLocalDeviceTv source, IHdmiControlCallback callback) {
5179c58a4b97f27ede6a1b680d2fece9c2a0edf7b7Jungshik Jang        mSource = source;
5279c58a4b97f27ede6a1b680d2fece9c2a0edf7b7Jungshik Jang        mService = mSource.getService();
53a6ce7708d6124224399241503fadcafe0c4684d4Jinsuk Kim        mCallback = callback;
54a6ce7708d6124224399241503fadcafe0c4684d4Jinsuk Kim    }
55a6ce7708d6124224399241503fadcafe0c4684d4Jinsuk Kim
56a6ce7708d6124224399241503fadcafe0c4684d4Jinsuk Kim    /**
57a6ce7708d6124224399241503fadcafe0c4684d4Jinsuk Kim     * Handles the incoming active source command.
58a6ce7708d6124224399241503fadcafe0c4684d4Jinsuk Kim     *
5972b7d738d5b9254594726304cdb1777b54d95631Jinsuk Kim     * @param newActive new active source information
60a6ce7708d6124224399241503fadcafe0c4684d4Jinsuk Kim     */
6172b7d738d5b9254594726304cdb1777b54d95631Jinsuk Kim    void process(ActiveSource newActive) {
628333571bd5e0a08773a1679964f8d96227af3356Jinsuk Kim        // Seq #17
638333571bd5e0a08773a1679964f8d96227af3356Jinsuk Kim        HdmiCecLocalDeviceTv tv = mSource;
6472b7d738d5b9254594726304cdb1777b54d95631Jinsuk Kim        ActiveSource activeSource = tv.getActiveSource();
6572b7d738d5b9254594726304cdb1777b54d95631Jinsuk Kim        if (activeSource.equals(newActive)) {
66c0c20d0522d7756d80f011e7a54bf3b51c78df41Jinsuk Kim            invokeCallback(HdmiControlManager.RESULT_SUCCESS);
67a6ce7708d6124224399241503fadcafe0c4684d4Jinsuk Kim            return;
68a6ce7708d6124224399241503fadcafe0c4684d4Jinsuk Kim        }
6961f4fbd2e8436a1ecd478c2a1f516d064a24d43bJungshik Jang        HdmiDeviceInfo device = mService.getDeviceInfo(newActive.logicalAddress);
70a6ce7708d6124224399241503fadcafe0c4684d4Jinsuk Kim        if (device == null) {
7172b7d738d5b9254594726304cdb1777b54d95631Jinsuk Kim            tv.startNewDeviceAction(newActive);
72a6ce7708d6124224399241503fadcafe0c4684d4Jinsuk Kim        }
73a6ce7708d6124224399241503fadcafe0c4684d4Jinsuk Kim
744d43d93743222311c6377d4904c19ccb93699d3bJinsuk Kim        if (!tv.isProhibitMode()) {
7572b7d738d5b9254594726304cdb1777b54d95631Jinsuk Kim            tv.updateActiveSource(newActive);
767c3a95633d307c4be30c9dbbf1071063aa7a3c64Jinsuk Kim            boolean notifyInputChange = (mCallback == null);
777c3a95633d307c4be30c9dbbf1071063aa7a3c64Jinsuk Kim            tv.updateActiveInput(newActive.physicalAddress, notifyInputChange);
78c0c20d0522d7756d80f011e7a54bf3b51c78df41Jinsuk Kim            invokeCallback(HdmiControlManager.RESULT_SUCCESS);
79a6ce7708d6124224399241503fadcafe0c4684d4Jinsuk Kim        } else {
80a6ce7708d6124224399241503fadcafe0c4684d4Jinsuk Kim            // TV is in a mode that should keep its current source/input from
81a6ce7708d6124224399241503fadcafe0c4684d4Jinsuk Kim            // being changed for its operation. Reclaim the active source
82a6ce7708d6124224399241503fadcafe0c4684d4Jinsuk Kim            // or switch the port back to the one used for the current mode.
837c3a95633d307c4be30c9dbbf1071063aa7a3c64Jinsuk Kim            ActiveSource current = tv.getActiveSource();
8472b7d738d5b9254594726304cdb1777b54d95631Jinsuk Kim            if (current.logicalAddress == getSourceAddress()) {
8572b7d738d5b9254594726304cdb1777b54d95631Jinsuk Kim                HdmiCecMessage activeSourceCommand = HdmiCecMessageBuilder.buildActiveSource(
8672b7d738d5b9254594726304cdb1777b54d95631Jinsuk Kim                        current.logicalAddress, current.physicalAddress);
8772b7d738d5b9254594726304cdb1777b54d95631Jinsuk Kim                mService.sendCecCommand(activeSourceCommand);
8872b7d738d5b9254594726304cdb1777b54d95631Jinsuk Kim                tv.updateActiveSource(current);
89c0c20d0522d7756d80f011e7a54bf3b51c78df41Jinsuk Kim                invokeCallback(HdmiControlManager.RESULT_SUCCESS);
90a6ce7708d6124224399241503fadcafe0c4684d4Jinsuk Kim            } else {
918333571bd5e0a08773a1679964f8d96227af3356Jinsuk Kim                HdmiCecMessage routingChange = HdmiCecMessageBuilder.buildRoutingChange(
9272b7d738d5b9254594726304cdb1777b54d95631Jinsuk Kim                        getSourceAddress(), newActive.physicalAddress, current.physicalAddress);
938333571bd5e0a08773a1679964f8d96227af3356Jinsuk Kim                mService.sendCecCommand(routingChange);
9472b7d738d5b9254594726304cdb1777b54d95631Jinsuk Kim                tv.addAndStartAction(
9572b7d738d5b9254594726304cdb1777b54d95631Jinsuk Kim                        new RoutingControlAction(tv, current.physicalAddress, true, mCallback));
96a6ce7708d6124224399241503fadcafe0c4684d4Jinsuk Kim            }
97a6ce7708d6124224399241503fadcafe0c4684d4Jinsuk Kim        }
98a6ce7708d6124224399241503fadcafe0c4684d4Jinsuk Kim    }
99a6ce7708d6124224399241503fadcafe0c4684d4Jinsuk Kim
10079c58a4b97f27ede6a1b680d2fece9c2a0edf7b7Jungshik Jang    private final int getSourceAddress() {
10179c58a4b97f27ede6a1b680d2fece9c2a0edf7b7Jungshik Jang        return mSource.getDeviceInfo().getLogicalAddress();
10279c58a4b97f27ede6a1b680d2fece9c2a0edf7b7Jungshik Jang    }
10379c58a4b97f27ede6a1b680d2fece9c2a0edf7b7Jungshik Jang
104a6ce7708d6124224399241503fadcafe0c4684d4Jinsuk Kim    private void invokeCallback(int result) {
105a6ce7708d6124224399241503fadcafe0c4684d4Jinsuk Kim        if (mCallback == null) {
106a6ce7708d6124224399241503fadcafe0c4684d4Jinsuk Kim            return;
107a6ce7708d6124224399241503fadcafe0c4684d4Jinsuk Kim        }
108a6ce7708d6124224399241503fadcafe0c4684d4Jinsuk Kim        try {
109a6ce7708d6124224399241503fadcafe0c4684d4Jinsuk Kim            mCallback.onComplete(result);
110a6ce7708d6124224399241503fadcafe0c4684d4Jinsuk Kim        } catch (RemoteException e) {
111a6ce7708d6124224399241503fadcafe0c4684d4Jinsuk Kim            Slog.e(TAG, "Callback failed:" + e);
112a6ce7708d6124224399241503fadcafe0c4684d4Jinsuk Kim        }
113a6ce7708d6124224399241503fadcafe0c4684d4Jinsuk Kim    }
114a6ce7708d6124224399241503fadcafe0c4684d4Jinsuk Kim}
115