ContextMap.java revision e90db937c008f365f47e7199d6d86f9eb13bed1e
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); 157e90db937c008f365f47e7199d6d86f9eb13bed1eAjay Panicker mApps.add(new App(uuid, callback, appName, appScanStats)); 1587a068c2a0861e12a3916cec313cf105395871999Ajay Panicker if (appScanStats == null) { 159e90db937c008f365f47e7199d6d86f9eb13bed1eAjay Panicker appScanStats = new AppScanStats(appName, this, service); 1607a068c2a0861e12a3916cec313cf105395871999Ajay Panicker mAppScanStats.put(appName, appScanStats); 1618a0bc0a61e97f8923cb362e1dbb7ff66ffe51507Ajay Panicker } 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) { 1936af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach entry.unlinkToDeath(); 1947a068c2a0861e12a3916cec313cf105395871999Ajay Panicker mAppScanStats.get(entry.name).isRegistered = false; 1956af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach i.remove(); 1966af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach break; 1976af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach } 19803b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta } 19903b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta } 20003b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta } 20103b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta 20203b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta /** 20303b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta * Add a new connection for a given application ID. 20403b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta */ 20503b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta void addConnection(int id, int connId, String address) { 2066af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach synchronized (mConnections) { 2076af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach App entry = getById(id); 2086af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach if (entry != null){ 2096af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach mConnections.add(new Connection(connId, address, id)); 2106af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach } 21103b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta } 21203b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta } 21303b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta 21403b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta /** 21503b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta * Remove a connection with the given ID. 21603b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta */ 21703b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta void removeConnection(int id, int connId) { 2186af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach synchronized (mConnections) { 2196af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach Iterator<Connection> i = mConnections.iterator(); 2208a0bc0a61e97f8923cb362e1dbb7ff66ffe51507Ajay Panicker while (i.hasNext()) { 2216af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach Connection connection = i.next(); 2226af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach if (connection.connId == connId) { 2236af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach i.remove(); 2246af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach break; 2256af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach } 22603b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta } 22703b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta } 22803b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta } 22903b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta 23003b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta /** 23103b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta * Get an application context by ID. 23203b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta */ 23303b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta App getById(int id) { 23403b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta Iterator<App> i = mApps.iterator(); 2358a0bc0a61e97f8923cb362e1dbb7ff66ffe51507Ajay Panicker while (i.hasNext()) { 23603b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta App entry = i.next(); 23703b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta if (entry.id == id) return entry; 23803b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta } 23903b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta Log.e(TAG, "Context not found for ID " + id); 24003b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta return null; 24103b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta } 24203b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta 24303b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta /** 24403b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta * Get an application context by UUID. 24503b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta */ 24603b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta App getByUuid(UUID uuid) { 24703b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta Iterator<App> i = mApps.iterator(); 2488a0bc0a61e97f8923cb362e1dbb7ff66ffe51507Ajay Panicker while (i.hasNext()) { 24903b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta App entry = i.next(); 25003b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta if (entry.uuid.equals(uuid)) return entry; 25103b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta } 25203b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta Log.e(TAG, "Context not found for UUID " + uuid); 25303b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta return null; 25403b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta } 25503b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta 25603b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta /** 2578a0bc0a61e97f8923cb362e1dbb7ff66ffe51507Ajay Panicker * Get an application context by the calling Apps name. 2588a0bc0a61e97f8923cb362e1dbb7ff66ffe51507Ajay Panicker */ 2598a0bc0a61e97f8923cb362e1dbb7ff66ffe51507Ajay Panicker App getByName(String name) { 2608a0bc0a61e97f8923cb362e1dbb7ff66ffe51507Ajay Panicker Iterator<App> i = mApps.iterator(); 2618a0bc0a61e97f8923cb362e1dbb7ff66ffe51507Ajay Panicker while (i.hasNext()) { 2628a0bc0a61e97f8923cb362e1dbb7ff66ffe51507Ajay Panicker App entry = i.next(); 2638a0bc0a61e97f8923cb362e1dbb7ff66ffe51507Ajay Panicker if (entry.name.equals(name)) return entry; 2648a0bc0a61e97f8923cb362e1dbb7ff66ffe51507Ajay Panicker } 2658a0bc0a61e97f8923cb362e1dbb7ff66ffe51507Ajay Panicker Log.e(TAG, "Context not found for name " + name); 2668a0bc0a61e97f8923cb362e1dbb7ff66ffe51507Ajay Panicker return null; 2678a0bc0a61e97f8923cb362e1dbb7ff66ffe51507Ajay Panicker } 2688a0bc0a61e97f8923cb362e1dbb7ff66ffe51507Ajay Panicker 2698a0bc0a61e97f8923cb362e1dbb7ff66ffe51507Ajay Panicker /** 2708a0bc0a61e97f8923cb362e1dbb7ff66ffe51507Ajay Panicker * Get Logging info by ID 2718a0bc0a61e97f8923cb362e1dbb7ff66ffe51507Ajay Panicker */ 2727a068c2a0861e12a3916cec313cf105395871999Ajay Panicker AppScanStats getAppScanStatsById(int id) { 2738a0bc0a61e97f8923cb362e1dbb7ff66ffe51507Ajay Panicker App temp = getById(id); 2748a0bc0a61e97f8923cb362e1dbb7ff66ffe51507Ajay Panicker if (temp != null) { 275e90db937c008f365f47e7199d6d86f9eb13bed1eAjay Panicker return temp.appScanStats; 2768a0bc0a61e97f8923cb362e1dbb7ff66ffe51507Ajay Panicker } 2778a0bc0a61e97f8923cb362e1dbb7ff66ffe51507Ajay Panicker return null; 2788a0bc0a61e97f8923cb362e1dbb7ff66ffe51507Ajay Panicker } 2798a0bc0a61e97f8923cb362e1dbb7ff66ffe51507Ajay Panicker 2808a0bc0a61e97f8923cb362e1dbb7ff66ffe51507Ajay Panicker /** 2813122e5171ef26ff487f10826786606df848ca25eAjay Panicker * Get Logging info by application name 2823122e5171ef26ff487f10826786606df848ca25eAjay Panicker */ 2837a068c2a0861e12a3916cec313cf105395871999Ajay Panicker AppScanStats getAppScanStatsByName(String name) { 2847a068c2a0861e12a3916cec313cf105395871999Ajay Panicker return mAppScanStats.get(name); 2853122e5171ef26ff487f10826786606df848ca25eAjay Panicker } 2863122e5171ef26ff487f10826786606df848ca25eAjay Panicker 2873122e5171ef26ff487f10826786606df848ca25eAjay Panicker /** 28803b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta * Get the device addresses for all connected devices 28903b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta */ 29003b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta Set<String> getConnectedDevices() { 29103b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta Set<String> addresses = new HashSet<String>(); 29203b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta Iterator<Connection> i = mConnections.iterator(); 2938a0bc0a61e97f8923cb362e1dbb7ff66ffe51507Ajay Panicker while (i.hasNext()) { 29403b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta Connection connection = i.next(); 29503b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta addresses.add(connection.address); 29603b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta } 29703b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta return addresses; 29803b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta } 29903b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta 30003b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta /** 30103b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta * Get an application context by a connection ID. 30203b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta */ 30303b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta App getByConnId(int connId) { 30403b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta Iterator<Connection> ii = mConnections.iterator(); 3058a0bc0a61e97f8923cb362e1dbb7ff66ffe51507Ajay Panicker while (ii.hasNext()) { 30603b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta Connection connection = ii.next(); 30703b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta if (connection.connId == connId){ 30803b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta return getById(connection.appId); 30903b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta } 31003b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta } 31103b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta return null; 31203b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta } 31303b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta 31403b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta /** 31503b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta * Returns a connection ID for a given device address. 31603b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta */ 31703b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta Integer connIdByAddress(int id, String address) { 31803b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta App entry = getById(id); 31903b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta if (entry == null) return null; 32003b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta 32103b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta Iterator<Connection> i = mConnections.iterator(); 3228a0bc0a61e97f8923cb362e1dbb7ff66ffe51507Ajay Panicker while (i.hasNext()) { 32303b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta Connection connection = i.next(); 32403b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta if (connection.address.equals(address) && connection.appId == id) 32503b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta return connection.connId; 32603b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta } 32703b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta return null; 32803b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta } 32903b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta 33003b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta /** 33103b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta * Returns the device address for a given connection ID. 33203b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta */ 33303b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta String addressByConnId(int connId) { 33403b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta Iterator<Connection> i = mConnections.iterator(); 3358a0bc0a61e97f8923cb362e1dbb7ff66ffe51507Ajay Panicker while (i.hasNext()) { 33603b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta Connection connection = i.next(); 33703b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta if (connection.connId == connId) return connection.address; 33803b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta } 33903b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta return null; 34003b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta } 34103b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta 34203b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta List<Connection> getConnectionByApp(int appId) { 34303b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta List<Connection> currentConnections = new ArrayList<Connection>(); 34403b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta Iterator<Connection> i = mConnections.iterator(); 3458a0bc0a61e97f8923cb362e1dbb7ff66ffe51507Ajay Panicker while (i.hasNext()) { 34603b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta Connection connection = i.next(); 34703b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta if (connection.appId == appId) 34803b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta currentConnections.add(connection); 34903b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta } 35003b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta return currentConnections; 35103b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta } 35203b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta 35303b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta /** 35403b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta * Erases all application context entries. 35503b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta */ 35603b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta void clear() { 3576af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach synchronized (mApps) { 3586af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach Iterator<App> i = mApps.iterator(); 3598a0bc0a61e97f8923cb362e1dbb7ff66ffe51507Ajay Panicker while (i.hasNext()) { 3606af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach App entry = i.next(); 3616af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach entry.unlinkToDeath(); 3626af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach i.remove(); 3636af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach } 3646af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach } 3656af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach 3666af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach synchronized (mConnections) { 3676af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach mConnections.clear(); 3686af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach } 36903b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta } 37003b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta 37103b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta /** 372f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora * Returns connect device map with addr and appid 373f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora */ 374f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora Map<Integer, String> getConnectedMap(){ 375f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora Map<Integer, String> connectedmap = new HashMap<Integer, String>(); 376f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora for(Connection conn: mConnections){ 377f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora connectedmap.put(conn.appId, conn.address); 378f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora } 379f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora return connectedmap; 380f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora } 381f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora 382f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora /** 38303b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta * Logs debug information. 38403b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta */ 385a02de6484f9b6cac6b8c811edae11be55746b555Andre Eisenbach void dump(StringBuilder sb) { 3867a068c2a0861e12a3916cec313cf105395871999Ajay Panicker sb.append(" Entries: " + mAppScanStats.size() + "\n\n"); 3878a0bc0a61e97f8923cb362e1dbb7ff66ffe51507Ajay Panicker 3887a068c2a0861e12a3916cec313cf105395871999Ajay Panicker Iterator<Map.Entry<String, AppScanStats>> it = mAppScanStats.entrySet().iterator(); 3895c07523b0b5d32176d7ff3ab28555123123261ddAjay Panicker while (it.hasNext()) { 3907a068c2a0861e12a3916cec313cf105395871999Ajay Panicker Map.Entry<String, AppScanStats> entry = it.next(); 39103b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta 3928a0bc0a61e97f8923cb362e1dbb7ff66ffe51507Ajay Panicker String name = entry.getKey(); 3937a068c2a0861e12a3916cec313cf105395871999Ajay Panicker AppScanStats appScanStats = entry.getValue(); 3947a068c2a0861e12a3916cec313cf105395871999Ajay Panicker appScanStats.dumpToString(sb); 39503b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta } 39603b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta } 39703b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta} 398