/* * Copyright (C) 2024 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.settings.bluetooth; import android.content.Context; import android.content.DialogInterface; import android.util.AttributeSet; import android.view.View; import android.widget.RadioGroup; import androidx.annotation.IntDef; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import com.android.settings.R; import com.android.settingslib.CustomDialogPreferenceCompat; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.Objects; /** * Preference for controlling the input routing for hearing device. * *
This preference displays a dialog that allows users to choose which input device that want to * use when using this hearing device. */ public class HearingDeviceInputRoutingPreference extends CustomDialogPreferenceCompat { /** * Annotations for possible input routing UI for this hearing device input routing preference. */ @Retention(RetentionPolicy.SOURCE) @IntDef({ InputRoutingValue.HEARING_DEVICE, InputRoutingValue.BUILTIN_MIC }) public @interface InputRoutingValue { int HEARING_DEVICE = 0; int BUILTIN_MIC = 1; } private static final int INVALID_ID = -1; private final Context mContext; private final int mFromHearingDeviceButtonId = R.id.input_from_hearing_device; private final int mFromBuiltinMicButtonId = R.id.input_from_builtin_mic; @Nullable private RadioGroup mInputRoutingGroup; @Nullable private InputRoutingCallback mCallback; // Default value is hearing device as input @InputRoutingValue private int mSelectedInputRoutingValue = InputRoutingValue.HEARING_DEVICE; public HearingDeviceInputRoutingPreference(@NonNull Context context) { this(context, null); } public HearingDeviceInputRoutingPreference(@NonNull Context context, @Nullable AttributeSet attrs) { super(context, attrs); mContext = context; setDialogTitle(R.string.bluetooth_hearing_device_input_routing_dialog_title); setDialogLayoutResource(R.layout.hearing_device_input_routing_dialog); setNegativeButtonText(R.string.cancel); setPositiveButtonText(R.string.done); } /** * Sets the callback to receive input routing updates. */ public void setInputRoutingCallback(@NonNull InputRoutingCallback callback) { mCallback = callback; } /** * Sets the {@link InputRoutingValue} value to determine which radio button should be checked, * and also update summary accordingly. * * @param inputRoutingValue The input routing value. */ public void setChecked(@InputRoutingValue int inputRoutingValue) { mSelectedInputRoutingValue = inputRoutingValue; setSummary(getSummary()); } @Override protected void onClick(DialogInterface dialog, int which) { if (which == DialogInterface.BUTTON_POSITIVE) { int prevBtnId = getRadioButtonId(mSelectedInputRoutingValue); int curBtnId = Objects.requireNonNull(mInputRoutingGroup).getCheckedRadioButtonId(); if (prevBtnId == curBtnId) { return; } setChecked(getSelectedInputRoutingValue()); if (mCallback != null) { mCallback.onInputRoutingUpdated(mSelectedInputRoutingValue); } } } @Override protected void onBindDialogView(View view) { super.onBindDialogView(view); mInputRoutingGroup = view.requireViewById(R.id.input_routing_group); mInputRoutingGroup.check(getRadioButtonId(mSelectedInputRoutingValue)); } @Nullable @Override public CharSequence getSummary() { return switch (mSelectedInputRoutingValue) { case InputRoutingValue.HEARING_DEVICE -> mContext.getResources().getString( R.string.bluetooth_hearing_device_input_routing_hearing_device_option); case InputRoutingValue.BUILTIN_MIC -> mContext.getResources().getString( R.string.bluetooth_hearing_device_input_routing_builtin_option); default -> null; }; } private int getRadioButtonId(@InputRoutingValue int inputRoutingValue) { return switch (inputRoutingValue) { case InputRoutingValue.HEARING_DEVICE -> mFromHearingDeviceButtonId; case InputRoutingValue.BUILTIN_MIC -> mFromBuiltinMicButtonId; default -> INVALID_ID; }; } @InputRoutingValue private int getSelectedInputRoutingValue() { int checkedId = Objects.requireNonNull(mInputRoutingGroup).getCheckedRadioButtonId(); if (checkedId == mFromBuiltinMicButtonId) { return InputRoutingValue.BUILTIN_MIC; } else { // Should always return default value hearing device as input if something error // happens. return InputRoutingValue.HEARING_DEVICE; } } /** * Callback to be invoked when input routing changes. */ public interface InputRoutingCallback { /** * Called when the positive button is clicked and input routing is changed. * * @param selectedInputRoutingValue The selected input routing value. */ void onInputRoutingUpdated(@InputRoutingValue int selectedInputRoutingValue); } }