aboutsummaryrefslogtreecommitdiff
path: root/src/com/android/tv/util/PipInputManager.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/com/android/tv/util/PipInputManager.java')
-rw-r--r--src/com/android/tv/util/PipInputManager.java432
1 files changed, 0 insertions, 432 deletions
diff --git a/src/com/android/tv/util/PipInputManager.java b/src/com/android/tv/util/PipInputManager.java
deleted file mode 100644
index 2c51d5a0..00000000
--- a/src/com/android/tv/util/PipInputManager.java
+++ /dev/null
@@ -1,432 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.tv.util;
-
-import android.content.Context;
-import android.media.tv.TvInputInfo;
-import android.media.tv.TvInputManager;
-import android.media.tv.TvInputManager.TvInputCallback;
-import android.util.ArraySet;
-import android.util.Log;
-
-import com.android.tv.ChannelTuner;
-import com.android.tv.R;
-import com.android.tv.data.Channel;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * A class that manages inputs for PIP. All tuner inputs are represented to one tuner input for PIP.
- * Hidden inputs should not be visible to the users.
- */
-public class PipInputManager {
- private static final String TAG = "PipInputManager";
-
- // Tuner inputs aren't distinguished each other in PipInput. They are handled as one input.
- // Therefore, we define a fake input id for the unified input.
- private static final String TUNER_INPUT_ID = "tuner_input_id";
-
- private final Context mContext;
- private final TvInputManagerHelper mInputManager;
- private final ChannelTuner mChannelTuner;
- private boolean mStarted;
- private final Map<String, PipInput> mPipInputMap = new HashMap<>(); // inputId -> PipInput
- private final Set<Listener> mListeners = new ArraySet<>();
-
- private final TvInputCallback mTvInputCallback = new TvInputCallback() {
- @Override
- public void onInputAdded(String inputId) {
- TvInputInfo input = mInputManager.getTvInputInfo(inputId);
- if (input.isPassthroughInput()) {
- boolean available = mInputManager.getInputState(input)
- == TvInputManager.INPUT_STATE_CONNECTED;
- mPipInputMap.put(inputId, new PipInput(inputId, available));
- } else if (!mPipInputMap.containsKey(TUNER_INPUT_ID)) {
- boolean available = mChannelTuner.getBrowsableChannelCount() != 0;
- mPipInputMap.put(TUNER_INPUT_ID, new PipInput(TUNER_INPUT_ID, available));
- } else {
- return;
- }
- for (Listener l : mListeners) {
- l.onPipInputListUpdated();
- }
- }
-
- @Override
- public void onInputRemoved(String inputId) {
- PipInput pipInput = mPipInputMap.remove(inputId);
- if (pipInput == null) {
- if (!mPipInputMap.containsKey(TUNER_INPUT_ID)) {
- Log.w(TAG, "A TV input (" + inputId + ") isn't tracked in PipInputManager");
- return;
- }
- if (mInputManager.getTunerTvInputSize() > 0) {
- return;
- }
- mPipInputMap.remove(TUNER_INPUT_ID);
- }
- for (Listener l : mListeners) {
- l.onPipInputListUpdated();
- }
- }
-
- @Override
- public void onInputStateChanged(String inputId, int state) {
- PipInput pipInput = mPipInputMap.get(inputId);
- if (pipInput == null) {
- // For tuner input, state change is handled in mChannelTunerListener.
- return;
- }
- pipInput.updateAvailability();
- }
- };
-
- private final ChannelTuner.Listener mChannelTunerListener = new ChannelTuner.Listener() {
- @Override
- public void onLoadFinished() { }
-
- @Override
- public void onCurrentChannelUnavailable(Channel channel) { }
-
- @Override
- public void onBrowsableChannelListChanged() {
- PipInput tunerInput = mPipInputMap.get(TUNER_INPUT_ID);
- if (tunerInput == null) {
- return;
- }
- tunerInput.updateAvailability();
- }
-
- @Override
- public void onChannelChanged(Channel previousChannel, Channel currentChannel) {
- if (previousChannel != null && currentChannel != null
- && !previousChannel.isPassthrough() && !currentChannel.isPassthrough()) {
- // Channel change between channels for tuner inputs.
- return;
- }
- PipInput previousMainInput = getPipInput(previousChannel);
- if (previousMainInput != null) {
- previousMainInput.updateAvailability();
- }
- PipInput currentMainInput = getPipInput(currentChannel);
- if (currentMainInput != null) {
- currentMainInput.updateAvailability();
- }
- }
- };
-
- public PipInputManager(Context context, TvInputManagerHelper inputManager,
- ChannelTuner channelTuner) {
- mContext = context;
- mInputManager = inputManager;
- mChannelTuner = channelTuner;
- }
-
- /**
- * Starts {@link PipInputManager}.
- */
- public void start() {
- if (mStarted) {
- return;
- }
- mStarted = true;
- mInputManager.addCallback(mTvInputCallback);
- mChannelTuner.addListener(mChannelTunerListener);
- initializePipInputList();
- }
-
- /**
- * Stops {@link PipInputManager}.
- */
- public void stop() {
- if (!mStarted) {
- return;
- }
- mStarted = false;
- mInputManager.removeCallback(mTvInputCallback);
- mChannelTuner.removeListener(mChannelTunerListener);
- mPipInputMap.clear();
- }
-
- /**
- * Adds a {@link PipInputManager.Listener}.
- */
- public void addListener(Listener listener) {
- mListeners.add(listener);
- }
-
- /**
- * Removes a {@link PipInputManager.Listener}.
- */
- public void removeListener(Listener listener) {
- mListeners.remove(listener);
- }
-
- /**
- * Gets the size of inputs for PIP.
- *
- * <p>The hidden inputs are not counted.
- *
- * @param availableOnly If {@code true}, it counts only available PIP inputs. Please see {@link
- * PipInput#isAvailable()} for the details of availability.
- */
- public int getPipInputSize(boolean availableOnly) {
- int count = 0;
- for (PipInput pipInput : mPipInputMap.values()) {
- if (!pipInput.isHidden() && (!availableOnly || pipInput.mAvailable)) {
- ++count;
- }
- if (pipInput.isPassthrough()) {
- TvInputInfo info = pipInput.getInputInfo();
- // Do not count HDMI ports if a CEC device is directly connected to the port.
- if (info.getParentId() != null && !info.isConnectedToHdmiSwitch()) {
- --count;
- }
- }
- }
- return count;
- }
-
- /**
- * Gets the list of inputs for PIP..
- *
- * <p>The hidden inputs are excluded.
- *
- * @param availableOnly If true, it returns only available PIP inputs. Please see {@link
- * PipInput#isAvailable()} for the details of availability.
- */
- public List<PipInput> getPipInputList(boolean availableOnly) {
- List<PipInput> pipInputs = new ArrayList<>();
- List<PipInput> removeInputs = new ArrayList<>();
- for (PipInput pipInput : mPipInputMap.values()) {
- if (!pipInput.isHidden() && (!availableOnly || pipInput.mAvailable)) {
- pipInputs.add(pipInput);
- }
- if (pipInput.isPassthrough()) {
- TvInputInfo info = pipInput.getInputInfo();
- // Do not show HDMI ports if a CEC device is directly connected to the port.
- if (info.getParentId() != null && !info.isConnectedToHdmiSwitch()) {
- removeInputs.add(mPipInputMap.get(info.getParentId()));
- }
- }
- }
- if (!removeInputs.isEmpty()) {
- pipInputs.removeAll(removeInputs);
- }
- Collections.sort(pipInputs, new Comparator<PipInput>() {
- @Override
- public int compare(PipInput lhs, PipInput rhs) {
- if (!lhs.mIsPassthrough) {
- return -1;
- }
- if (!rhs.mIsPassthrough) {
- return 1;
- }
- String a = lhs.getLabel();
- String b = rhs.getLabel();
- return a.compareTo(b);
- }
- });
- return pipInputs;
- }
-
- /**
- * Returns an PIP input corresponding to {@code channel}.
- */
- public PipInput getPipInput(Channel channel) {
- if (channel == null) {
- return null;
- }
- if (channel.isPassthrough()) {
- return mPipInputMap.get(channel.getInputId());
- } else {
- return mPipInputMap.get(TUNER_INPUT_ID);
- }
- }
-
- /**
- * Returns true, if {@code channel1} and {@code channel2} belong to the same input. For example,
- * two channels from different tuner inputs are also in the same input "Tuner" from PIP
- * point of view.
- */
- public boolean areInSamePipInput(Channel channel1, Channel channel2) {
- PipInput input1 = getPipInput(channel1);
- PipInput input2 = getPipInput(channel2);
- return input1 != null && input2 != null
- && getPipInput(channel1).equals(getPipInput(channel2));
- }
-
- private void initializePipInputList() {
- boolean hasTunerInput = false;
- for (TvInputInfo input : mInputManager.getTvInputInfos(false, false)) {
- if (input.isPassthroughInput()) {
- boolean available = mInputManager.getInputState(input)
- == TvInputManager.INPUT_STATE_CONNECTED;
- mPipInputMap.put(input.getId(), new PipInput(input.getId(), available));
- } else if (!hasTunerInput) {
- hasTunerInput = true;
- boolean available = mChannelTuner.getBrowsableChannelCount() != 0;
- mPipInputMap.put(TUNER_INPUT_ID, new PipInput(TUNER_INPUT_ID, available));
- }
- }
- PipInput input = getPipInput(mChannelTuner.getCurrentChannel());
- if (input != null) {
- input.updateAvailability();
- }
- for (Listener l : mListeners) {
- l.onPipInputListUpdated();
- }
- }
-
- /**
- * Listeners to notify PIP input state changes.
- */
- public interface Listener {
- /**
- * Called when the state (availability) of PIP inputs is changed.
- */
- void onPipInputStateUpdated();
-
- /**
- * Called when the list of PIP inputs is changed.
- */
- void onPipInputListUpdated();
- }
-
- /**
- * Input class for PIP. It has useful methods for PIP handling.
- */
- public class PipInput {
- private final String mInputId;
- private final boolean mIsPassthrough;
- private final TvInputInfo mInputInfo;
- private boolean mAvailable;
-
- private PipInput(String inputId, boolean available) {
- mInputId = inputId;
- mIsPassthrough = !mInputId.equals(TUNER_INPUT_ID);
- if (mIsPassthrough) {
- mInputInfo = mInputManager.getTvInputInfo(mInputId);
- } else {
- mInputInfo = null;
- }
- mAvailable = available;
- }
-
- /**
- * Returns the {@link TvInputInfo} object that matches to this PIP input.
- */
- public TvInputInfo getInputInfo() {
- return mInputInfo;
- }
-
- /**
- * Returns {@code true}, if the input is available for PIP. If a channel of an input is
- * already played or an input is not connected state or there is no browsable channel, the
- * input is unavailable.
- */
- public boolean isAvailable() {
- return mAvailable;
- }
-
- /**
- * Returns true, if the input is a passthrough TV input.
- */
- public boolean isPassthrough() {
- return mIsPassthrough;
- }
-
- /**
- * Gets a channel to play in a PIP view.
- */
- public Channel getChannel() {
- if (mIsPassthrough) {
- return Channel.createPassthroughChannel(mInputId);
- } else {
- return mChannelTuner.findNearestBrowsableChannel(
- Utils.getLastWatchedChannelId(mContext));
- }
- }
-
- /**
- * Gets a label of the input.
- */
- public String getLabel() {
- if (mIsPassthrough) {
- return mInputInfo.loadLabel(mContext).toString();
- } else {
- return mContext.getString(R.string.input_selector_tuner_label);
- }
- }
-
- /**
- * Gets a long label including a customized label.
- */
- public String getLongLabel() {
- if (mIsPassthrough) {
- String customizedLabel = Utils.loadLabel(mContext, mInputInfo);
- String label = getLabel();
- if (label.equals(customizedLabel)) {
- return customizedLabel;
- }
- return customizedLabel + " (" + label + ")";
- } else {
- return mContext.getString(R.string.input_long_label_for_tuner);
- }
- }
-
- /**
- * Updates availability. It returns true, if availability is changed.
- */
- private void updateAvailability() {
- boolean available;
- // current playing input cannot be available for PIP.
- Channel currentChannel = mChannelTuner.getCurrentChannel();
- if (mIsPassthrough) {
- if (currentChannel != null && currentChannel.getInputId().equals(mInputId)) {
- available = false;
- } else {
- available = mInputManager.getInputState(mInputId)
- == TvInputManager.INPUT_STATE_CONNECTED;
- }
- } else {
- if (currentChannel != null && !currentChannel.isPassthrough()) {
- available = false;
- } else {
- available = mChannelTuner.getBrowsableChannelCount() > 0;
- }
- }
- if (mAvailable != available) {
- mAvailable = available;
- for (Listener l : mListeners) {
- l.onPipInputStateUpdated();
- }
- }
- }
-
- private boolean isHidden() {
- // mInputInfo is null for the tuner input and it's always visible.
- return mInputInfo != null && mInputInfo.isHidden(mContext);
- }
- }
-}