1 /*
2  * Copyright (C) 2022 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.bluetooth;
18 
19 
20 import android.accessibilityservice.AccessibilityServiceInfo;
21 import android.accessibilityservice.AccessibilityShortcutInfo;
22 import android.content.ComponentName;
23 import android.content.Context;
24 import android.os.UserHandle;
25 import android.view.accessibility.AccessibilityManager;
26 
27 import androidx.annotation.NonNull;
28 import androidx.preference.Preference;
29 import androidx.preference.PreferenceCategory;
30 import androidx.preference.PreferenceFragmentCompat;
31 import androidx.preference.PreferenceScreen;
32 
33 import com.android.net.module.util.CollectionUtils;
34 import com.android.settings.accessibility.RestrictedPreferenceHelper;
35 import com.android.settings.overlay.FeatureFactory;
36 import com.android.settingslib.RestrictedPreference;
37 import com.android.settingslib.bluetooth.CachedBluetoothDevice;
38 import com.android.settingslib.core.lifecycle.Lifecycle;
39 
40 import java.util.Collection;
41 import java.util.List;
42 import java.util.stream.Collectors;
43 import java.util.stream.Stream;
44 
45 /**
46  * This class adds related tools preference.
47  */
48 public class BluetoothDetailsRelatedToolsController extends BluetoothDetailsController{
49     private static final String KEY_RELATED_TOOLS_GROUP = "bluetooth_related_tools";
50     private static final String KEY_LIVE_CAPTION = "live_caption";
51     private static final int ORDINAL = 99;
52 
53     private PreferenceCategory mPreferenceCategory;
54 
BluetoothDetailsRelatedToolsController(Context context, PreferenceFragmentCompat fragment, CachedBluetoothDevice device, Lifecycle lifecycle)55     public BluetoothDetailsRelatedToolsController(Context context,
56             PreferenceFragmentCompat fragment, CachedBluetoothDevice device, Lifecycle lifecycle) {
57         super(context, fragment, device, lifecycle);
58         lifecycle.addObserver(this);
59     }
60 
61     @Override
isAvailable()62     public boolean isAvailable() {
63         return mCachedDevice.isHearingAidDevice();
64     }
65 
66     @Override
init(PreferenceScreen screen)67     protected void init(PreferenceScreen screen) {
68         if (!mCachedDevice.isHearingAidDevice()) {
69             return;
70         }
71 
72         mPreferenceCategory = screen.findPreference(getPreferenceKey());
73         final Preference liveCaptionPreference = screen.findPreference(KEY_LIVE_CAPTION);
74         if (!liveCaptionPreference.isVisible()) {
75             mPreferenceCategory.removePreference(liveCaptionPreference);
76         }
77 
78         final List<ComponentName> relatedToolsList =
79                 FeatureFactory.getFeatureFactory().getBluetoothFeatureProvider().getRelatedTools();
80         if (!CollectionUtils.isEmpty(relatedToolsList)) {
81             addAccessibilityInstalledRelatedPreference(relatedToolsList);
82         }
83 
84         if (mPreferenceCategory.getPreferenceCount() == 0) {
85             screen.removePreference(mPreferenceCategory);
86         }
87     }
88 
89     @Override
refresh()90     protected void refresh() {}
91 
92     @Override
getPreferenceKey()93     public String getPreferenceKey() {
94         return KEY_RELATED_TOOLS_GROUP;
95     }
96 
addAccessibilityInstalledRelatedPreference( @onNull List<ComponentName> componentNameList)97     private void addAccessibilityInstalledRelatedPreference(
98             @NonNull List<ComponentName> componentNameList) {
99         final AccessibilityManager a11yManager = AccessibilityManager.getInstance(mContext);
100         final RestrictedPreferenceHelper preferenceHelper = new RestrictedPreferenceHelper(
101                 mContext);
102 
103         final List<AccessibilityServiceInfo> a11yServiceInfoList =
104                 a11yManager.getInstalledAccessibilityServiceList().stream()
105                         .filter(info -> componentNameList.contains(info.getComponentName()))
106                         .collect(Collectors.toList());
107         final List<AccessibilityShortcutInfo> a11yShortcutInfoList =
108                 a11yManager.getInstalledAccessibilityShortcutListAsUser(mContext,
109                         UserHandle.myUserId()).stream()
110                         .filter(info -> componentNameList.contains(info.getComponentName()))
111                         .collect(Collectors.toList());
112 
113         final List<RestrictedPreference> preferences = Stream.of(
114                 preferenceHelper.createAccessibilityServicePreferenceList(a11yServiceInfoList),
115                 preferenceHelper.createAccessibilityActivityPreferenceList(a11yShortcutInfoList))
116                 .flatMap(Collection::stream)
117                 .collect(Collectors.toList());
118 
119         for (RestrictedPreference preference : preferences) {
120             preference.setOrder(ORDINAL);
121             mPreferenceCategory.addPreference(preference);
122         }
123     }
124 }
125