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 java.util.ArrayList; 20 import java.util.Arrays; 21 import java.util.List; 22 23 import android.bluetooth.BluetoothProfile; 24 import android.content.ContentResolver; 25 import android.content.Context; 26 import android.content.res.Resources; 27 import android.os.SystemProperties; 28 import android.provider.Settings; 29 import android.util.Log; 30 31 import com.android.bluetooth.R; 32 import com.android.bluetooth.a2dp.A2dpService; 33 import com.android.bluetooth.a2dpsink.A2dpSinkService; 34 import com.android.bluetooth.avrcp.AvrcpControllerService; 35 import com.android.bluetooth.hdp.HealthService; 36 import com.android.bluetooth.hfp.HeadsetService; 37 import com.android.bluetooth.hfpclient.HeadsetClientService; 38 import com.android.bluetooth.hid.HidService; 39 import com.android.bluetooth.pan.PanService; 40 import com.android.bluetooth.gatt.GattService; 41 import com.android.bluetooth.map.BluetoothMapService; 42 import com.android.bluetooth.sap.SapService; 43 import com.android.bluetooth.pbapclient.PbapClientService; 44 45 public class Config { 46 private static final String TAG = "AdapterServiceConfig"; 47 /** 48 * List of profile services. 49 */ 50 @SuppressWarnings("rawtypes") 51 //Do not inclue OPP and PBAP, because their services 52 //are not managed by AdapterService 53 private static final Class[] PROFILE_SERVICES = { 54 HeadsetService.class, 55 A2dpService.class, 56 A2dpSinkService.class, 57 HidService.class, 58 HealthService.class, 59 PanService.class, 60 GattService.class, 61 BluetoothMapService.class, 62 HeadsetClientService.class, 63 AvrcpControllerService.class, 64 SapService.class, 65 PbapClientService.class 66 }; 67 /** 68 * Resource flag to indicate whether profile is supported or not. 69 */ 70 private static final int[] PROFILE_SERVICES_FLAG = { 71 R.bool.profile_supported_hs_hfp, 72 R.bool.profile_supported_a2dp, 73 R.bool.profile_supported_a2dp_sink, 74 R.bool.profile_supported_hid, 75 R.bool.profile_supported_hdp, 76 R.bool.profile_supported_pan, 77 R.bool.profile_supported_gatt, 78 R.bool.profile_supported_map, 79 R.bool.profile_supported_hfpclient, 80 R.bool.profile_supported_avrcp_controller, 81 R.bool.profile_supported_sap, 82 R.bool.profile_supported_pbapclient 83 }; 84 85 private static Class[] SUPPORTED_PROFILES = new Class[0]; 86 87 static void init(Context ctx) { 88 if (ctx == null) { 89 return; 90 } 91 Resources resources = ctx.getResources(); 92 if (resources == null) { 93 return; 94 } 95 96 ArrayList<Class> profiles = new ArrayList<Class>(PROFILE_SERVICES.length); 97 for (int i=0; i < PROFILE_SERVICES_FLAG.length; i++) { 98 boolean supported = resources.getBoolean(PROFILE_SERVICES_FLAG[i]); 99 if (supported && !isProfileDisabled(ctx, PROFILE_SERVICES[i])) { 100 Log.d(TAG, "Adding " + PROFILE_SERVICES[i].getSimpleName()); 101 profiles.add(PROFILE_SERVICES[i]); 102 } 103 } 104 int totalProfiles = profiles.size(); 105 SUPPORTED_PROFILES = new Class[totalProfiles]; 106 profiles.toArray(SUPPORTED_PROFILES); 107 } 108 109 static Class[] getSupportedProfiles() { 110 return SUPPORTED_PROFILES; 111 } 112 113 private static boolean isProfileDisabled(Context context, Class profile) { 114 int profileIndex = -1; 115 116 if (profile == HeadsetService.class) { 117 profileIndex = BluetoothProfile.HEADSET; 118 } else if (profile == A2dpService.class) { 119 profileIndex = BluetoothProfile.A2DP; 120 } else if (profile == A2dpSinkService.class) { 121 profileIndex = BluetoothProfile.A2DP_SINK; 122 } else if (profile == HidService.class) { 123 profileIndex = BluetoothProfile.INPUT_DEVICE; 124 } else if (profile == HealthService.class) { 125 profileIndex = BluetoothProfile.HEALTH; 126 } else if (profile == PanService.class) { 127 profileIndex = BluetoothProfile.PAN; 128 } else if (profile == GattService.class) { 129 profileIndex = BluetoothProfile.GATT; 130 } else if (profile == BluetoothMapService.class) { 131 profileIndex = BluetoothProfile.MAP; 132 } else if (profile == HeadsetClientService.class) { 133 profileIndex = BluetoothProfile.HEADSET_CLIENT; 134 } else if (profile == AvrcpControllerService.class) { 135 profileIndex = BluetoothProfile.AVRCP_CONTROLLER; 136 } else if (profile == SapService.class) { 137 profileIndex = BluetoothProfile.SAP; 138 } else if (profile == PbapClientService.class) { 139 profileIndex = BluetoothProfile.PBAP_CLIENT; 140 } 141 142 if (profileIndex == -1) { 143 Log.d(TAG, "Could not find profile bit mask"); 144 return false; 145 } 146 147 final ContentResolver resolver = context.getContentResolver(); 148 final long disabledProfilesBitMask = Settings.Global.getLong(resolver, 149 Settings.Global.BLUETOOTH_DISABLED_PROFILES, 0); 150 long profileBit = 1 << profileIndex; 151 152 return (disabledProfilesBitMask & profileBit) != 0; 153 } 154 } 155