• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2018 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.car;
18 
19 import android.bluetooth.BluetoothAdapter;
20 import android.bluetooth.BluetoothManager;
21 
22 import android.bluetooth.le.AdvertiseCallback;
23 import android.bluetooth.le.AdvertiseData;
24 import android.bluetooth.le.AdvertiseSettings;
25 import android.bluetooth.le.BluetoothLeAdvertiser;
26 import android.content.Context;
27 import android.content.res.Resources;
28 import android.os.ParcelUuid;
29 import android.util.Log;
30 
31 import java.nio.ByteBuffer;
32 import java.nio.ByteOrder;
33 import java.util.Arrays;
34 
35 /**
36  * An advertiser for the Bluetooth LE based Fast Pair service.
37  * FastPairProvider enables easy Bluetooth pairing between a peripheral and a phone participating in
38  * the Fast Pair Seeker role.  When the seeker finds a compatible peripheral a notification prompts
39  * the user to begin pairing if desired.  A peripheral should call startAdvertising when it is
40  * appropriate to pair, and stopAdvertising when pairing is complete or it is no longer appropriate
41  * to pair.
42  */
43 class FastPairProvider {
44 
45     private static final String TAG = "FastPairProvider";
46     private static final boolean DBG = Utils.DBG;
47 
48     // Service ID assigned for FastPair.
49     private static final ParcelUuid FastPairServiceUuid = ParcelUuid
50             .fromString("0000FE2C-0000-1000-8000-00805f9b34fb");
51 
52     private AdvertiseSettings mSettings;
53     private AdvertiseData mData;
54     private BluetoothLeAdvertiser mBluetoothLeAdvertiser;
55     private AdvertiseCallback mAdvertiseCallback;
56 
57 
FastPairProvider(Context context)58     FastPairProvider(Context context) {
59         Resources res = context.getResources();
60         int modelId = res.getInteger(R.integer.fastPairModelId);
61         if (modelId == 0) {
62             Log.w(TAG, "Model ID undefined, disabling");
63             return;
64         }
65 
66         BluetoothManager bluetoothManager = (BluetoothManager) context.getSystemService(
67                 Context.BLUETOOTH_SERVICE);
68         if (bluetoothManager != null) {
69             BluetoothAdapter bluetoothAdapter = bluetoothManager.getAdapter();
70             if (bluetoothAdapter != null) {
71                 mBluetoothLeAdvertiser = bluetoothAdapter.getBluetoothLeAdvertiser();
72             }
73         }
74 
75         AdvertiseSettings.Builder settingsBuilder = new AdvertiseSettings.Builder();
76         settingsBuilder.setAdvertiseMode(AdvertiseSettings.ADVERTISE_MODE_LOW_LATENCY);
77         settingsBuilder.setTxPowerLevel(AdvertiseSettings.ADVERTISE_TX_POWER_HIGH);
78         settingsBuilder.setConnectable(true);
79         settingsBuilder.setTimeout(0);
80         mSettings = settingsBuilder.build();
81 
82         AdvertiseData.Builder dataBuilder = new AdvertiseData.Builder();
83         ByteBuffer modelIdBytes = ByteBuffer.allocate(4).order(ByteOrder.LITTLE_ENDIAN).putInt(
84                 modelId);
85         byte[] fastPairServiceData = Arrays.copyOfRange(modelIdBytes.array(), 0, 3);
86         dataBuilder.addServiceData(FastPairServiceUuid, fastPairServiceData);
87         dataBuilder.setIncludeTxPowerLevel(true).build();
88         mData = dataBuilder.build();
89 
90         mAdvertiseCallback = new FastPairAdvertiseCallback();
91     }
92 
93     /* register the BLE advertisement using the model id provided during construction */
startAdvertising()94     boolean startAdvertising() {
95         if (mBluetoothLeAdvertiser != null) {
96             mBluetoothLeAdvertiser.startAdvertising(mSettings, mData, mAdvertiseCallback);
97             return true;
98         }
99         return false;
100     }
101 
102     /* unregister the BLE advertisement. */
stopAdvertising()103     boolean stopAdvertising() {
104         if (mBluetoothLeAdvertiser != null) {
105             mBluetoothLeAdvertiser.stopAdvertising(mAdvertiseCallback);
106             return true;
107         }
108         return false;
109     }
110 
111     /* Callback to handle status when advertising starts. */
112     private class FastPairAdvertiseCallback extends AdvertiseCallback {
113         @Override
onStartFailure(int errorCode)114         public void onStartFailure(int errorCode) {
115             super.onStartFailure(errorCode);
116             if (DBG) Log.d(TAG, "Advertising failed");
117         }
118 
119         @Override
onStartSuccess(AdvertiseSettings settingsInEffect)120         public void onStartSuccess(AdvertiseSettings settingsInEffect) {
121             super.onStartSuccess(settingsInEffect);
122             if (DBG) Log.d(TAG, "Advertising successfully started");
123         }
124     }
125 }
126