1 /* 2 * Copyright (C) 2021 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.server.nearby.fastpair.cache; 18 19 import android.bluetooth.le.ScanResult; 20 import android.content.ContentValues; 21 import android.content.Context; 22 import android.database.Cursor; 23 import android.database.sqlite.SQLiteDatabase; 24 import android.util.Log; 25 26 import com.android.server.nearby.common.eventloop.Annotations; 27 28 import com.google.protobuf.InvalidProtocolBufferException; 29 30 import java.util.ArrayList; 31 import java.util.List; 32 33 import service.proto.Cache; 34 import service.proto.Rpcs; 35 36 37 /** 38 * Save FastPair device info to database to avoid multiple requesting. 39 */ 40 public class FastPairCacheManager { 41 private final Context mContext; 42 private final FastPairDbHelper mFastPairDbHelper; 43 FastPairCacheManager(Context context)44 public FastPairCacheManager(Context context) { 45 mContext = context; 46 mFastPairDbHelper = new FastPairDbHelper(context); 47 } 48 49 /** 50 * Clean up function to release db 51 */ cleanUp()52 public void cleanUp() { 53 mFastPairDbHelper.close(); 54 } 55 56 /** 57 * Saves the response to the db 58 */ saveDevice()59 private void saveDevice() { 60 } 61 getDeviceFromScanResult(ScanResult scanResult)62 Cache.ServerResponseDbItem getDeviceFromScanResult(ScanResult scanResult) { 63 return Cache.ServerResponseDbItem.newBuilder().build(); 64 } 65 66 /** 67 * Save discovery item into database. Discovery item is item that discovered through Ble before 68 * pairing success. 69 */ saveDiscoveryItem(DiscoveryItem item)70 public boolean saveDiscoveryItem(DiscoveryItem item) { 71 72 SQLiteDatabase db = mFastPairDbHelper.getWritableDatabase(); 73 ContentValues values = new ContentValues(); 74 values.put(DiscoveryItemContract.DiscoveryItemEntry.COLUMN_MODEL_ID, item.getTriggerId()); 75 values.put(DiscoveryItemContract.DiscoveryItemEntry.COLUMN_SCAN_BYTE, 76 item.getCopyOfStoredItem().toByteArray()); 77 db.insert(DiscoveryItemContract.DiscoveryItemEntry.TABLE_NAME, null, values); 78 return true; 79 } 80 81 82 @Annotations.EventThread getObservedDeviceInfo(ScanResult scanResult)83 private Rpcs.GetObservedDeviceResponse getObservedDeviceInfo(ScanResult scanResult) { 84 return Rpcs.GetObservedDeviceResponse.getDefaultInstance(); 85 } 86 87 /** 88 * Get discovery item from item id. 89 */ getDiscoveryItem(String itemId)90 public DiscoveryItem getDiscoveryItem(String itemId) { 91 return new DiscoveryItem(mContext, getStoredDiscoveryItem(itemId)); 92 } 93 94 /** 95 * Get discovery item from item id. 96 */ getStoredDiscoveryItem(String itemId)97 public Cache.StoredDiscoveryItem getStoredDiscoveryItem(String itemId) { 98 SQLiteDatabase db = mFastPairDbHelper.getReadableDatabase(); 99 String[] projection = { 100 DiscoveryItemContract.DiscoveryItemEntry.COLUMN_MODEL_ID, 101 DiscoveryItemContract.DiscoveryItemEntry.COLUMN_SCAN_BYTE 102 }; 103 String selection = DiscoveryItemContract.DiscoveryItemEntry.COLUMN_MODEL_ID + " =? "; 104 String[] selectionArgs = {itemId}; 105 Cursor cursor = db.query( 106 DiscoveryItemContract.DiscoveryItemEntry.TABLE_NAME, 107 projection, 108 selection, 109 selectionArgs, 110 null, 111 null, 112 null 113 ); 114 115 if (cursor.moveToNext()) { 116 byte[] res = cursor.getBlob(cursor.getColumnIndexOrThrow( 117 DiscoveryItemContract.DiscoveryItemEntry.COLUMN_SCAN_BYTE)); 118 try { 119 Cache.StoredDiscoveryItem item = Cache.StoredDiscoveryItem.parseFrom(res); 120 return item; 121 } catch (InvalidProtocolBufferException e) { 122 Log.e("FastPairCacheManager", "storediscovery has error"); 123 } 124 } 125 cursor.close(); 126 return Cache.StoredDiscoveryItem.getDefaultInstance(); 127 } 128 129 /** 130 * Get all of the discovery item related info in the cache. 131 */ getAllSavedStoreDiscoveryItem()132 public List<Cache.StoredDiscoveryItem> getAllSavedStoreDiscoveryItem() { 133 List<Cache.StoredDiscoveryItem> storedDiscoveryItemList = new ArrayList<>(); 134 SQLiteDatabase db = mFastPairDbHelper.getReadableDatabase(); 135 String[] projection = { 136 DiscoveryItemContract.DiscoveryItemEntry.COLUMN_MODEL_ID, 137 DiscoveryItemContract.DiscoveryItemEntry.COLUMN_SCAN_BYTE 138 }; 139 Cursor cursor = db.query( 140 DiscoveryItemContract.DiscoveryItemEntry.TABLE_NAME, 141 projection, 142 null, 143 null, 144 null, 145 null, 146 null 147 ); 148 149 while (cursor.moveToNext()) { 150 byte[] res = cursor.getBlob(cursor.getColumnIndexOrThrow( 151 DiscoveryItemContract.DiscoveryItemEntry.COLUMN_SCAN_BYTE)); 152 try { 153 Cache.StoredDiscoveryItem item = Cache.StoredDiscoveryItem.parseFrom(res); 154 storedDiscoveryItemList.add(item); 155 } catch (InvalidProtocolBufferException e) { 156 Log.e("FastPairCacheManager", "storediscovery has error"); 157 } 158 159 } 160 cursor.close(); 161 return storedDiscoveryItemList; 162 } 163 164 /** 165 * Get scan result from local database use model id 166 */ getStoredScanResult(String modelId)167 public Cache.StoredScanResult getStoredScanResult(String modelId) { 168 return Cache.StoredScanResult.getDefaultInstance(); 169 } 170 171 /** 172 * Gets the paired Fast Pair item that paired to the phone through mac address. 173 */ getStoredFastPairItemFromMacAddress(String macAddress)174 public Cache.StoredFastPairItem getStoredFastPairItemFromMacAddress(String macAddress) { 175 SQLiteDatabase db = mFastPairDbHelper.getReadableDatabase(); 176 String[] projection = { 177 StoredFastPairItemContract.StoredFastPairItemEntry.COLUMN_ACCOUNT_KEY, 178 StoredFastPairItemContract.StoredFastPairItemEntry.COLUMN_MAC_ADDRESS, 179 StoredFastPairItemContract.StoredFastPairItemEntry.COLUMN_STORED_FAST_PAIR_BYTE 180 }; 181 String selection = 182 StoredFastPairItemContract.StoredFastPairItemEntry.COLUMN_MAC_ADDRESS + " =? "; 183 String[] selectionArgs = {macAddress}; 184 Cursor cursor = db.query( 185 StoredFastPairItemContract.StoredFastPairItemEntry.TABLE_NAME, 186 projection, 187 selection, 188 selectionArgs, 189 null, 190 null, 191 null 192 ); 193 194 if (cursor.moveToNext()) { 195 byte[] res = cursor.getBlob(cursor.getColumnIndexOrThrow( 196 StoredFastPairItemContract.StoredFastPairItemEntry 197 .COLUMN_STORED_FAST_PAIR_BYTE)); 198 try { 199 Cache.StoredFastPairItem item = Cache.StoredFastPairItem.parseFrom(res); 200 return item; 201 } catch (InvalidProtocolBufferException e) { 202 Log.e("FastPairCacheManager", "storediscovery has error"); 203 } 204 } 205 cursor.close(); 206 return Cache.StoredFastPairItem.getDefaultInstance(); 207 } 208 209 /** 210 * Save paired fast pair item into the database. 211 */ putStoredFastPairItem(Cache.StoredFastPairItem storedFastPairItem)212 public boolean putStoredFastPairItem(Cache.StoredFastPairItem storedFastPairItem) { 213 SQLiteDatabase db = mFastPairDbHelper.getWritableDatabase(); 214 ContentValues values = new ContentValues(); 215 values.put(StoredFastPairItemContract.StoredFastPairItemEntry.COLUMN_MAC_ADDRESS, 216 storedFastPairItem.getMacAddress()); 217 values.put(StoredFastPairItemContract.StoredFastPairItemEntry.COLUMN_ACCOUNT_KEY, 218 storedFastPairItem.getAccountKey().toString()); 219 values.put(StoredFastPairItemContract.StoredFastPairItemEntry.COLUMN_STORED_FAST_PAIR_BYTE, 220 storedFastPairItem.toByteArray()); 221 db.insert(StoredFastPairItemContract.StoredFastPairItemEntry.TABLE_NAME, null, values); 222 return true; 223 224 } 225 226 /** 227 * Removes certain storedFastPairItem so that it can update timely. 228 */ removeStoredFastPairItem(String macAddress)229 public void removeStoredFastPairItem(String macAddress) { 230 SQLiteDatabase db = mFastPairDbHelper.getWritableDatabase(); 231 int res = db.delete(StoredFastPairItemContract.StoredFastPairItemEntry.TABLE_NAME, 232 StoredFastPairItemContract.StoredFastPairItemEntry.COLUMN_MAC_ADDRESS + "=?", 233 new String[]{macAddress}); 234 235 } 236 237 /** 238 * Get all of the store fast pair item related info in the cache. 239 */ getAllSavedStoredFastPairItem()240 public List<Cache.StoredFastPairItem> getAllSavedStoredFastPairItem() { 241 List<Cache.StoredFastPairItem> storedFastPairItemList = new ArrayList<>(); 242 SQLiteDatabase db = mFastPairDbHelper.getReadableDatabase(); 243 String[] projection = { 244 StoredFastPairItemContract.StoredFastPairItemEntry.COLUMN_MAC_ADDRESS, 245 StoredFastPairItemContract.StoredFastPairItemEntry.COLUMN_ACCOUNT_KEY, 246 StoredFastPairItemContract.StoredFastPairItemEntry.COLUMN_STORED_FAST_PAIR_BYTE 247 }; 248 Cursor cursor = db.query( 249 StoredFastPairItemContract.StoredFastPairItemEntry.TABLE_NAME, 250 projection, 251 null, 252 null, 253 null, 254 null, 255 null 256 ); 257 258 while (cursor.moveToNext()) { 259 byte[] res = cursor.getBlob(cursor.getColumnIndexOrThrow(StoredFastPairItemContract 260 .StoredFastPairItemEntry.COLUMN_STORED_FAST_PAIR_BYTE)); 261 try { 262 Cache.StoredFastPairItem item = Cache.StoredFastPairItem.parseFrom(res); 263 storedFastPairItemList.add(item); 264 } catch (InvalidProtocolBufferException e) { 265 Log.e("FastPairCacheManager", "storediscovery has error"); 266 } 267 268 } 269 cursor.close(); 270 return storedFastPairItemList; 271 } 272 } 273