1 /*
2  * Copyright (C) 2015 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 
17 package com.android.tv.ui.sidepanel;
18 
19 import android.media.tv.TvInputInfo;
20 import android.os.Bundle;
21 import android.text.TextUtils;
22 import android.util.Log;
23 import android.view.LayoutInflater;
24 import android.view.View;
25 import android.view.ViewGroup;
26 
27 import com.android.tv.R;
28 import com.android.tv.util.PipInputManager;
29 import com.android.tv.util.PipInputManager.PipInput;
30 
31 import java.util.ArrayList;
32 import java.util.List;
33 import java.util.Objects;
34 
35 public class PipInputSelectorFragment extends SideFragment {
36     private static final String TAG = "PipInputSelector";
37     private static final String TRACKER_LABEL = "PIP input source";
38 
39     private final List<Item> mInputItems = new ArrayList<>();
40     private PipInputManager mPipInputManager;
41     private PipInput mInitialPipInput;
42     private boolean mSelected;
43 
44     private final PipInputManager.Listener mPipInputListener = new PipInputManager.Listener() {
45         @Override
46         public void onPipInputStateUpdated() {
47             notifyDataSetChanged();
48         }
49 
50         @Override
51         public void onPipInputListUpdated() {
52             refreshInputList();
53             setItems(mInputItems);
54         }
55     };
56 
57     @Override
onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)58     public View onCreateView(LayoutInflater inflater, ViewGroup container,
59             Bundle savedInstanceState) {
60         mPipInputManager = getMainActivity().getPipInputManager();
61         mPipInputManager.addListener(mPipInputListener);
62         getMainActivity().startShrunkenTvView(false, false);
63         return super.onCreateView(inflater, container, savedInstanceState);
64     }
65 
66     @Override
onStart()67     public void onStart() {
68         super.onStart();
69         mInitialPipInput = mPipInputManager.getPipInput(getMainActivity().getPipChannel());
70         if (mInitialPipInput == null) {
71             Log.w(TAG, "PIP should be on");
72             closeFragment();
73         }
74         int count = 0;
75         for (Item item : mInputItems) {
76             InputItem inputItem = (InputItem) item;
77             if (Objects.equals(inputItem.mPipInput, mInitialPipInput)) {
78                 setSelectedPosition(count);
79                 break;
80             }
81             ++count;
82         }
83     }
84 
85     @Override
onDestroyView()86     public void onDestroyView() {
87         super.onDestroyView();
88         mPipInputManager.removeListener(mPipInputListener);
89         if (!mSelected) {
90             getMainActivity().tuneToChannelForPip(mInitialPipInput.getChannel());
91         }
92         getMainActivity().endShrunkenTvView();
93     }
94 
95     @Override
getTitle()96     protected String getTitle() {
97         return getString(R.string.side_panel_title_pip_input_source);
98     }
99 
100     @Override
getTrackerLabel()101     public String getTrackerLabel() {
102         return TRACKER_LABEL;
103     }
104 
105     @Override
getItemList()106     protected List<Item> getItemList() {
107         refreshInputList();
108         return mInputItems;
109     }
110 
refreshInputList()111     private void refreshInputList() {
112         mInputItems.clear();
113         for (PipInput input : mPipInputManager.getPipInputList(false)) {
114             mInputItems.add(new InputItem(input));
115         }
116     }
117 
118     private class InputItem extends RadioButtonItem {
119         private final PipInput mPipInput;
120 
InputItem(PipInput input)121         private InputItem(PipInput input) {
122             super(input.getLongLabel());
123             mPipInput = input;
124             setEnabled(isAvailable());
125         }
126 
127         @Override
onUpdate()128         protected void onUpdate() {
129             super.onUpdate();
130             setEnabled(mPipInput.isAvailable());
131             setChecked(mPipInput == mInitialPipInput);
132         }
133 
134         @Override
onFocused()135         protected void onFocused() {
136             super.onFocused();
137             if (isEnabled()) {
138                 getMainActivity().tuneToChannelForPip(mPipInput.getChannel());
139             }
140         }
141 
142         @Override
onSelected()143         protected void onSelected() {
144             super.onSelected();
145             if (isEnabled()) {
146                 mSelected = true;
147                 closeFragment();
148             }
149         }
150 
isAvailable()151         private boolean isAvailable() {
152             if (!mPipInput.isAvailable()) {
153                 return false;
154             }
155 
156             // If this input shares the same parent with the current main input, you cannot select
157             // it. (E.g. two HDMI CEC devices that are connected to HDMI port 1 through an A/V
158             // receiver.)
159             PipInput pipInput = mPipInputManager.getPipInput(getMainActivity().getCurrentChannel());
160             if (pipInput == null) {
161                 return false;
162             }
163             TvInputInfo mainInputInfo = pipInput.getInputInfo();
164             TvInputInfo pipInputInfo = mPipInput.getInputInfo();
165             return mainInputInfo == null || pipInputInfo == null
166                     || !TextUtils.equals(mainInputInfo.getId(), pipInputInfo.getId())
167                     && !TextUtils.equals(mainInputInfo.getParentId(), pipInputInfo.getParentId());
168         }
169     }
170 }
171