ContextMap.java revision a02de6484f9b6cac6b8c811edae11be55746b555
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
186af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbachimport android.os.IBinder;
196af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbachimport android.os.IBinder.DeathRecipient;
206af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbachimport android.os.IInterface;
216af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbachimport android.os.RemoteException;
2203b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Battaimport android.util.Log;
2303b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Battaimport java.util.ArrayList;
246af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbachimport java.util.HashSet;
2503b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Battaimport java.util.Iterator;
2603b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Battaimport java.util.List;
276af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbachimport java.util.NoSuchElementException;
2803b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Battaimport java.util.Set;
2903b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Battaimport java.util.UUID;
3003b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta
3103b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta/**
3203b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta * Helper class that keeps track of registered GATT applications.
3303b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta * This class manages application callbacks and keeps track of GATT connections.
3403b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta * @hide
3503b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta */
3603b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta/*package*/ class ContextMap<T> {
3703b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta    private static final String TAG = GattServiceConfig.TAG_PREFIX + "ContextMap";
3803b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta
3903b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta    /**
4003b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta     * Connection class helps map connection IDs to device addresses.
4103b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta     */
4203b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta    class Connection {
4303b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta        int connId;
4403b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta        String address;
4503b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta        int appId;
4603b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta
4703b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta        Connection(int connId, String address,int appId) {
4803b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta            this.connId = connId;
4903b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta            this.address = address;
5003b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta            this.appId = appId;
5103b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta        }
5203b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta    }
5303b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta
5403b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta    /**
5503b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta     * Application entry mapping UUIDs to appIDs and callbacks.
5603b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta     */
5703b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta    class App {
5803b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta        /** The UUID of the application */
5903b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta        UUID uuid;
6003b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta
6103b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta        /** The id of the application */
6203b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta        int id;
6303b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta
6403b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta        /** Application callbacks */
6503b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta        T callback;
6603b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta
676af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach        /** Death receipient */
686af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach        private IBinder.DeathRecipient mDeathRecipient;
696af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach
70934dee789c0c68607a704c5c31ae2e4b956dc227Prerepa Viswanadham        /** Flag to signal that transport is congested */
71934dee789c0c68607a704c5c31ae2e4b956dc227Prerepa Viswanadham        Boolean isCongested = false;
72934dee789c0c68607a704c5c31ae2e4b956dc227Prerepa Viswanadham
73934dee789c0c68607a704c5c31ae2e4b956dc227Prerepa Viswanadham        /** Internal callback info queue, waiting to be send on congestion clear */
74934dee789c0c68607a704c5c31ae2e4b956dc227Prerepa Viswanadham        private List<CallbackInfo> congestionQueue = new ArrayList<CallbackInfo>();
75934dee789c0c68607a704c5c31ae2e4b956dc227Prerepa Viswanadham
7603b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta        /**
7703b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta         * Creates a new app context.
7803b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta         */
7903b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta        App(UUID uuid, T callback) {
8003b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta            this.uuid = uuid;
8103b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta            this.callback = callback;
8203b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta        }
836af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach
846af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach        /**
856af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach         * Link death recipient
866af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach         */
876af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach        void linkToDeath(IBinder.DeathRecipient deathRecipient) {
886af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach            try {
896af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach                IBinder binder = ((IInterface)callback).asBinder();
906af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach                binder.linkToDeath(deathRecipient, 0);
916af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach                mDeathRecipient = deathRecipient;
926af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach            } catch (RemoteException e) {
936af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach                Log.e(TAG, "Unable to link deathRecipient for app id " + id);
946af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach            }
956af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach        }
966af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach
976af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach        /**
986af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach         * Unlink death recipient
996af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach         */
1006af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach        void unlinkToDeath() {
1016af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach            if (mDeathRecipient != null) {
1026af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach                try {
1036af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach                    IBinder binder = ((IInterface)callback).asBinder();
1046af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach                    binder.unlinkToDeath(mDeathRecipient,0);
1056af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach                } catch (NoSuchElementException e) {
1066af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach                    Log.e(TAG, "Unable to unlink deathRecipient for app id " + id);
1076af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach                }
1086af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach            }
1096af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach        }
110934dee789c0c68607a704c5c31ae2e4b956dc227Prerepa Viswanadham
111934dee789c0c68607a704c5c31ae2e4b956dc227Prerepa Viswanadham        void queueCallback(CallbackInfo callbackInfo) {
112934dee789c0c68607a704c5c31ae2e4b956dc227Prerepa Viswanadham            congestionQueue.add(callbackInfo);
113934dee789c0c68607a704c5c31ae2e4b956dc227Prerepa Viswanadham        }
114934dee789c0c68607a704c5c31ae2e4b956dc227Prerepa Viswanadham
115934dee789c0c68607a704c5c31ae2e4b956dc227Prerepa Viswanadham        CallbackInfo popQueuedCallback() {
116934dee789c0c68607a704c5c31ae2e4b956dc227Prerepa Viswanadham            if (congestionQueue.size() == 0) return null;
117934dee789c0c68607a704c5c31ae2e4b956dc227Prerepa Viswanadham            return congestionQueue.remove(0);
118934dee789c0c68607a704c5c31ae2e4b956dc227Prerepa Viswanadham        }
11903b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta    }
12003b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta
12103b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta    /** Our internal application list */
12203b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta    List<App> mApps = new ArrayList<App>();
12303b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta
12403b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta    /** Internal list of connected devices **/
12503b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta    Set<Connection> mConnections = new HashSet<Connection>();
12603b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta
12703b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta    /**
12803b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta     * Add an entry to the application context list.
12903b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta     */
13003b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta    void add(UUID uuid, T callback) {
1316af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach        synchronized (mApps) {
1326af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach            mApps.add(new App(uuid, callback));
1336af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach        }
13403b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta    }
13503b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta
13603b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta    /**
13703b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta     * Remove the context for a given application ID.
13803b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta     */
13903b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta    void remove(int id) {
1406af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach        synchronized (mApps) {
1416af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach            Iterator<App> i = mApps.iterator();
1426af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach            while(i.hasNext()) {
1436af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach                App entry = i.next();
1446af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach                if (entry.id == id) {
1456af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach                    entry.unlinkToDeath();
1466af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach                    i.remove();
1476af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach                    break;
1486af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach                }
14903b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta            }
15003b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta        }
15103b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta    }
15203b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta
15303b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta    /**
15403b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta     * Add a new connection for a given application ID.
15503b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta     */
15603b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta    void addConnection(int id, int connId, String address) {
1576af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach        synchronized (mConnections) {
1586af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach            App entry = getById(id);
1596af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach            if (entry != null){
1606af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach                mConnections.add(new Connection(connId, address, id));
1616af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach            }
16203b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta        }
16303b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta    }
16403b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta
16503b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta    /**
16603b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta     * Remove a connection with the given ID.
16703b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta     */
16803b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta    void removeConnection(int id, int connId) {
1696af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach        synchronized (mConnections) {
1706af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach            Iterator<Connection> i = mConnections.iterator();
1716af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach            while(i.hasNext()) {
1726af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach                Connection connection = i.next();
1736af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach                if (connection.connId == connId) {
1746af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach                    i.remove();
1756af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach                    break;
1766af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach                }
17703b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta            }
17803b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta        }
17903b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta    }
18003b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta
18103b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta    /**
18203b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta     * Get an application context by ID.
18303b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta     */
18403b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta    App getById(int id) {
18503b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta        Iterator<App> i = mApps.iterator();
18603b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta        while(i.hasNext()) {
18703b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta            App entry = i.next();
18803b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta            if (entry.id == id) return entry;
18903b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta        }
19003b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta        Log.e(TAG, "Context not found for ID " + id);
19103b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta        return null;
19203b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta    }
19303b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta
19403b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta    /**
19503b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta     * Get an application context by UUID.
19603b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta     */
19703b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta    App getByUuid(UUID uuid) {
19803b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta        Iterator<App> i = mApps.iterator();
19903b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta        while(i.hasNext()) {
20003b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta            App entry = i.next();
20103b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta            if (entry.uuid.equals(uuid)) return entry;
20203b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta        }
20303b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta        Log.e(TAG, "Context not found for UUID " + uuid);
20403b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta        return null;
20503b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta    }
20603b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta
20703b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta    /**
20803b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta     * Get the device addresses for all connected devices
20903b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta     */
21003b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta    Set<String> getConnectedDevices() {
21103b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta        Set<String> addresses = new HashSet<String>();
21203b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta        Iterator<Connection> i = mConnections.iterator();
21303b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta        while(i.hasNext()) {
21403b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta            Connection connection = i.next();
21503b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta            addresses.add(connection.address);
21603b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta        }
21703b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta        return addresses;
21803b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta    }
21903b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta
22003b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta    /**
22103b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta     * Get an application context by a connection ID.
22203b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta     */
22303b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta    App getByConnId(int connId) {
22403b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta        Iterator<Connection> ii = mConnections.iterator();
22503b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta        while(ii.hasNext()) {
22603b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta            Connection connection = ii.next();
22703b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta            if (connection.connId == connId){
22803b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta                return getById(connection.appId);
22903b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta            }
23003b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta        }
23103b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta        return null;
23203b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta    }
23303b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta
23403b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta    /**
23503b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta     * Returns a connection ID for a given device address.
23603b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta     */
23703b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta    Integer connIdByAddress(int id, String address) {
23803b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta        App entry = getById(id);
23903b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta        if (entry == null) return null;
24003b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta
24103b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta        Iterator<Connection> i = mConnections.iterator();
24203b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta        while(i.hasNext()) {
24303b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta            Connection connection = i.next();
24403b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta            if (connection.address.equals(address) && connection.appId == id)
24503b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta                return connection.connId;
24603b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta        }
24703b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta        return null;
24803b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta    }
24903b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta
25003b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta    /**
25103b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta     * Returns the device address for a given connection ID.
25203b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta     */
25303b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta    String addressByConnId(int connId) {
25403b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta        Iterator<Connection> i = mConnections.iterator();
25503b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta        while(i.hasNext()) {
25603b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta            Connection connection = i.next();
25703b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta            if (connection.connId == connId) return connection.address;
25803b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta        }
25903b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta        return null;
26003b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta    }
26103b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta
26203b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta    List<Connection> getConnectionByApp(int appId) {
26303b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta        List<Connection> currentConnections = new ArrayList<Connection>();
26403b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta        Iterator<Connection> i = mConnections.iterator();
26503b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta        while(i.hasNext()) {
26603b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta            Connection connection = i.next();
26703b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta            if (connection.appId == appId)
26803b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta                currentConnections.add(connection);
26903b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta        }
27003b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta        return currentConnections;
27103b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta    }
27203b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta
27303b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta    /**
27403b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta     * Erases all application context entries.
27503b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta     */
27603b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta    void clear() {
2776af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach        synchronized (mApps) {
2786af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach            Iterator<App> i = mApps.iterator();
2796af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach            while(i.hasNext()) {
2806af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach                App entry = i.next();
2816af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach                entry.unlinkToDeath();
2826af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach                i.remove();
2836af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach            }
2846af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach        }
2856af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach
2866af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach        synchronized (mConnections) {
2876af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach            mConnections.clear();
2886af1f25031e4378efb1a4fc286974c1038a357baAndre Eisenbach        }
28903b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta    }
29003b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta
29103b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta    /**
29203b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta     * Logs debug information.
29303b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta     */
294a02de6484f9b6cac6b8c811edae11be55746b555Andre Eisenbach    void dump(StringBuilder sb) {
295a02de6484f9b6cac6b8c811edae11be55746b555Andre Eisenbach        sb.append("  Entries: " + mApps.size() + "\n");
29603b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta
29703b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta        Iterator<App> i = mApps.iterator();
29803b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta        while(i.hasNext()) {
29903b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta            App entry = i.next();
30003b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta            List<Connection> connections = getConnectionByApp(entry.id);
30103b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta
302a02de6484f9b6cac6b8c811edae11be55746b555Andre Eisenbach            sb.append("\n  Application Id: " + entry.id + "\n");
303a02de6484f9b6cac6b8c811edae11be55746b555Andre Eisenbach            sb.append("  UUID: " + entry.uuid + "\n");
304a02de6484f9b6cac6b8c811edae11be55746b555Andre Eisenbach            sb.append("  Connections: " + connections.size() + "\n");
30503b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta
30603b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta            Iterator<Connection> ii = connections.iterator();
30703b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta            while(ii.hasNext()) {
30803b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta                Connection connection = ii.next();
309a02de6484f9b6cac6b8c811edae11be55746b555Andre Eisenbach                sb.append("    " + connection.connId + ": " + connection.address + "\n");
31003b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta            }
31103b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta        }
31203b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta    }
31303b8386de26ba6500af2d66687bff9b01f2cbbd7Ganesh Ganapathi Batta}
314