1 /* 2 * Copyright (C) 2023 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.accessibility; 18 19 import android.content.Context; 20 import android.util.Log; 21 22 import androidx.annotation.VisibleForTesting; 23 import androidx.preference.Preference; 24 import androidx.preference.PreferenceScreen; 25 26 import com.android.settings.R; 27 import com.android.settings.bluetooth.BluetoothDeviceUpdater; 28 import com.android.settings.bluetooth.Utils; 29 import com.android.settings.connecteddevice.DevicePreferenceCallback; 30 import com.android.settings.dashboard.DashboardFragment; 31 import com.android.settingslib.bluetooth.CachedBluetoothDevice; 32 import com.android.settingslib.bluetooth.LocalBluetoothManager; 33 import com.android.settingslib.core.lifecycle.LifecycleObserver; 34 import com.android.settingslib.core.lifecycle.events.OnResume; 35 import com.android.settingslib.core.lifecycle.events.OnStart; 36 import com.android.settingslib.core.lifecycle.events.OnStop; 37 import com.android.settingslib.search.SearchIndexableRaw; 38 39 import java.util.List; 40 41 /** 42 * Controller to update the {@link androidx.preference.PreferenceCategory} for all 43 * saved ((bonded but not connected)) hearing devices, including ASHA and HAP profile. 44 * Parent class {@link BaseBluetoothDevicePreferenceController} will use 45 * {@link DevicePreferenceCallback} to add/remove {@link Preference}. 46 */ 47 public class SavedHearingDevicePreferenceController extends 48 BaseBluetoothDevicePreferenceController implements LifecycleObserver, OnStart, OnResume, 49 OnStop { 50 51 private static final String TAG = "SavedHearingDevicePreferenceController"; 52 private static final String SEARCH_DATA_KEY_PREFIX = "a11y_saved_hearing_device"; 53 private BluetoothDeviceUpdater mSavedHearingDeviceUpdater; 54 private final LocalBluetoothManager mLocalBluetoothManager; 55 SavedHearingDevicePreferenceController(Context context, String preferenceKey)56 public SavedHearingDevicePreferenceController(Context context, 57 String preferenceKey) { 58 super(context, preferenceKey); 59 mLocalBluetoothManager = Utils.getLocalBluetoothManager(context); 60 } 61 62 @VisibleForTesting init(SavedHearingDeviceUpdater savedHearingDeviceUpdater)63 void init(SavedHearingDeviceUpdater savedHearingDeviceUpdater) { 64 if (mSavedHearingDeviceUpdater != null) { 65 throw new IllegalStateException("Should not call init() more than 1 time."); 66 } 67 mSavedHearingDeviceUpdater = savedHearingDeviceUpdater; 68 } 69 70 /** 71 * Initializes objects in this controller. Need to call this before onStart(). 72 * 73 * <p>Should not call this more than 1 time. 74 * 75 * @param fragment The {@link DashboardFragment} uses the controller. 76 */ init(DashboardFragment fragment)77 public void init(DashboardFragment fragment) { 78 if (mSavedHearingDeviceUpdater != null) { 79 throw new IllegalStateException("Should not call init() more than 1 time."); 80 } 81 mSavedHearingDeviceUpdater = new SavedHearingDeviceUpdater(fragment.getContext(), this, 82 fragment.getMetricsCategory()); 83 } 84 85 @Override onStart()86 public void onStart() { 87 mSavedHearingDeviceUpdater.registerCallback(); 88 } 89 90 @Override onResume()91 public void onResume() { 92 mSavedHearingDeviceUpdater.refreshPreference(); 93 } 94 95 @Override onStop()96 public void onStop() { 97 mSavedHearingDeviceUpdater.unregisterCallback(); 98 } 99 100 @Override displayPreference(PreferenceScreen screen)101 public void displayPreference(PreferenceScreen screen) { 102 super.displayPreference(screen); 103 104 if (isAvailable()) { 105 final Context context = screen.getContext(); 106 mSavedHearingDeviceUpdater.setPrefContext(context); 107 mSavedHearingDeviceUpdater.forceUpdate(); 108 } 109 } 110 111 @Override updateDynamicRawDataToIndex(List<SearchIndexableRaw> rawData)112 public void updateDynamicRawDataToIndex(List<SearchIndexableRaw> rawData) { 113 if (Flags.fixA11ySettingsSearch()) { 114 if (mLocalBluetoothManager == null) { 115 Log.d(TAG, "Bluetooth is not supported"); 116 return; 117 } 118 119 for (CachedBluetoothDevice cachedDevice : 120 mLocalBluetoothManager.getCachedDeviceManager().getCachedDevicesCopy()) { 121 122 if (!SavedHearingDeviceUpdater.isSavedHearingAidDevice(cachedDevice)) { 123 continue; 124 } 125 126 SearchIndexableRaw data = new SearchIndexableRaw(mContext); 127 // Include the identity address and add prefix to ensure the key is unique and 128 // distinguish from Bluetooth's connected devices. 129 data.key = SEARCH_DATA_KEY_PREFIX 130 + cachedDevice.getName() + cachedDevice.getIdentityAddress(); 131 data.title = cachedDevice.getName(); 132 data.summaryOn = mContext.getString(R.string.accessibility_hearingaid_title); 133 data.screenTitle = mContext.getString(R.string.accessibility_hearingaid_title); 134 rawData.add(data); 135 } 136 } else { 137 super.updateDynamicRawDataToIndex(rawData); 138 } 139 } 140 } 141