Uwb会话的管理是整个UWB测距中比较重要的部分,也是Android UWB服务实现的一个重点,本文首先简要介绍会话管理中相关消息处理的框架、多会话处理的调用。
Uwb会话管理
UwbSessionManager
实现INativeUwbManager.SessionNotification
会话通知接口,以便实现会话管理,会话相关通知均可以得到处理,进而维护与管理测距会话。同时,在会话管理类的实现中,直接创建了会话mSessionTable
,以用于管理多会话。
public class UwbSessionManager implements INativeUwbManager.SessionNotification,
ActivityManager.OnUidImportanceListener {
//...
@VisibleForTesting
final ConcurrentHashMap<SessionHandle, UwbSession> mSessionTable = new ConcurrentHashMap();
final ConcurrentHashMap<Integer, List<UwbSession>> mNonPrivilegedUidToFiraSessionsTable =
new ConcurrentHashMap();
final ConcurrentHashMap<Integer, Integer> mSessionTokenMap = new ConcurrentHashMap<>();
// 构造函数
public UwbSessionManager(
UwbConfigurationManager uwbConfigurationManager,
NativeUwbManager nativeUwbManager, UwbMetrics uwbMetrics,
UwbAdvertiseManager uwbAdvertiseManager,
UwbSessionNotificationManager uwbSessionNotificationManager,
UwbInjector uwbInjector, AlarmManager alarmManager, ActivityManager activityManager,
Looper serviceLooper) {
mNativeUwbManager = nativeUwbManager;
mNativeUwbManager.setSessionListener(this);
mUwbMetrics = uwbMetrics;
mAdvertiseManager = uwbAdvertiseManager;
mConfigurationManager = uwbConfigurationManager;
mSessionNotificationManager = uwbSessionNotificationManager;
mUwbInjector = uwbInjector;
mAlarmManager = alarmManager;
mActivityManager = activityManager;
mLooper = serviceLooper;
mEventTask = new EventTask(serviceLooper);
registerUidImportanceTransitions(); //注册UID事务,通过ActivityManager
}
// Detect UIDs going foreground/background
private void registerUidImportanceTransitions() {
mActivityManager.addOnUidImportanceListener(
UwbSessionManager.this, IMPORTANCE_FOREGROUND_SERVICE);
}
}
从构造函数来看,需要UWB配置管理器、本地UWB管理器、UWB度量类(UwbMetrics)、UWB广播管理器、UWB会话通知管理器等。
其中,EventTask为事件任务,为自定义的类:
private class EventTask extends Handler {
EventTask(Looper looper) {
super(looper);
}
@Override
public void handleMessage(Message msg) {
int type = msg.what;
//提供消息处理,包括:
// 1. SESSION_OPEN_RANGING
// 2. SESSION_START_RANGING
// 3. SESSION_STOP_RANGING
// 4. SESSION_RECONFIG_RANGING
// 5. SESSION_DEINIT,对应处理函数:handleDeInitWithReason
case SESSION_DEINIT: {
//通过消息获取类型、获取UwbSession,进行处理
UwbSession uwbSession = (UwbSession) msg.obj;
int reason = msg.arg1;
handleDeInitWithReason(uwbSession, reason);
break;
}
// 6. SESSION_ON_DEINIT
// 7. SESSION_SEND_DATA
// 8. SESSION_UPDATE_DT_TAG_RANGING_ROUNDS, 更新下行标签
}
// 执行,获取消息,向消息队列发送消息
public void execute(int task, Object obj) {
Message msg = mEventTask.obtainMessage();
msg.what = task;
msg.obj = obj;
this.sendMessage(msg);
}
public void execute(int task, Object obj, int arg1) {
Message msg = mEventTask.obtainMessage();
msg.what = task;
msg.obj = obj;
msg.arg1 = arg1;
this.sendMessage(msg);
}
}
关于事件任务handleTask相关处理,都通过FutureTask
来定义,通过UwbInjector类,来执行。
以下以handleDeInitWithReason
中的FutureTask异步任务实现为例进行分析:
//定义FutureTask
FutureTask<Integer> deInitTask = new FutureTask<>(
(Callable<Integer>) () -> {
int status = UwbUciConstants.STATUS_CODE_FAILED;
synchronized (uwbSession.getWaitObj()) { //实现线程同步,互斥资源等,以下为同步代码块
status = mNativeUwbManager.deInitSession(uwbSession.getSessionId(), uwbSession.getChipId());
if (status != UwbUciConstants.STATUS_CODE_OK) {
mSessionNotificationManager.onRangingClosed(uwbSession, status);
return status;
}
uwbSession.getWaitObj().blockingWait();
}
return status;
});
//deInitTask 返回执行状态
//通过UwbInjector类,模拟执行器执行Task,返回值为task.get()
status = mUwbInjector.runTaskOnSingleThreadExecutor(deInitTask,
IUwbAdapter.RANGING_SESSION_CLOSE_THRESHOLD_MS);
Android基础补充
由于在Android UWB的实现中,涉及了较多的多线程、异步任务、消息处理机制相关的内容,在此,进行简单的基础知识的补充。
Handler与Looper
Handler是Android提供的一种机制,用于在不同的线程之间发送和处理消息。每个Handler对象都关联一个特定的Looper和一个消息队列,通过Handler,可以将消息发送到消息队列,并在关联的Looper执行消息时进行处理。
Looper是一个用于管理线程消息循环的类,每个线程只能有一个Looper,负责维护线程的消息队列并按顺序处理消息。通过Looper.prepare和Looper.loop,可以在线程中准备Looper并启动消息循环。
Looper.prepare(); // 准备 Looper
Handler handler = new Handler();
// 执行其他操作,如创建 Handler、注册消息处理逻辑等
Looper.loop(); // 启动消息循环
在Android UWB的实现中,EventTask继承自Handler。
在应用中,Handler通过obtainMessage
方法,获取一个Message对象。
public final Message obtainMessage()
Message用于发送和处理消息,封装线程之间的传递的信息和指令。
通过handler.sendMessage(message)
来发送消息。sendMessage()方法可以将消息发送到Handler关联的消息队列中,以便在Handler所在的线程中被处理。处理消息时,调用handleMessage()方法。可以看到,在UWB会话管理中,关于会话相应状态的处理都在handlerMessage内部实现,根据不同的消息类型,执行相应的处理。
处理接收消息:
@Override
public void handleMessage(Message msg) {
int type = msg.what;
}
ActivityManager
ActivityManager是Android系统中的一个重要类,提供了应用程序和活动的管理,android.app.ActivityManager
。
ActivityManager的主要职责包括:
- 管理应用程序的生命周期:ActivityManager 负责跟踪应用程序的状态和生命周期。它可以启动、停止、销毁应用程序的组件,如活动、服务和广播接收器。
- 管理活动(Activity):ActivityManager 可以启动、停止、重启、销毁和管理活动的任务栈。它可以管理活动的堆栈顺序,切换活动之间的转换,并处理活动之间的通信和交互。
- 启动应用程序和服务:ActivityManager 可以启动应用程序的活动和服务组件。它允许应用程序之间相互启动活动,并启动和管理后台服务。
- 获取设备信息:ActivityManager 可以提供关于设备的信息,如可用内存、运行中的进程和服务等。这些信息可以用于优化应用程序的性能和资源管理。
- 监控应用程序的使用情况:ActivityManager 可以监视应用程序的使用情况和状态。它可以提供有关正在运行的应用程序、内存使用情况、电池状态等信息。
FutureTask
FutureTask是Java中java.util.concurrent
包提供的一个类,实现Future接口和Runnable接口,用于表示一个可获取结果的异步任务。
主要支持:
- 异步执行任务:可在单独线程中执行,不会阻塞当前线程;
- 获取任务结果:任务可以有返回值(Callable),通过调用get()方法获取任务的执行结果;
- 取消任务:支持任务的取消,通过cancel方法可以请求取消任务执行;
- 状态查询:通过isDone()判断是否完成;isCancelled()判断任务是否已取消。
在执行相关状态的处理时,通过以下来实现FutureTask的执行。
//通过UwbInjector类,模拟执行器执行Task,返回值为task.get()
status = mUwbInjector.runTaskOnSingleThreadExecutor(deInitTask,
IUwbAdapter.RANGING_SESSION_CLOSE_THRESHOLD_MS);
//在UwbInjector.java的实现中,可以看到线程按照以下的方式执行
/* Helps to mock the executor for tests */
public int runTaskOnSingleThreadExecutor(FutureTask<Integer> task, int timeoutMs)
throws InterruptedException, TimeoutException, ExecutionException {
ExecutorService executor = Executors.newSingleThreadExecutor();
executor.submit(task);
try {
return task.get(timeoutMs, TimeUnit.MILLISECONDS);
} catch (TimeoutException e) {
executor.shutdownNow();
throw e;
}
}