1/*
2 * Copyright (C) 2016 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.tv.settings.system;
18
19import android.content.Context;
20import android.media.tv.TvInputInfo;
21import android.os.Bundle;
22import android.os.UserHandle;
23import android.support.annotation.NonNull;
24import android.support.v17.preference.LeanbackPreferenceFragment;
25import android.support.v7.preference.Preference;
26import android.support.v7.preference.PreferenceGroup;
27import android.support.v7.preference.TwoStatePreference;
28import android.text.TextUtils;
29
30import com.android.tv.settings.R;
31import com.android.tv.settings.RadioPreference;
32
33import java.util.Map;
34import java.util.Set;
35
36public class InputOptionsFragment extends LeanbackPreferenceFragment implements
37        InputCustomNameFragment.Callback {
38
39    private static final String KEY_SHOW_INPUT = "show_input";
40    private static final String KEY_NAMES = "names";
41    private static final String KEY_NAME_DEFAULT = "name_default";
42    private static final String KEY_NAME_CUSTOM = "name_custom";
43
44    private static final String ARG_INPUT = "input";
45
46    private TwoStatePreference mShowPref;
47    private PreferenceGroup mNamesGroup;
48    private TwoStatePreference mNameDefaultPref;
49    private TwoStatePreference mNameCustomPref;
50
51    private Map<String, String> mCustomLabels;
52    private Set<String> mHiddenIds;
53
54    private TvInputInfo mInputInfo;
55
56    public static void prepareArgs(@NonNull Bundle args, TvInputInfo inputInfo) {
57        args.putParcelable(ARG_INPUT, inputInfo);
58    }
59
60    @Override
61    public void onCreate(Bundle savedInstanceState) {
62        mInputInfo = getArguments().getParcelable(ARG_INPUT);
63
64        super.onCreate(savedInstanceState);
65
66        final Context context = getContext();
67        mCustomLabels =
68                TvInputInfo.TvInputSettings.getCustomLabels(context, UserHandle.USER_SYSTEM);
69        mHiddenIds =
70                TvInputInfo.TvInputSettings.getHiddenTvInputIds(context, UserHandle.USER_SYSTEM);
71
72    }
73
74    @Override
75    public void onResume() {
76        super.onResume();
77        refresh();
78    }
79
80    @Override
81    public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
82        setPreferencesFromResource(R.xml.input_options, null);
83        getPreferenceScreen().setTitle(mInputInfo.loadLabel(getContext()));
84
85        mShowPref = (TwoStatePreference) findPreference(KEY_SHOW_INPUT);
86
87        mNamesGroup = (PreferenceGroup) findPreference(KEY_NAMES);
88
89        mNameDefaultPref = (TwoStatePreference) findPreference(KEY_NAME_DEFAULT);
90        mNameCustomPref = (TwoStatePreference) findPreference(KEY_NAME_CUSTOM);
91
92    }
93
94    private void refresh() {
95
96        mShowPref.setChecked(!mHiddenIds.contains(mInputInfo.getId()));
97
98        final CharSequence defaultLabel = mInputInfo.loadLabel(getContext());
99        final CharSequence customLabel = mCustomLabels.get(mInputInfo.getId());
100
101        boolean nameMatched = false;
102        for (int i = 0; i < mNamesGroup.getPreferenceCount(); i++) {
103            final TwoStatePreference namePref = (TwoStatePreference) mNamesGroup.getPreference(i);
104
105            if (TextUtils.equals(namePref.getKey(), KEY_NAME_DEFAULT)
106                    || TextUtils.equals(namePref.getKey(), KEY_NAME_CUSTOM)) {
107                continue;
108            }
109            final boolean nameMatch = TextUtils.equals(namePref.getTitle(), customLabel);
110            namePref.setChecked(nameMatch);
111            nameMatched |= nameMatch;
112        }
113
114        mNameDefaultPref.setTitle(defaultLabel);
115
116        final boolean nameIsDefault = TextUtils.isEmpty(customLabel);
117        mNameDefaultPref.setChecked(nameIsDefault);
118
119        InputCustomNameFragment.prepareArgs(mNameCustomPref.getExtras(), defaultLabel,
120                nameIsDefault ? defaultLabel : customLabel);
121
122        if (!nameIsDefault && !nameMatched) {
123            mNameCustomPref.setChecked(true);
124            mNameCustomPref.setSummary(customLabel);
125        } else {
126            mNameCustomPref.setChecked(false);
127            mNameCustomPref.setSummary(null);
128        }
129    }
130
131    @Override
132    public boolean onPreferenceTreeClick(Preference preference) {
133        final String key = preference.getKey();
134        if (key == null) {
135            return super.onPreferenceTreeClick(preference);
136        }
137        if (preference instanceof RadioPreference) {
138            final RadioPreference radioPreference = (RadioPreference) preference;
139            radioPreference.setChecked(true);
140            radioPreference.clearOtherRadioPreferences(mNamesGroup);
141
142            if (TextUtils.equals(key, KEY_NAME_CUSTOM)) {
143                return super.onPreferenceTreeClick(preference);
144            } else if (TextUtils.equals(key, KEY_NAME_DEFAULT)) {
145                setInputName(null);
146                return true;
147            } else {
148                setInputName(preference.getTitle());
149            }
150        }
151        switch (key) {
152            case KEY_SHOW_INPUT:
153                setInputVisible(((TwoStatePreference) preference).isChecked());
154                return true;
155        }
156        return super.onPreferenceTreeClick(preference);
157    }
158
159    private void setInputName(CharSequence name) {
160        if (TextUtils.isEmpty(name)) {
161            mCustomLabels.remove(mInputInfo.getId());
162        } else {
163            mCustomLabels.put(mInputInfo.getId(), name.toString());
164        }
165
166        TvInputInfo.TvInputSettings
167                .putCustomLabels(getContext(), mCustomLabels, UserHandle.USER_SYSTEM);
168    }
169
170    private void setInputVisible(boolean visible) {
171        final boolean wasVisible = !mHiddenIds.contains(mInputInfo.getId());
172
173        if (wasVisible == visible) {
174            return;
175        }
176
177        if (visible) {
178            mHiddenIds.remove(mInputInfo.getId());
179        } else {
180            mHiddenIds.add(mInputInfo.getId());
181        }
182
183        TvInputInfo.TvInputSettings
184                .putHiddenTvInputs(getContext(), mHiddenIds, UserHandle.USER_SYSTEM);
185    }
186
187    @Override
188    public void onSetCustomName(CharSequence name) {
189        setInputName(name);
190    }
191}
192