blob: 13375e49f816f381997dfe106716a406a01a7318 [file] [log] [blame]
/******************************************************************************
*
* Copyright 2021 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************/
package com.android.bluetooth.groupclient;
import android.bluetooth.IBluetoothGroupCallback;
import android.bluetooth.BluetoothGroupCallback;
import android.os.Binder;
import android.os.IBinder;
import android.os.IInterface;
import android.os.RemoteException;
import android.util.Log;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Collections;
import java.util.concurrent.ConcurrentHashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Set;
import java.util.UUID;
/* This class keeps track of registered GroupClient applications and
* managing callbacks to be given to appropriate app or module */
public class GroupAppMap {
private static final String TAG = "BluetoothGroupAppMap";
class GroupClientApp {
/* The UUID of the application */
public UUID uuid;
/* The id of the application */
public int appId;
/* flag to determine if Bluetooth module has registered. */
public boolean isLocal;
/* Callbacks to be given to application */
public IBluetoothGroupCallback appCb;
/* Callbacks to be given to registered Bluetooth modules*/
public BluetoothGroupCallback mCallback;
public boolean isRegistered;
/** Death receipient */
private IBinder.DeathRecipient mDeathRecipient;
GroupClientApp(UUID uuid, boolean isLocal, IBluetoothGroupCallback appCb,
BluetoothGroupCallback localCallbacks) {
this.uuid = uuid;
this.isLocal = isLocal;
this.appCb = appCb;
this.mCallback = localCallbacks;
this.isRegistered = true;
appUuids.add(uuid);
}
/**
* To link death recipient
*/
void linkToDeath(IBinder.DeathRecipient deathRecipient) {
try {
IBinder binder = ((IInterface) appCb).asBinder();
binder.linkToDeath(deathRecipient, 0);
mDeathRecipient = deathRecipient;
} catch (RemoteException e) {
Log.e(TAG, "Unable to link deathRecipient for appId: " + appId);
}
}
}
List<GroupClientApp> mApps = Collections.synchronizedList(new ArrayList<GroupClientApp>());
ArrayList<UUID> appUuids = new ArrayList<UUID>();
/**
* Add an entry to the application list.
*/
GroupClientApp add(UUID uuid, boolean isLocal, IBluetoothGroupCallback appCb,
BluetoothGroupCallback localCallback) {
synchronized (mApps) {
GroupClientApp app = new GroupClientApp(uuid, isLocal, appCb, localCallback);
mApps.add(app);
return app;
}
}
/**
* Remove the entry for a given UUID
*/
void remove(UUID uuid) {
synchronized (mApps) {
Iterator<GroupClientApp> i = mApps.iterator();
while (i.hasNext()) {
GroupClientApp entry = i.next();
if (entry.uuid.equals(uuid)) {
entry.isRegistered = false;
i.remove();
break;
}
}
}
}
/**
* Remove the entry for a given application ID.
*/
void remove(int appId) {
synchronized (mApps) {
Iterator<GroupClientApp> i = mApps.iterator();
while (i.hasNext()) {
GroupClientApp entry = i.next();
if (entry.appId == appId) {
entry.isRegistered = false;
i.remove();
break;
}
}
}
}
/**
* Get GroupClient application by UUID.
*/
GroupClientApp getByUuid(UUID uuid) {
synchronized (mApps) {
Iterator<GroupClientApp> i = mApps.iterator();
while (i.hasNext()) {
GroupClientApp entry = i.next();
if (entry.uuid.equals(uuid)) {
return entry;
}
}
}
Log.e(TAG, "App not found for UUID " + uuid);
return null;
}
/**
* Get a GroupClient application by appId.
*/
GroupClientApp getById(int appId) {
synchronized (mApps) {
Iterator<GroupClientApp> i = mApps.iterator();
while (i.hasNext()) {
GroupClientApp entry = i.next();
if (entry.appId == appId) {
return entry;
}
}
}
Log.e(TAG, "GroupClient App not found for appId " + appId);
return null;
}
}