• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 android.nearby.fastpair.provider.bluetooth;
18 
19 import android.annotation.TargetApi;
20 import android.bluetooth.BluetoothGattCharacteristic;
21 import android.bluetooth.BluetoothGattService;
22 
23 import androidx.annotation.Nullable;
24 
25 import com.android.server.nearby.common.bluetooth.BluetoothConsts;
26 
27 import java.util.ArrayList;
28 import java.util.HashMap;
29 import java.util.List;
30 import java.util.Map;
31 import java.util.Map.Entry;
32 import java.util.UUID;
33 
34 /** Configuration of a GATT server. */
35 @TargetApi(18)
36 public class BluetoothGattServerConfig {
37     private final Map<UUID, ServiceConfig> mServiceConfigs = new HashMap<UUID, ServiceConfig>();
38 
39     @Nullable
40     private BluetoothGattServerHelper.Listener mServerlistener = null;
41 
addService(UUID uuid, ServiceConfig serviceConfig)42     public BluetoothGattServerConfig addService(UUID uuid, ServiceConfig serviceConfig) {
43         mServiceConfigs.put(uuid, serviceConfig);
44         return this;
45     }
46 
setServerConnectionListener( BluetoothGattServerHelper.Listener listener)47     public BluetoothGattServerConfig setServerConnectionListener(
48             BluetoothGattServerHelper.Listener listener) {
49         mServerlistener = listener;
50         return this;
51     }
52 
53     @Nullable
getServerListener()54     public BluetoothGattServerHelper.Listener getServerListener() {
55         return mServerlistener;
56     }
57 
58     /**
59      * Adds a service and a characteristic to indicate that the server has dynamic services.
60      * This is a workaround for b/21587710.
61      * TODO(lingjunl): remove them when b/21587710 is fixed.
62      */
addSelfDefinedDynamicService()63     public BluetoothGattServerConfig addSelfDefinedDynamicService() {
64         ServiceConfig serviceConfig = new ServiceConfig().addCharacteristic(
65                 new BluetoothGattServlet() {
66                     @Override
67                     public BluetoothGattCharacteristic getCharacteristic() {
68                         return new BluetoothGattCharacteristic(
69                                 BluetoothConsts.SERVICE_DYNAMIC_CHARACTERISTIC,
70                                 BluetoothGattCharacteristic.PROPERTY_READ,
71                                 BluetoothGattCharacteristic.PERMISSION_READ);
72                     }
73                 });
74         return addService(BluetoothConsts.SERVICE_DYNAMIC_SERVICE, serviceConfig);
75     }
76 
getBluetoothGattServices()77     public List<BluetoothGattService> getBluetoothGattServices() {
78         List<BluetoothGattService> result = new ArrayList<BluetoothGattService>();
79         for (Entry<UUID, ServiceConfig> serviceEntry : mServiceConfigs.entrySet()) {
80             UUID serviceUuid = serviceEntry.getKey();
81             ServiceConfig serviceConfig = serviceEntry.getValue();
82             if (serviceUuid == null || serviceConfig == null) {
83                 // This is not supposed to happen
84                 throw new IllegalStateException();
85             }
86             BluetoothGattService gattService = new BluetoothGattService(serviceUuid,
87                     BluetoothGattService.SERVICE_TYPE_PRIMARY);
88             for (Entry<BluetoothGattCharacteristic, BluetoothGattServlet> servletEntry :
89                     serviceConfig.getServlets().entrySet()) {
90                 BluetoothGattCharacteristic characteristic = servletEntry.getKey();
91                 if (characteristic == null) {
92                     // This is not supposed to happen
93                     throw new IllegalStateException();
94                 }
95                 gattService.addCharacteristic(characteristic);
96             }
97             result.add(gattService);
98         }
99         return result;
100     }
101 
getAdvertisedUuids()102     public List<UUID> getAdvertisedUuids() {
103         List<UUID> result = new ArrayList<UUID>();
104         for (Entry<UUID, ServiceConfig> serviceEntry : mServiceConfigs.entrySet()) {
105             UUID serviceUuid = serviceEntry.getKey();
106             ServiceConfig serviceConfig = serviceEntry.getValue();
107             if (serviceUuid == null || serviceConfig == null) {
108                 // This is not supposed to happen
109                 throw new IllegalStateException();
110             }
111             if (serviceConfig.isAdvertised()) {
112                 result.add(serviceUuid);
113             }
114         }
115         return result;
116     }
117 
getServlets()118     public Map<BluetoothGattCharacteristic, BluetoothGattServlet> getServlets() {
119         Map<BluetoothGattCharacteristic, BluetoothGattServlet> result =
120                 new HashMap<BluetoothGattCharacteristic, BluetoothGattServlet>();
121         for (ServiceConfig serviceConfig : mServiceConfigs.values()) {
122             result.putAll(serviceConfig.getServlets());
123         }
124         return result;
125     }
126 
127     /** Configuration of a GATT service. */
128     public static class ServiceConfig {
129         private final Map<BluetoothGattCharacteristic, BluetoothGattServlet> mServlets =
130                 new HashMap<BluetoothGattCharacteristic, BluetoothGattServlet>();
131         private boolean mAdvertise = false;
132 
addCharacteristic(BluetoothGattServlet servlet)133         public ServiceConfig addCharacteristic(BluetoothGattServlet servlet) {
134             mServlets.put(servlet.getCharacteristic(), servlet);
135             return this;
136         }
137 
setAdvertise(boolean advertise)138         public ServiceConfig setAdvertise(boolean advertise) {
139             mAdvertise = advertise;
140             return this;
141         }
142 
getServlets()143         public Map<BluetoothGattCharacteristic, BluetoothGattServlet> getServlets() {
144             return mServlets;
145         }
146 
isAdvertised()147         public boolean isAdvertised() {
148             return mAdvertise;
149         }
150     }
151 }
152