• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2012 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.bluetooth.btservice;
18 
19 import android.bluetooth.BluetoothProfile;
20 import android.content.ContentResolver;
21 import android.content.Context;
22 import android.content.res.Resources;
23 import android.provider.Settings;
24 import android.util.FeatureFlagUtils;
25 import android.util.Log;
26 
27 import com.android.bluetooth.R;
28 import com.android.bluetooth.a2dp.A2dpService;
29 import com.android.bluetooth.a2dpsink.A2dpSinkService;
30 import com.android.bluetooth.avrcp.AvrcpTargetService;
31 import com.android.bluetooth.avrcpcontroller.AvrcpControllerService;
32 import com.android.bluetooth.gatt.GattService;
33 import com.android.bluetooth.hearingaid.HearingAidService;
34 import com.android.bluetooth.hfp.HeadsetService;
35 import com.android.bluetooth.hfpclient.HeadsetClientService;
36 import com.android.bluetooth.hid.HidDeviceService;
37 import com.android.bluetooth.hid.HidHostService;
38 import com.android.bluetooth.map.BluetoothMapService;
39 import com.android.bluetooth.mapclient.MapClientService;
40 import com.android.bluetooth.opp.BluetoothOppService;
41 import com.android.bluetooth.pan.PanService;
42 import com.android.bluetooth.pbap.BluetoothPbapService;
43 import com.android.bluetooth.pbapclient.PbapClientService;
44 import com.android.bluetooth.sap.SapService;
45 
46 import java.util.ArrayList;
47 
48 public class Config {
49     private static final String TAG = "AdapterServiceConfig";
50 
51     private static class ProfileConfig {
52         Class mClass;
53         int mSupported;
54         long mMask;
55 
ProfileConfig(Class theClass, int supportedFlag, long mask)56         ProfileConfig(Class theClass, int supportedFlag, long mask) {
57             mClass = theClass;
58             mSupported = supportedFlag;
59             mMask = mask;
60         }
61     }
62 
63     /**
64      * List of profile services with the profile-supported resource flag and bit mask.
65      */
66     private static final ProfileConfig[] PROFILE_SERVICES_AND_FLAGS = {
67             new ProfileConfig(HeadsetService.class, R.bool.profile_supported_hs_hfp,
68                     (1 << BluetoothProfile.HEADSET)),
69             new ProfileConfig(A2dpService.class, R.bool.profile_supported_a2dp,
70                     (1 << BluetoothProfile.A2DP)),
71             new ProfileConfig(A2dpSinkService.class, R.bool.profile_supported_a2dp_sink,
72                     (1 << BluetoothProfile.A2DP_SINK)),
73             new ProfileConfig(HidHostService.class, R.bool.profile_supported_hid_host,
74                     (1 << BluetoothProfile.HID_HOST)),
75             new ProfileConfig(PanService.class, R.bool.profile_supported_pan,
76                     (1 << BluetoothProfile.PAN)),
77             new ProfileConfig(GattService.class, R.bool.profile_supported_gatt,
78                     (1 << BluetoothProfile.GATT)),
79             new ProfileConfig(BluetoothMapService.class, R.bool.profile_supported_map,
80                     (1 << BluetoothProfile.MAP)),
81             new ProfileConfig(HeadsetClientService.class, R.bool.profile_supported_hfpclient,
82                     (1 << BluetoothProfile.HEADSET_CLIENT)),
83             new ProfileConfig(AvrcpTargetService.class, R.bool.profile_supported_avrcp_target,
84                     (1 << BluetoothProfile.AVRCP)),
85             new ProfileConfig(AvrcpControllerService.class,
86                     R.bool.profile_supported_avrcp_controller,
87                     (1 << BluetoothProfile.AVRCP_CONTROLLER)),
88             new ProfileConfig(SapService.class, R.bool.profile_supported_sap,
89                     (1 << BluetoothProfile.SAP)),
90             new ProfileConfig(PbapClientService.class, R.bool.profile_supported_pbapclient,
91                     (1 << BluetoothProfile.PBAP_CLIENT)),
92             new ProfileConfig(MapClientService.class, R.bool.profile_supported_mapmce,
93                     (1 << BluetoothProfile.MAP_CLIENT)),
94             new ProfileConfig(HidDeviceService.class, R.bool.profile_supported_hid_device,
95                     (1 << BluetoothProfile.HID_DEVICE)),
96             new ProfileConfig(BluetoothOppService.class, R.bool.profile_supported_opp,
97                     (1 << BluetoothProfile.OPP)),
98             new ProfileConfig(BluetoothPbapService.class, R.bool.profile_supported_pbap,
99                     (1 << BluetoothProfile.PBAP)),
100             new ProfileConfig(HearingAidService.class,
101                     com.android.internal.R.bool.config_hearing_aid_profile_supported,
102                     (1 << BluetoothProfile.HEARING_AID))
103     };
104 
105     private static Class[] sSupportedProfiles = new Class[0];
106 
init(Context ctx)107     static void init(Context ctx) {
108         if (ctx == null) {
109             return;
110         }
111         Resources resources = ctx.getResources();
112         if (resources == null) {
113             return;
114         }
115 
116         ArrayList<Class> profiles = new ArrayList<>(PROFILE_SERVICES_AND_FLAGS.length);
117         for (ProfileConfig config : PROFILE_SERVICES_AND_FLAGS) {
118             boolean supported = resources.getBoolean(config.mSupported);
119 
120             if (!supported && (config.mClass == HearingAidService.class) && FeatureFlagUtils
121                                 .isEnabled(ctx, FeatureFlagUtils.HEARING_AID_SETTINGS)) {
122                 Log.v(TAG, "Feature Flag enables support for HearingAidService");
123                 supported = true;
124             }
125 
126             if (supported && !isProfileDisabled(ctx, config.mMask)) {
127                 Log.v(TAG, "Adding " + config.mClass.getSimpleName());
128                 profiles.add(config.mClass);
129             }
130             sSupportedProfiles = profiles.toArray(new Class[profiles.size()]);
131         }
132     }
133 
getSupportedProfiles()134     static Class[] getSupportedProfiles() {
135         return sSupportedProfiles;
136     }
137 
getProfileMask(Class profile)138     private static long getProfileMask(Class profile) {
139         for (ProfileConfig config : PROFILE_SERVICES_AND_FLAGS) {
140             if (config.mClass == profile) {
141                 return config.mMask;
142             }
143         }
144         Log.w(TAG, "Could not find profile bit mask for " + profile.getSimpleName());
145         return 0;
146     }
147 
getSupportedProfilesBitMask()148     static long getSupportedProfilesBitMask() {
149         long mask = 0;
150         for (final Class profileClass : getSupportedProfiles()) {
151             mask |= getProfileMask(profileClass);
152         }
153         return mask;
154     }
155 
isProfileDisabled(Context context, long profileMask)156     private static boolean isProfileDisabled(Context context, long profileMask) {
157         final ContentResolver resolver = context.getContentResolver();
158         final long disabledProfilesBitMask =
159                 Settings.Global.getLong(resolver, Settings.Global.BLUETOOTH_DISABLED_PROFILES, 0);
160 
161         return (disabledProfilesBitMask & profileMask) != 0;
162     }
163 }
164