Android-UWB——UwbManager

发布时间:2023年12月20日

在前面的文章中,介绍了Android实现UWB的相关框架以及示例程序,在后续的章节中,将从Android源码角度来逐步解析UWB相关实现。

?UwbManager介绍

随着官方 Android API 的引入,开发者将能够创建在配备 UWB 硬件的不同 Android 智能手机上无缝工作的应用,而不是使用来自不同 OEM 厂商的不同套装 API。

目前谷歌已经将UWB相关内容放在Android 开源项目(AOSP)中,增加了一个超宽带(UWB)系统API。例如,UwbManager 类 “提供了一种执行 UWB 操作的方法,例如查询设备的能力,确定本地设备和远程设备之间的距离和角度”。API 的实现遵循 IEEE 的 802.15.4z 标准,用于低速率无线网络。(整体为FiRa标准,关于FiRa标准可以查看之前的文章)

到2023年4月,拥有超宽带(UWB)硬件的安卓设备包括三星 Galaxy Note 20, S21+, S22+, Z Fold 2, 3, 4,Google Pixel 6 Pro, Pixel 7 Pro,而使用这一硬件的应用只有三星的 SmartThings 应用的 SmartThings Find 功能。

整体而言,Android UWB 目前仍处于起步阶段,虽然它有望带来巨大的可能性,但其在现实世界中的作用和应用还没有充分实现。随着官方 Android API 的引入,开发者将能够创建在配备 UWB 硬件的不同 Android 智能手机上无缝工作的应用,而不是使用来自不同 OEM 厂商的不同套装 API。

跟踪官方的相关平台文档,可以查到,目前已经可以在android开发平台找到相关接口的文档:

UwbManager ?|? Android Developers

相关的开发内容包括:`androidx.core.uwb`、`androidx.core.uwb.exception`。

UwbManager实现

关于UwbManager的定义也在包:android.uwb中。

@SystemApi
@SystemService(Context.UWB_SERVICE)
public final class UwbManager {
    private static final String TAG = "UwbManager";

    private final Context mContext;
    private final IUwbAdapter mUwbAdapter;
    private final AdapterStateListener mAdapterStateListener;
    private final RangingManager mRangingManager;
    private final UwbVendorUciCallbackListener mUwbVendorUciCallbackListener;
    private final UwbOemExtensionCallbackListener mUwbOemExtensionCallbackListener;

    /**
     * Interface for receiving UWB adapter state changes
     */
    public interface AdapterStateCallback {
        // UWB adapter状态改变接口
    }

    /**
     * 抽象类用于接收ADF provision state,需被应用扩展
     */
    public abstract static class AdfProvisionStateCallback {
        private final AdfProvisionStateCallbackProxy mAdfProvisionStateCallbackProxy;

        public AdfProvisionStateCallback() {
            mAdfProvisionStateCallbackProxy = new AdfProvisionStateCallbackProxy();
        }
        //...
        private static class AdfProvisionStateCallbackProxy extends
                IUwbAdfProvisionStateCallbacks.Stub {
            //AIDL接口
        }
    }

    /**
     * Interface for receiving vendor UCI responses and notifications.
     * 接收供应商UCI响应和通知,由上层应用发送命令
     */
    public interface UwbVendorUciCallback {
        void onVendorUciResponse(
            @IntRange(from = 0, to = 15) int gid, int oid, @NonNull byte[] payload);
        void onVendorUciNotification(
            @IntRange(from = 9, to = 15) int gid, int oid, @NonNull byte[] payload);
    }


    @RequiresApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
    public interface UwbOemExtensionCallback {
        //Oem扩展接口
    }

    public UwbManager(@NonNull Context ctx, @NonNull IUwbAdapter adapter) {
        mContext = ctx;
        mUwbAdapter = adapter;
        mAdapterStateListener = new AdapterStateListener(adapter);
        mRangingManager = new RangingManager(adapter);
        mUwbVendorUciCallbackListener = new UwbVendorUciCallbackListener(adapter);
        mUwbOemExtensionCallbackListener = new UwbOemExtensionCallbackListener(adapter);
    }

    //均需要有UWB权限
    @RequiresPermission(permission.UWB_PRIVILEGED)
    public void registerAdapterStateCallback(@NonNull @CallbackExecutor Executor executor,
            @NonNull AdapterStateCallback callback) {
        mAdapterStateListener.register(executor, callback);
    }

    @RequiresPermission(permission.UWB_PRIVILEGED)
    public void unregisterAdapterStateCallback(@NonNull AdapterStateCallback callback) {
        mAdapterStateListener.unregister(callback);
    }

