| /* |
| * 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. |
| * |
| * <p> 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); |
| } |
| } |