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"; 438a0bc0a61e97f8923cb362e1dbb7ff66ffe51507Ajay Panicker 448a0bc0a61e97f8923cb362e1dbb7ff66ffe51507Ajay Panicker /** 4503b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta * Connection class helps map connection IDs to device addresses. 4603b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta */ 4703b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta class Connection { 4803b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta int connId; 4903b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta String address; 5003b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta int appId; 51337ee9418b0122e6a89ff38cd49f031ba80aa24cAjay Panicker long startTime; 5203b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta 5303b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta Connection(int connId, String address,int appId) { 5403b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta this.connId = connId; 5503b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta this.address = address; 5603b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta this.appId = appId; 57337ee9418b0122e6a89ff38cd49f031ba80aa24cAjay Panicker this.startTime = System.currentTimeMillis(); 5803b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta } 5903b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta } 6003b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta 6103b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta /** 6203b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta * Application entry mapping UUIDs to appIDs and callbacks. 6303b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta */ 6403b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta class App { 6503b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta /** The UUID of the application */ 6603b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta UUID uuid; 6703b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta 6803b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta /** The id of the application */ 6903b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta int id; 7003b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta 718a0bc0a61e97f8923cb362e1dbb7ff66ffe51507Ajay Panicker /** The package name of the application */ 728a0bc0a61e97f8923cb362e1dbb7ff66ffe51507Ajay Panicker String name; 738a0bc0a61e97f8923cb362e1dbb7ff66ffe51507Ajay Panicker 74e90db937c008f365f47e7199d6d86f9eb13bed1eAjay Panicker /** Statistics for this app */ 75e90db937c008f365f47e7199d6d86f9eb13bed1eAjay Panicker AppScanStats appScanStats; 76e90db937c008f365f47e7199d6d86f9eb13bed1eAjay Panicker 7703b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta /** Application callbacks */ 7803b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta T callback; 7903b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta 806af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach /** Death receipient */ 816af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach private IBinder.DeathRecipient mDeathRecipient; 826af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach 83934dee789c0c68607a704c5c31ae2e4b956dc227Prerepa Viswanadham /** Flag to signal that transport is congested */ 84934dee789c0c68607a704c5c31ae2e4b956dc227Prerepa Viswanadham Boolean isCongested = false; 85934dee789c0c68607a704c5c31ae2e4b956dc227Prerepa Viswanadham 86934dee789c0c68607a704c5c31ae2e4b956dc227Prerepa Viswanadham /** Internal callback info queue, waiting to be send on congestion clear */ 87934dee789c0c68607a704c5c31ae2e4b956dc227Prerepa Viswanadham private List<CallbackInfo> congestionQueue = new ArrayList<CallbackInfo>(); 88934dee789c0c68607a704c5c31ae2e4b956dc227Prerepa Viswanadham 8903b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta /** 9003b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta * Creates a new app context. 9103b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta */ 92e90db937c008f365f47e7199d6d86f9eb13bed1eAjay Panicker App(UUID uuid, T callback, String name, AppScanStats appScanStats) { 9303b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta this.uuid = uuid; 9403b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta this.callback = callback; 958a0bc0a61e97f8923cb362e1dbb7ff66ffe51507Ajay Panicker this.name = name; 96e90db937c008f365f47e7199d6d86f9eb13bed1eAjay Panicker this.appScanStats = appScanStats; 9703b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta } 986af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach 996af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach /** 1006af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach * Link death recipient 1016af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach */ 1026af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach void linkToDeath(IBinder.DeathRecipient deathRecipient) { 1036af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach try { 1046af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach IBinder binder = ((IInterface)callback).asBinder(); 1056af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach binder.linkToDeath(deathRecipient, 0); 1066af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach mDeathRecipient = deathRecipient; 1076af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach } catch (RemoteException e) { 1086af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach Log.e(TAG, "Unable to link deathRecipient for app id " + id); 1096af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach } 1106af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach } 1116af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach 1126af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach /** 1136af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach * Unlink death recipient 1146af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach */ 1156af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach void unlinkToDeath() { 1166af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach if (mDeathRecipient != null) { 1176af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach try { 1186af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach IBinder binder = ((IInterface)callback).asBinder(); 1196af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach binder.unlinkToDeath(mDeathRecipient,0); 1206af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach } catch (NoSuchElementException e) { 1216af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach Log.e(TAG, "Unable to unlink deathRecipient for app id " + id); 1226af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach } 1236af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach } 1246af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach } 125934dee789c0c68607a704c5c31ae2e4b956dc227Prerepa Viswanadham 126934dee789c0c68607a704c5c31ae2e4b956dc227Prerepa Viswanadham void queueCallback(CallbackInfo callbackInfo) { 127934dee789c0c68607a704c5c31ae2e4b956dc227Prerepa Viswanadham congestionQueue.add(callbackInfo); 128934dee789c0c68607a704c5c31ae2e4b956dc227Prerepa Viswanadham } 129934dee789c0c68607a704c5c31ae2e4b956dc227Prerepa Viswanadham 130934dee789c0c68607a704c5c31ae2e4b956dc227Prerepa Viswanadham CallbackInfo popQueuedCallback() { 131934dee789c0c68607a704c5c31ae2e4b956dc227Prerepa Viswanadham if (congestionQueue.size() == 0) return null; 132934dee789c0c68607a704c5c31ae2e4b956dc227Prerepa Viswanadham return congestionQueue.remove(0); 133934dee789c0c68607a704c5c31ae2e4b956dc227Prerepa Viswanadham } 13403b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta } 13503b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta 13603b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta /** Our internal application list */ 13703b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta List<App> mApps = new ArrayList<App>(); 13803b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta 1398a0bc0a61e97f8923cb362e1dbb7ff66ffe51507Ajay Panicker /** Internal map to keep track of logging information by app name */ 1407a068c2a0861e12a3916cec313cf105395871999Ajay Panicker HashMap<String, AppScanStats> mAppScanStats = new HashMap<String, AppScanStats>(); 1417a068c2a0861e12a3916cec313cf105395871999Ajay Panicker 14203b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta /** Internal list of connected devices **/ 14303b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta Set<Connection> mConnections = new HashSet<Connection>(); 14403b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta 14503b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta /** 14603b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta * Add an entry to the application context list. 14703b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta */ 148e90db937c008f365f47e7199d6d86f9eb13bed1eAjay Panicker void add(UUID uuid, T callback, GattService service) { 149e90db937c008f365f47e7199d6d86f9eb13bed1eAjay Panicker String appName = service.getPackageManager().getNameForUid( 1508a0bc0a61e97f8923cb362e1dbb7ff66ffe51507Ajay Panicker Binder.getCallingUid()); 1518a0bc0a61e97f8923cb362e1dbb7ff66ffe51507Ajay Panicker if (appName == null) { 1528a0bc0a61e97f8923cb362e1dbb7ff66ffe51507Ajay Panicker // Assign an app name if one isn't found 1538a0bc0a61e97f8923cb362e1dbb7ff66ffe51507Ajay Panicker appName = "Unknown App (UID: " + Binder.getCallingUid() + ")"; 1548a0bc0a61e97f8923cb362e1dbb7ff66ffe51507Ajay Panicker } 1556af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach synchronized (mApps) { 1567a068c2a0861e12a3916cec313cf105395871999Ajay Panicker AppScanStats appScanStats = mAppScanStats.get(appName); 1577a068c2a0861e12a3916cec313cf105395871999Ajay Panicker if (appScanStats == null) { 158e90db937c008f365f47e7199d6d86f9eb13bed1eAjay Panicker appScanStats = new AppScanStats(appName, this, service); 1597a068c2a0861e12a3916cec313cf105395871999Ajay Panicker mAppScanStats.put(appName, appScanStats); 1608a0bc0a61e97f8923cb362e1dbb7ff66ffe51507Ajay Panicker } 1612a6d08a87c210918a0ad5b4c01bb5152cce2ba69Sharvil Nanavati mApps.add(new App(uuid, callback, appName, appScanStats)); 1627a068c2a0861e12a3916cec313cf105395871999Ajay Panicker appScanStats.isRegistered = true; 1636af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach } 16403b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta } 16503b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta 16603b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta /** 1673f8164cd8c4bcce5e79770ee7c02fe00ba9581d5Andre Eisenbach * Remove the context for a given UUID 1683f8164cd8c4bcce5e79770ee7c02fe00ba9581d5Andre Eisenbach */ 1693f8164cd8c4bcce5e79770ee7c02fe00ba9581d5Andre Eisenbach void remove(UUID uuid) { 1703f8164cd8c4bcce5e79770ee7c02fe00ba9581d5Andre Eisenbach synchronized (mApps) { 1713f8164cd8c4bcce5e79770ee7c02fe00ba9581d5Andre Eisenbach Iterator<App> i = mApps.iterator(); 1728a0bc0a61e97f8923cb362e1dbb7ff66ffe51507Ajay Panicker while (i.hasNext()) { 1733f8164cd8c4bcce5e79770ee7c02fe00ba9581d5Andre Eisenbach App entry = i.next(); 1743f8164cd8c4bcce5e79770ee7c02fe00ba9581d5Andre Eisenbach if (entry.uuid.equals(uuid)) { 1753f8164cd8c4bcce5e79770ee7c02fe00ba9581d5Andre Eisenbach entry.unlinkToDeath(); 176e90db937c008f365f47e7199d6d86f9eb13bed1eAjay Panicker entry.appScanStats.isRegistered = false; 1773f8164cd8c4bcce5e79770ee7c02fe00ba9581d5Andre Eisenbach i.remove(); 1783f8164cd8c4bcce5e79770ee7c02fe00ba9581d5Andre Eisenbach break; 1793f8164cd8c4bcce5e79770ee7c02fe00ba9581d5Andre Eisenbach } 1803f8164cd8c4bcce5e79770ee7c02fe00ba9581d5Andre Eisenbach } 1813f8164cd8c4bcce5e79770ee7c02fe00ba9581d5Andre Eisenbach } 1823f8164cd8c4bcce5e79770ee7c02fe00ba9581d5Andre Eisenbach } 1833f8164cd8c4bcce5e79770ee7c02fe00ba9581d5Andre Eisenbach 1843f8164cd8c4bcce5e79770ee7c02fe00ba9581d5Andre Eisenbach /** 18503b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta * Remove the context for a given application ID. 18603b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta */ 18703b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta void remove(int id) { 1886af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach synchronized (mApps) { 1896af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach Iterator<App> i = mApps.iterator(); 1908a0bc0a61e97f8923cb362e1dbb7ff66ffe51507Ajay Panicker while (i.hasNext()) { 1916af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach App entry = i.next(); 1926af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach if (entry.id == id) { 193660208ad2ee2ea394adab0d1c1cea9b068bb70c6Kyle Horimoto removeConnectionsByAppId(id); 1946af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach entry.unlinkToDeath(); 195b37b80b24a26a697d302583c900c5e9237acb03aAjay Panicker entry.appScanStats.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); 209660208ad2ee2ea394adab0d1c1cea9b068bb70c6Kyle Horimoto 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 /** 232660208ad2ee2ea394adab0d1c1cea9b068bb70c6Kyle Horimoto * Remove all connections for a given application ID. 233660208ad2ee2ea394adab0d1c1cea9b068bb70c6Kyle Horimoto */ 234660208ad2ee2ea394adab0d1c1cea9b068bb70c6Kyle Horimoto void removeConnectionsByAppId(int appId) { 235660208ad2ee2ea394adab0d1c1cea9b068bb70c6Kyle Horimoto Iterator<Connection> i = mConnections.iterator(); 236660208ad2ee2ea394adab0d1c1cea9b068bb70c6Kyle Horimoto while (i.hasNext()) { 237660208ad2ee2ea394adab0d1c1cea9b068bb70c6Kyle Horimoto Connection connection = i.next(); 238660208ad2ee2ea394adab0d1c1cea9b068bb70c6Kyle Horimoto if (connection.appId == appId) { 239660208ad2ee2ea394adab0d1c1cea9b068bb70c6Kyle Horimoto i.remove(); 240660208ad2ee2ea394adab0d1c1cea9b068bb70c6Kyle Horimoto } 241660208ad2ee2ea394adab0d1c1cea9b068bb70c6Kyle Horimoto } 242660208ad2ee2ea394adab0d1c1cea9b068bb70c6Kyle Horimoto } 243660208ad2ee2ea394adab0d1c1cea9b068bb70c6Kyle Horimoto 244660208ad2ee2ea394adab0d1c1cea9b068bb70c6Kyle Horimoto /** 24503b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta * Get an application context by ID. 24603b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta */ 24703b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta App getById(int id) { 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.id == id) return entry; 25203b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta } 25303b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta Log.e(TAG, "Context not found for ID " + id); 25403b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta return null; 25503b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta } 25603b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta 25703b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta /** 25803b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta * Get an application context by UUID. 25903b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta */ 26003b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta App getByUuid(UUID uuid) { 26103b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta Iterator<App> i = mApps.iterator(); 2628a0bc0a61e97f8923cb362e1dbb7ff66ffe51507Ajay Panicker while (i.hasNext()) { 26303b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta App entry = i.next(); 26403b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta if (entry.uuid.equals(uuid)) return entry; 26503b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta } 26603b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta Log.e(TAG, "Context not found for UUID " + uuid); 26703b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta return null; 26803b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta } 26903b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta 27003b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta /** 2718a0bc0a61e97f8923cb362e1dbb7ff66ffe51507Ajay Panicker * Get an application context by the calling Apps name. 2728a0bc0a61e97f8923cb362e1dbb7ff66ffe51507Ajay Panicker */ 2738a0bc0a61e97f8923cb362e1dbb7ff66ffe51507Ajay Panicker App getByName(String name) { 2748a0bc0a61e97f8923cb362e1dbb7ff66ffe51507Ajay Panicker Iterator<App> i = mApps.iterator(); 2758a0bc0a61e97f8923cb362e1dbb7ff66ffe51507Ajay Panicker while (i.hasNext()) { 2768a0bc0a61e97f8923cb362e1dbb7ff66ffe51507Ajay Panicker App entry = i.next(); 2778a0bc0a61e97f8923cb362e1dbb7ff66ffe51507Ajay Panicker if (entry.name.equals(name)) return entry; 2788a0bc0a61e97f8923cb362e1dbb7ff66ffe51507Ajay Panicker } 2798a0bc0a61e97f8923cb362e1dbb7ff66ffe51507Ajay Panicker Log.e(TAG, "Context not found for name " + name); 2808a0bc0a61e97f8923cb362e1dbb7ff66ffe51507Ajay Panicker return null; 2818a0bc0a61e97f8923cb362e1dbb7ff66ffe51507Ajay Panicker } 2828a0bc0a61e97f8923cb362e1dbb7ff66ffe51507Ajay Panicker 2838a0bc0a61e97f8923cb362e1dbb7ff66ffe51507Ajay Panicker /** 2848a0bc0a61e97f8923cb362e1dbb7ff66ffe51507Ajay Panicker * Get Logging info by ID 2858a0bc0a61e97f8923cb362e1dbb7ff66ffe51507Ajay Panicker */ 2867a068c2a0861e12a3916cec313cf105395871999Ajay Panicker AppScanStats getAppScanStatsById(int id) { 2878a0bc0a61e97f8923cb362e1dbb7ff66ffe51507Ajay Panicker App temp = getById(id); 2888a0bc0a61e97f8923cb362e1dbb7ff66ffe51507Ajay Panicker if (temp != null) { 289e90db937c008f365f47e7199d6d86f9eb13bed1eAjay Panicker return temp.appScanStats; 2908a0bc0a61e97f8923cb362e1dbb7ff66ffe51507Ajay Panicker } 2918a0bc0a61e97f8923cb362e1dbb7ff66ffe51507Ajay Panicker return null; 2928a0bc0a61e97f8923cb362e1dbb7ff66ffe51507Ajay Panicker } 2938a0bc0a61e97f8923cb362e1dbb7ff66ffe51507Ajay Panicker 2948a0bc0a61e97f8923cb362e1dbb7ff66ffe51507Ajay Panicker /** 2953122e5171ef26ff487f10826786606df848ca25eAjay Panicker * Get Logging info by application name 2963122e5171ef26ff487f10826786606df848ca25eAjay Panicker */ 2977a068c2a0861e12a3916cec313cf105395871999Ajay Panicker AppScanStats getAppScanStatsByName(String name) { 2987a068c2a0861e12a3916cec313cf105395871999Ajay Panicker return mAppScanStats.get(name); 2993122e5171ef26ff487f10826786606df848ca25eAjay Panicker } 3003122e5171ef26ff487f10826786606df848ca25eAjay Panicker 3013122e5171ef26ff487f10826786606df848ca25eAjay Panicker /** 30203b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta * Get the device addresses for all connected devices 30303b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta */ 30403b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta Set<String> getConnectedDevices() { 30503b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta Set<String> addresses = new HashSet<String>(); 30603b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta Iterator<Connection> i = mConnections.iterator(); 3078a0bc0a61e97f8923cb362e1dbb7ff66ffe51507Ajay Panicker while (i.hasNext()) { 30803b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta Connection connection = i.next(); 30903b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta addresses.add(connection.address); 31003b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta } 31103b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta return addresses; 31203b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta } 31303b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta 31403b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta /** 31503b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta * Get an application context by a connection ID. 31603b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta */ 31703b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta App getByConnId(int connId) { 31803b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta Iterator<Connection> ii = mConnections.iterator(); 3198a0bc0a61e97f8923cb362e1dbb7ff66ffe51507Ajay Panicker while (ii.hasNext()) { 32003b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta Connection connection = ii.next(); 32103b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta if (connection.connId == connId){ 32203b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta return getById(connection.appId); 32303b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta } 32403b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta } 32503b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta return null; 32603b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta } 32703b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta 32803b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta /** 32903b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta * Returns a connection ID for a given device address. 33003b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta */ 33103b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta Integer connIdByAddress(int id, String address) { 33203b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta App entry = getById(id); 33303b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta if (entry == null) return null; 33403b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta 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.address.equals(address) && connection.appId == id) 33903b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta return connection.connId; 34003b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta } 34103b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta return null; 34203b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta } 34303b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta 34403b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta /** 34503b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta * Returns the device address for a given connection ID. 34603b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta */ 34703b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta String addressByConnId(int connId) { 34803b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta Iterator<Connection> i = mConnections.iterator(); 3498a0bc0a61e97f8923cb362e1dbb7ff66ffe51507Ajay Panicker while (i.hasNext()) { 35003b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta Connection connection = i.next(); 35103b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta if (connection.connId == connId) return connection.address; 35203b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta } 35303b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta return null; 35403b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta } 35503b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta 35603b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta List<Connection> getConnectionByApp(int appId) { 35703b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta List<Connection> currentConnections = new ArrayList<Connection>(); 35803b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta Iterator<Connection> i = mConnections.iterator(); 3598a0bc0a61e97f8923cb362e1dbb7ff66ffe51507Ajay Panicker while (i.hasNext()) { 36003b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta Connection connection = i.next(); 36103b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta if (connection.appId == appId) 36203b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta currentConnections.add(connection); 36303b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta } 36403b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta return currentConnections; 36503b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta } 36603b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta 36703b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta /** 36803b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta * Erases all application context entries. 36903b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta */ 37003b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta void clear() { 3716af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach synchronized (mApps) { 3726af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach Iterator<App> i = mApps.iterator(); 3738a0bc0a61e97f8923cb362e1dbb7ff66ffe51507Ajay Panicker while (i.hasNext()) { 3746af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach App entry = i.next(); 3756af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach entry.unlinkToDeath(); 376b37b80b24a26a697d302583c900c5e9237acb03aAjay Panicker entry.appScanStats.isRegistered = false; 3776af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach i.remove(); 3786af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach } 3796af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach } 3806af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach 3816af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach synchronized (mConnections) { 3826af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach mConnections.clear(); 3836af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach } 38403b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta } 38503b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta 38603b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta /** 387f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora * Returns connect device map with addr and appid 388f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora */ 389f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora Map<Integer, String> getConnectedMap(){ 390f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora Map<Integer, String> connectedmap = new HashMap<Integer, String>(); 391f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora for(Connection conn: mConnections){ 392f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora connectedmap.put(conn.appId, conn.address); 393f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora } 394f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora return connectedmap; 395f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora } 396f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora 397f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora /** 39803b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta * Logs debug information. 39903b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta */ 400a02de6484f9b6cac6b8c811edae11be55746b555Andre Eisenbach void dump(StringBuilder sb) { 4017a068c2a0861e12a3916cec313cf105395871999Ajay Panicker sb.append(" Entries: " + mAppScanStats.size() + "\n\n"); 4028a0bc0a61e97f8923cb362e1dbb7ff66ffe51507Ajay Panicker 4037a068c2a0861e12a3916cec313cf105395871999Ajay Panicker Iterator<Map.Entry<String, AppScanStats>> it = mAppScanStats.entrySet().iterator(); 4045c07523b0b5d32176d7ff3ab28555123123261ddAjay Panicker while (it.hasNext()) { 4057a068c2a0861e12a3916cec313cf105395871999Ajay Panicker Map.Entry<String, AppScanStats> entry = it.next(); 40603b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta 4078a0bc0a61e97f8923cb362e1dbb7ff66ffe51507Ajay Panicker String name = entry.getKey(); 4087a068c2a0861e12a3916cec313cf105395871999Ajay Panicker AppScanStats appScanStats = entry.getValue(); 4097a068c2a0861e12a3916cec313cf105395871999Ajay Panicker appScanStats.dumpToString(sb); 41003b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta } 41103b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta } 41203b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta} 413