    @RequiresPermission(permission.UWB_PRIVILEGED)
    public void registerUwbVendorUciCallback(@NonNull @CallbackExecutor Executor executor,
            @NonNull UwbVendorUciCallback callback) {
        mUwbVendorUciCallbackListener.register(executor, callback);
    }

    public void unregisterUwbVendorUciCallback(@NonNull UwbVendorUciCallback callback) {
        mUwbVendorUciCallbackListener.unregister(callback);
    }
    //...
    @NonNull
    @RequiresPermission(allOf = {
            permission.UWB_PRIVILEGED,
            permission.UWB_RANGING
    })
    public CancellationSignal openRangingSession(@NonNull PersistableBundle parameters,
            @NonNull @CallbackExecutor Executor executor,
            @NonNull RangingSession.Callback callbacks) {
        return openRangingSessionInternal(parameters, executor, callbacks, /* chipId= */ null);
    }

	/* 用户可调用禁止或使能UWB */
    @RequiresPermission(permission.UWB_PRIVILEGED)
    public void setUwbEnabled(boolean enabled) {
        mAdapterStateListener.setEnabled(enabled);
    }

    /* 返回UWB Chip的信息,通过HAL接口来获取 */
    @RequiresPermission(permission.UWB_PRIVILEGED)
    @NonNull
    public List<PersistableBundle> getChipInfos() {
        try {
            return mUwbAdapter.getChipInfos();
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }

	/* 注册UWB服务profile */
    @RequiresPermission(permission.UWB_PRIVILEGED)
    @NonNull
    public PersistableBundle addServiceProfile(@NonNull PersistableBundle parameters) {
        try {
            return mUwbAdapter.addServiceProfile(parameters);
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }


    /**
     * 发送供应商定义UCI消息
     * UCI消息格式参考UCI规范,如有必要,平台需负责对有效载荷的分包(fragment)。
     */
    @NonNull
    @RequiresPermission(permission.UWB_PRIVILEGED)
    public @SendVendorUciStatus int sendVendorUciMessage(
            @IntRange(from = 0, to = 15) int gid, int oid, @NonNull byte[] payload) {
        Objects.requireNonNull(payload, "Payload must not be null");
        try {
            return mUwbAdapter.sendVendorUciMessage(MESSAGE_TYPE_COMMAND, gid, oid, payload);
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }

    @Retention(RetentionPolicy.SOURCE)
    @IntDef(value = {
            MESSAGE_TYPE_COMMAND,
            MESSAGE_TYPE_TEST_1,
            MESSAGE_TYPE_TEST_2,
    })
    @interface MessageType {}
    
    /**
     * 自定义类型供应商定义UCI消息
     * 注意:消息类型(mt)是在方法参数的开头添加的,因此比其他参数更独特,且是供应商要求的。
     */
    @NonNull
    @RequiresApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
    @RequiresPermission(permission.UWB_PRIVILEGED)
    public @SendVendorUciStatus int sendVendorUciMessage(@MessageType int mt,
            @IntRange(from = 0, to = 15) int gid, int oid, @NonNull byte[] payload) {
        Objects.requireNonNull(payload, "Payload must not be null");
        try {
            return mUwbAdapter.sendVendorUciMessage(mt, gid, oid, payload);
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }

    private static class OnUwbActivityEnergyInfoProxy
            extends IOnUwbActivityEnergyInfoListener.Stub {
        //AIDL接口实现
    }
    
}

????????从注释上我们可以看到,UwbManager提供了一种执行超宽带(UWB)操作的方法,例如查询设备的能力,以及确定本地设备和远程设备的距离以及角度。

????????API surface使用不透明的参数。这些参数将使用所提供的UWB支持库创建。支持库在AOSP:package/modules/Uwb/service/support_lib

????????要获取UwbManager,可以通过Context.getSystemServie(UwbManager.class)来实现。

关于openRangingSession

如果会话使用FiRa定义的配置文件(而不是自定义配置文件),则会触发:

  • 使用service UUID开启OOB发现
  • 在发现会话参数协商之后,建立OOB连接
  • 建立基于动态STS的FiRa会话,需要Secure Element交互
  • 根据OOB协商的参数配置UWB会话。
  • 注意:OOB流程需要获取BLE权限
  • permission.BLUETOOTH_ADVERTISE
    permission.BLUETOOTH_SCAN
    permission.BLUETOOTH_CONNECT

若会话不能打开,则会触发适当的原因。RangingSession.Callback.Reason

关于参数限定为PersistableBundle,必须使用UWB支持库,以构造对应参数,定义测距会话。

根据前文介绍的Android-UWB技术框架,在UwbManager之后,就是UWB Service,将陆续在后续的文章中进行分析。

文章来源:https://blog.csdn.net/luo58614013/article/details/132774769
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。