1 /* 2 * Copyright (C) 2019 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.settings.development.bluetooth; 18 19 import android.content.Context; 20 import android.util.AttributeSet; 21 import android.util.Log; 22 import android.view.View; 23 import android.widget.RadioButton; 24 import android.widget.RadioGroup; 25 import android.widget.TextView; 26 27 import com.android.settings.R; 28 import com.android.settingslib.CustomDialogPreferenceCompat; 29 30 import java.util.ArrayList; 31 import java.util.List; 32 33 /** 34 * Abstract class for Bluetooth A2DP config preference in developer option. 35 */ 36 public abstract class BaseBluetoothDialogPreference extends CustomDialogPreferenceCompat implements 37 RadioGroup.OnCheckedChangeListener{ 38 private static final String TAG = "BaseBluetoothDlgPref"; 39 40 protected List<Integer> mRadioButtonIds = new ArrayList<>(); 41 protected List<String> mRadioButtonStrings = new ArrayList<>(); 42 protected List<String> mSummaryStrings = new ArrayList<>(); 43 44 private Callback mCallback; 45 BaseBluetoothDialogPreference(Context context)46 public BaseBluetoothDialogPreference(Context context) { 47 super(context); 48 } 49 BaseBluetoothDialogPreference(Context context, AttributeSet attrs)50 public BaseBluetoothDialogPreference(Context context, AttributeSet attrs) { 51 super(context, attrs); 52 } 53 BaseBluetoothDialogPreference(Context context, AttributeSet attrs, int defStyleAttr)54 public BaseBluetoothDialogPreference(Context context, AttributeSet attrs, int defStyleAttr) { 55 super(context, attrs, defStyleAttr); 56 } 57 BaseBluetoothDialogPreference(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes)58 public BaseBluetoothDialogPreference(Context context, AttributeSet attrs, int defStyleAttr, 59 int defStyleRes) { 60 super(context, attrs, defStyleAttr, defStyleRes); 61 } 62 63 @Override onBindDialogView(View view)64 protected void onBindDialogView(View view) { 65 super.onBindDialogView(view); 66 if (mCallback == null) { 67 Log.e(TAG, "Unable to show dialog by the callback is null"); 68 return; 69 } 70 if (mRadioButtonStrings.size() != mRadioButtonIds.size()) { 71 Log.e(TAG, "Unable to show dialog by the view and string size are not matched"); 72 return; 73 } 74 final int currentIndex = mCallback.getCurrentConfigIndex(); 75 if (currentIndex < 0 || currentIndex >= mRadioButtonIds.size()) { 76 Log.e(TAG, "Unable to show dialog by the incorrect index: " + currentIndex); 77 return; 78 } 79 // Initial radio button group 80 final RadioGroup radioGroup = view.findViewById(getRadioButtonGroupId()); 81 if (radioGroup == null) { 82 Log.e(TAG, "Unable to show dialog by no radio button group: " 83 + getRadioButtonGroupId()); 84 return; 85 } 86 radioGroup.check(mRadioButtonIds.get(currentIndex)); 87 radioGroup.setOnCheckedChangeListener(this); 88 // Initial radio button 89 final List<Integer> selectableIndex = mCallback.getSelectableIndex(); 90 RadioButton radioButton; 91 for (int i = 0; i < mRadioButtonStrings.size(); i++) { 92 radioButton = view.findViewById(mRadioButtonIds.get(i)); 93 if (radioButton == null) { 94 Log.e(TAG, "Unable to show dialog by no radio button:" + mRadioButtonIds.get(i)); 95 return; 96 } 97 radioButton.setText(mRadioButtonStrings.get(i)); 98 radioButton.setEnabled(selectableIndex.contains(i)); 99 } 100 // Initial help information text view 101 final TextView helpTextView = view.findViewById(R.id.bluetooth_audio_codec_help_info); 102 if (selectableIndex.size() == mRadioButtonIds.size()) { 103 // View will be invisible when all options are enabled. 104 helpTextView.setVisibility(View.GONE); 105 } else { 106 helpTextView.setText(R.string.bluetooth_select_a2dp_codec_type_help_info); 107 helpTextView.setVisibility(View.VISIBLE); 108 } 109 } 110 111 @Override onCheckedChanged(RadioGroup group, int checkedId)112 public void onCheckedChanged(RadioGroup group, int checkedId) { 113 if (mCallback == null) { 114 Log.e(TAG, "Callback is null"); 115 return; 116 } 117 mCallback.onIndexUpdated(mRadioButtonIds.indexOf(checkedId)); 118 getDialog().dismiss(); 119 } 120 121 /** 122 * Method to set callback. 123 */ setCallback(Callback callback)124 public void setCallback(Callback callback) { 125 mCallback = callback; 126 } 127 128 /** 129 * Method to get summary strings by index. 130 */ generateSummary(int index)131 protected String generateSummary(int index) { 132 if (index > mSummaryStrings.size()) { 133 Log.e(TAG, "Unable to get summary of " + index + ". Size is " + mSummaryStrings.size()); 134 return null; 135 } 136 return index == getDefaultIndex() ? mSummaryStrings.get(getDefaultIndex()) : 137 String.format(getContext().getResources().getString( 138 R.string.bluetooth_select_a2dp_codec_streaming_label), 139 mSummaryStrings.get(index)); 140 } 141 142 /** 143 * Method to get default index. 144 */ getDefaultIndex()145 protected int getDefaultIndex() { 146 return 0; 147 } 148 149 /** 150 * Method to get radio button group id. 151 */ getRadioButtonGroupId()152 protected abstract int getRadioButtonGroupId(); 153 154 /** 155 * Callback interface for this class to manipulate data from controller. 156 */ 157 public interface Callback { 158 /** 159 * Method to get current Bluetooth A2DP config index. 160 */ getCurrentConfigIndex()161 int getCurrentConfigIndex(); 162 /** 163 * Method to get selectable config index which means supported by phone and device. 164 * 165 * @return the available {@link List} of the Bluetooth A2DP config. 166 */ getSelectableIndex()167 List<Integer> getSelectableIndex(); 168 /** 169 * Method to notify controller when user changes config. 170 * 171 * @param index for the selected index. 172 */ onIndexUpdated(int index)173 void onIndexUpdated(int index); 174 } 175 } 176