blob: d835105133a4608b1fb97688d055e12ed461f791 [file] [log] [blame]
/*
* Copyright (C) 2018 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.settings.device.sound;
import android.content.Context;
import android.media.AudioManager;
import android.provider.Settings;
import androidx.preference.SwitchPreference;
import androidx.preference.Preference;
import android.text.TextUtils;
import android.util.Log;
import com.android.settingslib.core.AbstractPreferenceController;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Map;
/**
* Controller for the surround sound switch preferences.
*/
public class SoundFormatPreferenceController extends AbstractPreferenceController {
private static final String TAG = "SoundFormatController";
private int mFormatId;
private AudioManager mAudioManager;
private Map<Integer, Boolean> mReportedFormats;
public SoundFormatPreferenceController(Context context, int formatId) {
super(context);
mFormatId = formatId;
mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
mReportedFormats = mAudioManager.getReportedSurroundFormats();
}
@Override
public boolean isAvailable() {
return true;
}
@Override
public String getPreferenceKey() {
return SoundFragment.KEY_SURROUND_SOUND_FORMAT_PREFIX + mFormatId;
}
@Override
public void updateState(Preference preference) {
super.updateState(preference);
if (preference.getKey().equals(getPreferenceKey())) {
preference.setEnabled(getFormatPreferencesEnabledState());
((SwitchPreference) preference).setChecked(getFormatPreferenceCheckedState());
}
}
@Override
public boolean handlePreferenceTreeClick(Preference preference) {
if (preference.getKey().equals(getPreferenceKey())) {
setSurroundManualFormatsSetting(((SwitchPreference) preference).isChecked());
}
return super.handlePreferenceTreeClick(preference);
}
/**
* @return checked state of a surround sound format switch based on passthrough setting and
* audio manager state for the format.
*/
private boolean getFormatPreferenceCheckedState() {
switch (SoundFragment.getSurroundPassthroughSetting(mContext)) {
case SoundFragment.VAL_SURROUND_SOUND_NEVER:
return false;
case SoundFragment.VAL_SURROUND_SOUND_ALWAYS:
return true;
case SoundFragment.VAL_SURROUND_SOUND_AUTO:
return isReportedFormat();
case SoundFragment.VAL_SURROUND_SOUND_MANUAL:
return getFormatsEnabledInManualMode().contains(mFormatId);
default: return false;
}
}
/** @return true if the format checkboxes should be enabled, i.e. in manual mode. */
private boolean getFormatPreferencesEnabledState() {
return SoundFragment.getSurroundPassthroughSetting(mContext)
== SoundFragment.VAL_SURROUND_SOUND_MANUAL;
}
/** @return the formats that are enabled in manual mode, from global settings */
private HashSet<Integer> getFormatsEnabledInManualMode() {
HashSet<Integer> formats = new HashSet<>();
String enabledFormats = Settings.Global.getString(mContext.getContentResolver(),
Settings.Global.ENCODED_SURROUND_OUTPUT_ENABLED_FORMATS);
if (enabledFormats == null) {
// Starting with Android P passthrough setting ALWAYS has been replaced with MANUAL.
// In that case all formats will be enabled when in MANUAL mode.
formats.addAll(mAudioManager.getSurroundFormats().keySet());
} else {
try {
Arrays.stream(enabledFormats.split(",")).mapToInt(Integer::parseInt)
.forEach(formats::add);
} catch (NumberFormatException e) {
Log.w(TAG, "ENCODED_SURROUND_OUTPUT_ENABLED_FORMATS misformatted.", e);
}
}
return formats;
}
/**
* Writes enabled/disabled state for a given format to the global settings.
*/
private void setSurroundManualFormatsSetting(boolean enabled) {
HashSet<Integer> formats = getFormatsEnabledInManualMode();
if (enabled) {
formats.add(mFormatId);
} else {
formats.remove(mFormatId);
}
Settings.Global.putString(mContext.getContentResolver(),
Settings.Global.ENCODED_SURROUND_OUTPUT_ENABLED_FORMATS,
TextUtils.join(",", formats));
}
/** @return true if the given format is reported by the device. */
private boolean isReportedFormat() {
return mReportedFormats != null && mReportedFormats.get(mFormatId) != null;
}
}