ContextMap.java revision 7a068c2a0861e12a3916cec313cf105395871999
103b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta/* 203b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta * Copyright (C) 2013 The Android Open Source Project 303b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta * 403b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta * Licensed under the Apache License, Version 2.0 (the "License"); 503b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta * you may not use this file except in compliance with the License. 603b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta * You may obtain a copy of the License at 703b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta * 803b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta * http://www.apache.org/licenses/LICENSE-2.0 903b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta * 1003b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta * Unless required by applicable law or agreed to in writing, software 1103b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta * distributed under the License is distributed on an "AS IS" BASIS, 1203b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1303b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta * See the License for the specific language governing permissions and 1403b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta * limitations under the License. 1503b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta */ 166af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbachpackage com.android.bluetooth.gatt; 1703b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta 188a0bc0a61e97f8923cb362e1dbb7ff66ffe51507Ajay Panickerimport android.content.Context; 198a0bc0a61e97f8923cb362e1dbb7ff66ffe51507Ajay Panickerimport android.os.Binder; 206af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbachimport android.os.IBinder; 216af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbachimport android.os.IBinder.DeathRecipient; 226af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbachimport android.os.IInterface; 236af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbachimport android.os.RemoteException; 2403b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Battaimport android.util.Log; 2503b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Battaimport java.util.ArrayList; 266af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbachimport java.util.HashSet; 2703b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Battaimport java.util.Iterator; 2803b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Battaimport java.util.List; 296af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbachimport java.util.NoSuchElementException; 3003b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Battaimport java.util.Set; 3103b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Battaimport java.util.UUID; 32f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Aroraimport java.util.HashMap; 33f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Aroraimport java.util.Map; 3403b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta 353122e5171ef26ff487f10826786606df848ca25eAjay Panickerimport com.android.bluetooth.btservice.BluetoothProto; 3603b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta/** 3703b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta * Helper class that keeps track of registered GATT applications. 3803b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta * This class manages application callbacks and keeps track of GATT connections. 3903b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta * @hide 4003b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta */ 4103b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta/*package*/ class ContextMap<T> { 4203b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta private static final String TAG = GattServiceConfig.TAG_PREFIX + "ContextMap"; 433122e5171ef26ff487f10826786606df848ca25eAjay Panicker static final int NUM_SCAN_EVENTS_KEPT = 20; 448a0bc0a61e97f8923cb362e1dbb7ff66ffe51507Ajay Panicker 458a0bc0a61e97f8923cb362e1dbb7ff66ffe51507Ajay Panicker /** 4603b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta * Connection class helps map connection IDs to device addresses. 4703b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta */ 4803b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta class Connection { 4903b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta int connId; 5003b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta String address; 5103b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta int appId; 52337ee9418b0122e6a89ff38cd49f031ba80aa24cAjay Panicker long startTime; 5303b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta 5403b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta Connection(int connId, String address,int appId) { 5503b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta this.connId = connId; 5603b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta this.address = address; 5703b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta this.appId = appId; 58337ee9418b0122e6a89ff38cd49f031ba80aa24cAjay Panicker this.startTime = System.currentTimeMillis(); 5903b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta } 6003b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta } 6103b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta 6203b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta /** 6303b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta * Application entry mapping UUIDs to appIDs and callbacks. 6403b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta */ 6503b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta class App { 6603b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta /** The UUID of the application */ 6703b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta UUID uuid; 6803b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta 6903b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta /** The id of the application */ 7003b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta int id; 7103b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta 728a0bc0a61e97f8923cb362e1dbb7ff66ffe51507Ajay Panicker /** The package name of the application */ 738a0bc0a61e97f8923cb362e1dbb7ff66ffe51507Ajay Panicker String name; 748a0bc0a61e97f8923cb362e1dbb7ff66ffe51507Ajay Panicker 7503b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta /** Application callbacks */ 7603b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta T callback; 7703b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta 786af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach /** Death receipient */ 796af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach private IBinder.DeathRecipient mDeathRecipient; 806af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach 81934dee789c0c68607a704c5c31ae2e4b956dc227Prerepa Viswanadham /** Flag to signal that transport is congested */ 82934dee789c0c68607a704c5c31ae2e4b956dc227Prerepa Viswanadham Boolean isCongested = false; 83934dee789c0c68607a704c5c31ae2e4b956dc227Prerepa Viswanadham 84934dee789c0c68607a704c5c31ae2e4b956dc227Prerepa Viswanadham /** Internal callback info queue, waiting to be send on congestion clear */ 85934dee789c0c68607a704c5c31ae2e4b956dc227Prerepa Viswanadham private List<CallbackInfo> congestionQueue = new ArrayList<CallbackInfo>(); 86934dee789c0c68607a704c5c31ae2e4b956dc227Prerepa Viswanadham 8703b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta /** 8803b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta * Creates a new app context. 8903b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta */ 908a0bc0a61e97f8923cb362e1dbb7ff66ffe51507Ajay Panicker App(UUID uuid, T callback, String name) { 9103b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta this.uuid = uuid; 9203b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta this.callback = callback; 938a0bc0a61e97f8923cb362e1dbb7ff66ffe51507Ajay Panicker this.name = name; 9403b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta } 956af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach 966af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach /** 976af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach * Link death recipient 986af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach */ 996af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach void linkToDeath(IBinder.DeathRecipient deathRecipient) { 1006af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach try { 1016af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach IBinder binder = ((IInterface)callback).asBinder(); 1026af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach binder.linkToDeath(deathRecipient, 0); 1036af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach mDeathRecipient = deathRecipient; 1046af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach } catch (RemoteException e) { 1056af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach Log.e(TAG, "Unable to link deathRecipient for app id " + id); 1066af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach } 1076af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach } 1086af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach 1096af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach /** 1106af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach * Unlink death recipient 1116af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach */ 1126af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach void unlinkToDeath() { 1136af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach if (mDeathRecipient != null) { 1146af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach try { 1156af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach IBinder binder = ((IInterface)callback).asBinder(); 1166af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach binder.unlinkToDeath(mDeathRecipient,0); 1176af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach } catch (NoSuchElementException e) { 1186af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach Log.e(TAG, "Unable to unlink deathRecipient for app id " + id); 1196af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach } 1206af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach } 1216af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach } 122934dee789c0c68607a704c5c31ae2e4b956dc227Prerepa Viswanadham 123934dee789c0c68607a704c5c31ae2e4b956dc227Prerepa Viswanadham void queueCallback(CallbackInfo callbackInfo) { 124934dee789c0c68607a704c5c31ae2e4b956dc227Prerepa Viswanadham congestionQueue.add(callbackInfo); 125934dee789c0c68607a704c5c31ae2e4b956dc227Prerepa Viswanadham } 126934dee789c0c68607a704c5c31ae2e4b956dc227Prerepa Viswanadham 127934dee789c0c68607a704c5c31ae2e4b956dc227Prerepa Viswanadham CallbackInfo popQueuedCallback() { 128934dee789c0c68607a704c5c31ae2e4b956dc227Prerepa Viswanadham if (congestionQueue.size() == 0) return null; 129934dee789c0c68607a704c5c31ae2e4b956dc227Prerepa Viswanadham return congestionQueue.remove(0); 130934dee789c0c68607a704c5c31ae2e4b956dc227Prerepa Viswanadham } 13103b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta } 13203b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta 13303b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta /** Our internal application list */ 13403b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta List<App> mApps = new ArrayList<App>(); 13503b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta 1368a0bc0a61e97f8923cb362e1dbb7ff66ffe51507Ajay Panicker /** Internal map to keep track of logging information by app name */ 1377a068c2a0861e12a3916cec313cf105395871999Ajay Panicker HashMap<String, AppScanStats> mAppScanStats = new HashMap<String, AppScanStats>(); 1387a068c2a0861e12a3916cec313cf105395871999Ajay Panicker 1397a068c2a0861e12a3916cec313cf105395871999Ajay Panicker /** Internal list of scan events to use with the proto */ 1407a068c2a0861e12a3916cec313cf105395871999Ajay Panicker ArrayList<BluetoothProto.ScanEvent> mScanEvents = 1417a068c2a0861e12a3916cec313cf105395871999Ajay Panicker new ArrayList<BluetoothProto.ScanEvent>(NUM_SCAN_EVENTS_KEPT); 1428a0bc0a61e97f8923cb362e1dbb7ff66ffe51507Ajay Panicker 14303b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta /** Internal list of connected devices **/ 14403b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta Set<Connection> mConnections = new HashSet<Connection>(); 14503b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta 14603b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta /** 14703b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta * Add an entry to the application context list. 14803b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta */ 1498a0bc0a61e97f8923cb362e1dbb7ff66ffe51507Ajay Panicker void add(UUID uuid, T callback, Context context) { 1508a0bc0a61e97f8923cb362e1dbb7ff66ffe51507Ajay Panicker String appName = context.getPackageManager().getNameForUid( 1518a0bc0a61e97f8923cb362e1dbb7ff66ffe51507Ajay Panicker Binder.getCallingUid()); 1528a0bc0a61e97f8923cb362e1dbb7ff66ffe51507Ajay Panicker if (appName == null) { 1538a0bc0a61e97f8923cb362e1dbb7ff66ffe51507Ajay Panicker // Assign an app name if one isn't found 1548a0bc0a61e97f8923cb362e1dbb7ff66ffe51507Ajay Panicker appName = "Unknown App (UID: " + Binder.getCallingUid() + ")"; 1558a0bc0a61e97f8923cb362e1dbb7ff66ffe51507Ajay Panicker } 1566af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach synchronized (mApps) { 1578a0bc0a61e97f8923cb362e1dbb7ff66ffe51507Ajay Panicker mApps.add(new App(uuid, callback, appName)); 1587a068c2a0861e12a3916cec313cf105395871999Ajay Panicker AppScanStats appScanStats = mAppScanStats.get(appName); 1597a068c2a0861e12a3916cec313cf105395871999Ajay Panicker if (appScanStats == null) { 1607a068c2a0861e12a3916cec313cf105395871999Ajay Panicker appScanStats = new AppScanStats(appName, this); 1617a068c2a0861e12a3916cec313cf105395871999Ajay Panicker mAppScanStats.put(appName, appScanStats); 1628a0bc0a61e97f8923cb362e1dbb7ff66ffe51507Ajay Panicker } 1637a068c2a0861e12a3916cec313cf105395871999Ajay Panicker appScanStats.isRegistered = true; 1646af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach } 16503b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta } 16603b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta 16703b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta /** 1683f8164cd8c4bcce5e79770ee7c02fe00ba9581d5Andre Eisenbach * Remove the context for a given UUID 1693f8164cd8c4bcce5e79770ee7c02fe00ba9581d5Andre Eisenbach */ 1703f8164cd8c4bcce5e79770ee7c02fe00ba9581d5Andre Eisenbach void remove(UUID uuid) { 1713f8164cd8c4bcce5e79770ee7c02fe00ba9581d5Andre Eisenbach synchronized (mApps) { 1723f8164cd8c4bcce5e79770ee7c02fe00ba9581d5Andre Eisenbach Iterator<App> i = mApps.iterator(); 1738a0bc0a61e97f8923cb362e1dbb7ff66ffe51507Ajay Panicker while (i.hasNext()) { 1743f8164cd8c4bcce5e79770ee7c02fe00ba9581d5Andre Eisenbach App entry = i.next(); 1753f8164cd8c4bcce5e79770ee7c02fe00ba9581d5Andre Eisenbach if (entry.uuid.equals(uuid)) { 1763f8164cd8c4bcce5e79770ee7c02fe00ba9581d5Andre Eisenbach entry.unlinkToDeath(); 1777a068c2a0861e12a3916cec313cf105395871999Ajay Panicker mAppScanStats.get(entry.name).isRegistered = false; 1783f8164cd8c4bcce5e79770ee7c02fe00ba9581d5Andre Eisenbach i.remove(); 1793f8164cd8c4bcce5e79770ee7c02fe00ba9581d5Andre Eisenbach break; 1803f8164cd8c4bcce5e79770ee7c02fe00ba9581d5Andre Eisenbach } 1813f8164cd8c4bcce5e79770ee7c02fe00ba9581d5Andre Eisenbach } 1823f8164cd8c4bcce5e79770ee7c02fe00ba9581d5Andre Eisenbach } 1833f8164cd8c4bcce5e79770ee7c02fe00ba9581d5Andre Eisenbach } 1843f8164cd8c4bcce5e79770ee7c02fe00ba9581d5Andre Eisenbach 1853f8164cd8c4bcce5e79770ee7c02fe00ba9581d5Andre Eisenbach /** 18603b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta * Remove the context for a given application ID. 18703b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta */ 18803b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta void remove(int id) { 1896af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach synchronized (mApps) { 1906af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach Iterator<App> i = mApps.iterator(); 1918a0bc0a61e97f8923cb362e1dbb7ff66ffe51507Ajay Panicker while (i.hasNext()) { 1926af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach App entry = i.next(); 1936af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach if (entry.id == id) { 1946af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach entry.unlinkToDeath(); 1957a068c2a0861e12a3916cec313cf105395871999Ajay Panicker mAppScanStats.get(entry.name).isRegistered = false; 1966af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach i.remove(); 1976af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach break; 1986af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach } 19903b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta } 20003b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta } 20103b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta } 20203b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta 20303b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta /** 20403b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta * Add a new connection for a given application ID. 20503b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta */ 20603b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta void addConnection(int id, int connId, String address) { 2076af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach synchronized (mConnections) { 2086af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach App entry = getById(id); 2096af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach if (entry != null){ 2106af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach mConnections.add(new Connection(connId, address, id)); 2116af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach } 21203b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta } 21303b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta } 21403b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta 21503b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta /** 21603b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta * Remove a connection with the given ID. 21703b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta */ 21803b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta void removeConnection(int id, int connId) { 2196af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach synchronized (mConnections) { 2206af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach Iterator<Connection> i = mConnections.iterator(); 2218a0bc0a61e97f8923cb362e1dbb7ff66ffe51507Ajay Panicker while (i.hasNext()) { 2226af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach Connection connection = i.next(); 2236af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach if (connection.connId == connId) { 2246af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach i.remove(); 2256af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach break; 2266af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach } 22703b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta } 22803b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta } 22903b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta } 23003b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta 23103b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta /** 23203b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta * Get an application context by ID. 23303b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta */ 23403b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta App getById(int id) { 23503b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta Iterator<App> i = mApps.iterator(); 2368a0bc0a61e97f8923cb362e1dbb7ff66ffe51507Ajay Panicker while (i.hasNext()) { 23703b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta App entry = i.next(); 23803b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta if (entry.id == id) return entry; 23903b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta } 24003b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta Log.e(TAG, "Context not found for ID " + id); 24103b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta return null; 24203b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta } 24303b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta 24403b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta /** 24503b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta * Get an application context by UUID. 24603b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta */ 24703b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta App getByUuid(UUID uuid) { 24803b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta Iterator<App> i = mApps.iterator(); 2498a0bc0a61e97f8923cb362e1dbb7ff66ffe51507Ajay Panicker while (i.hasNext()) { 25003b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta App entry = i.next(); 25103b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta if (entry.uuid.equals(uuid)) return entry; 25203b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta } 25303b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta Log.e(TAG, "Context not found for UUID " + uuid); 25403b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta return null; 25503b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta } 25603b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta 25703b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta /** 2588a0bc0a61e97f8923cb362e1dbb7ff66ffe51507Ajay Panicker * Get an application context by the calling Apps name. 2598a0bc0a61e97f8923cb362e1dbb7ff66ffe51507Ajay Panicker */ 2608a0bc0a61e97f8923cb362e1dbb7ff66ffe51507Ajay Panicker App getByName(String name) { 2618a0bc0a61e97f8923cb362e1dbb7ff66ffe51507Ajay Panicker Iterator<App> i = mApps.iterator(); 2628a0bc0a61e97f8923cb362e1dbb7ff66ffe51507Ajay Panicker while (i.hasNext()) { 2638a0bc0a61e97f8923cb362e1dbb7ff66ffe51507Ajay Panicker App entry = i.next(); 2648a0bc0a61e97f8923cb362e1dbb7ff66ffe51507Ajay Panicker if (entry.name.equals(name)) return entry; 2658a0bc0a61e97f8923cb362e1dbb7ff66ffe51507Ajay Panicker } 2668a0bc0a61e97f8923cb362e1dbb7ff66ffe51507Ajay Panicker Log.e(TAG, "Context not found for name " + name); 2678a0bc0a61e97f8923cb362e1dbb7ff66ffe51507Ajay Panicker return null; 2688a0bc0a61e97f8923cb362e1dbb7ff66ffe51507Ajay Panicker } 2698a0bc0a61e97f8923cb362e1dbb7ff66ffe51507Ajay Panicker 2708a0bc0a61e97f8923cb362e1dbb7ff66ffe51507Ajay Panicker /** 2718a0bc0a61e97f8923cb362e1dbb7ff66ffe51507Ajay Panicker * Get Logging info by ID 2728a0bc0a61e97f8923cb362e1dbb7ff66ffe51507Ajay Panicker */ 2737a068c2a0861e12a3916cec313cf105395871999Ajay Panicker AppScanStats getAppScanStatsById(int id) { 2748a0bc0a61e97f8923cb362e1dbb7ff66ffe51507Ajay Panicker App temp = getById(id); 2758a0bc0a61e97f8923cb362e1dbb7ff66ffe51507Ajay Panicker if (temp != null) { 2767a068c2a0861e12a3916cec313cf105395871999Ajay Panicker return mAppScanStats.get(temp.name); 2778a0bc0a61e97f8923cb362e1dbb7ff66ffe51507Ajay Panicker } 2788a0bc0a61e97f8923cb362e1dbb7ff66ffe51507Ajay Panicker return null; 2798a0bc0a61e97f8923cb362e1dbb7ff66ffe51507Ajay Panicker } 2808a0bc0a61e97f8923cb362e1dbb7ff66ffe51507Ajay Panicker 2818a0bc0a61e97f8923cb362e1dbb7ff66ffe51507Ajay Panicker /** 2823122e5171ef26ff487f10826786606df848ca25eAjay Panicker * Get Logging info by application name 2833122e5171ef26ff487f10826786606df848ca25eAjay Panicker */ 2847a068c2a0861e12a3916cec313cf105395871999Ajay Panicker AppScanStats getAppScanStatsByName(String name) { 2857a068c2a0861e12a3916cec313cf105395871999Ajay Panicker return mAppScanStats.get(name); 2863122e5171ef26ff487f10826786606df848ca25eAjay Panicker } 2873122e5171ef26ff487f10826786606df848ca25eAjay Panicker 2883122e5171ef26ff487f10826786606df848ca25eAjay Panicker /** 28903b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta * Get the device addresses for all connected devices 29003b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta */ 29103b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta Set<String> getConnectedDevices() { 29203b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta Set<String> addresses = new HashSet<String>(); 29303b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta Iterator<Connection> i = mConnections.iterator(); 2948a0bc0a61e97f8923cb362e1dbb7ff66ffe51507Ajay Panicker while (i.hasNext()) { 29503b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta Connection connection = i.next(); 29603b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta addresses.add(connection.address); 29703b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta } 29803b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta return addresses; 29903b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta } 30003b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta 30103b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta /** 30203b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta * Get an application context by a connection ID. 30303b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta */ 30403b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta App getByConnId(int connId) { 30503b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta Iterator<Connection> ii = mConnections.iterator(); 3068a0bc0a61e97f8923cb362e1dbb7ff66ffe51507Ajay Panicker while (ii.hasNext()) { 30703b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta Connection connection = ii.next(); 30803b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta if (connection.connId == connId){ 30903b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta return getById(connection.appId); 31003b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta } 31103b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta } 31203b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta return null; 31303b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta } 31403b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta 31503b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta /** 31603b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta * Returns a connection ID for a given device address. 31703b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta */ 31803b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta Integer connIdByAddress(int id, String address) { 31903b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta App entry = getById(id); 32003b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta if (entry == null) return null; 32103b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta 32203b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta Iterator<Connection> i = mConnections.iterator(); 3238a0bc0a61e97f8923cb362e1dbb7ff66ffe51507Ajay Panicker while (i.hasNext()) { 32403b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta Connection connection = i.next(); 32503b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta if (connection.address.equals(address) && connection.appId == id) 32603b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta return connection.connId; 32703b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta } 32803b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta return null; 32903b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta } 33003b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta 33103b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta /** 33203b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta * Returns the device address for a given connection ID. 33303b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta */ 33403b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta String addressByConnId(int connId) { 33503b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta Iterator<Connection> i = mConnections.iterator(); 3368a0bc0a61e97f8923cb362e1dbb7ff66ffe51507Ajay Panicker while (i.hasNext()) { 33703b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta Connection connection = i.next(); 33803b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta if (connection.connId == connId) return connection.address; 33903b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta } 34003b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta return null; 34103b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta } 34203b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta 34303b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta List<Connection> getConnectionByApp(int appId) { 34403b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta List<Connection> currentConnections = new ArrayList<Connection>(); 34503b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta Iterator<Connection> i = mConnections.iterator(); 3468a0bc0a61e97f8923cb362e1dbb7ff66ffe51507Ajay Panicker while (i.hasNext()) { 34703b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta Connection connection = i.next(); 34803b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta if (connection.appId == appId) 34903b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta currentConnections.add(connection); 35003b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta } 35103b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta return currentConnections; 35203b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta } 35303b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta 35403b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta /** 35503b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta * Erases all application context entries. 35603b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta */ 35703b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta void clear() { 3586af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach synchronized (mApps) { 3596af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach Iterator<App> i = mApps.iterator(); 3608a0bc0a61e97f8923cb362e1dbb7ff66ffe51507Ajay Panicker while (i.hasNext()) { 3616af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach App entry = i.next(); 3626af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach entry.unlinkToDeath(); 3636af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach i.remove(); 3646af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach } 3656af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach } 3666af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach 3676af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach synchronized (mConnections) { 3686af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach mConnections.clear(); 3696af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach } 37003b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta } 37103b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta 37203b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta /** 373f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora * Returns connect device map with addr and appid 374f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora */ 375f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora Map<Integer, String> getConnectedMap(){ 376f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora Map<Integer, String> connectedmap = new HashMap<Integer, String>(); 377f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora for(Connection conn: mConnections){ 378f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora connectedmap.put(conn.appId, conn.address); 379f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora } 380f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora return connectedmap; 381f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora } 382f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora 3837a068c2a0861e12a3916cec313cf105395871999Ajay Panicker void addScanEvent(BluetoothProto.ScanEvent event) { 3847a068c2a0861e12a3916cec313cf105395871999Ajay Panicker synchronized(mScanEvents) { 3857a068c2a0861e12a3916cec313cf105395871999Ajay Panicker if (mScanEvents.size() == NUM_SCAN_EVENTS_KEPT) 3867a068c2a0861e12a3916cec313cf105395871999Ajay Panicker mScanEvents.remove(0); 3877a068c2a0861e12a3916cec313cf105395871999Ajay Panicker mScanEvents.add(event); 3887a068c2a0861e12a3916cec313cf105395871999Ajay Panicker } 3897a068c2a0861e12a3916cec313cf105395871999Ajay Panicker } 3907a068c2a0861e12a3916cec313cf105395871999Ajay Panicker 391f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora /** 39203b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta * Logs debug information. 39303b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta */ 394a02de6484f9b6cac6b8c811edae11be55746b555Andre Eisenbach void dump(StringBuilder sb) { 3957a068c2a0861e12a3916cec313cf105395871999Ajay Panicker sb.append(" Entries: " + mAppScanStats.size() + "\n\n"); 3968a0bc0a61e97f8923cb362e1dbb7ff66ffe51507Ajay Panicker 3977a068c2a0861e12a3916cec313cf105395871999Ajay Panicker Iterator<Map.Entry<String, AppScanStats>> it = mAppScanStats.entrySet().iterator(); 3985c07523b0b5d32176d7ff3ab28555123123261ddAjay Panicker while (it.hasNext()) { 3997a068c2a0861e12a3916cec313cf105395871999Ajay Panicker Map.Entry<String, AppScanStats> entry = it.next(); 40003b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta 4018a0bc0a61e97f8923cb362e1dbb7ff66ffe51507Ajay Panicker String name = entry.getKey(); 4027a068c2a0861e12a3916cec313cf105395871999Ajay Panicker AppScanStats appScanStats = entry.getValue(); 4037a068c2a0861e12a3916cec313cf105395871999Ajay Panicker appScanStats.dumpToString(sb); 40403b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta } 40503b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta } 4063122e5171ef26ff487f10826786606df848ca25eAjay Panicker 4073122e5171ef26ff487f10826786606df848ca25eAjay Panicker void dumpProto(BluetoothProto.BluetoothLog proto) { 4083122e5171ef26ff487f10826786606df848ca25eAjay Panicker synchronized(mScanEvents) { 4093122e5171ef26ff487f10826786606df848ca25eAjay Panicker for (BluetoothProto.ScanEvent event : mScanEvents) { 4103122e5171ef26ff487f10826786606df848ca25eAjay Panicker proto.addScanEvent(event); 4113122e5171ef26ff487f10826786606df848ca25eAjay Panicker } 4123122e5171ef26ff487f10826786606df848ca25eAjay Panicker } 4133122e5171ef26ff487f10826786606df848ca25eAjay Panicker } 41403b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta} 415