简介

DeviceManager组件在OpenHarmony上提供账号无关的分布式设备的认证组网能力,并为开发者提供了一套用于分布式设备间监听、发现和认证的接口。
其组成及依赖如下所示:

img

目录

foundation/distributedhardware/distributedhardware_device_manager
├── common                        # 公共能力头文件存放目录
│   ├── include
│   │   ├── dfx                   # dfx功能头文件存放目录
│   │   └── ipc                   # ipc功能头文件存放目录
│   │       ├── lite              # small
│   │       ├── model             # ipc功能模块头文件存放目录
│   │       └── standard          # standard
│   └── src
│       ├── dfx                   # dfx功能实现相关代码
│       └── ipc                   # ipc公共功能代码
│           ├── lite              # small
│           └── standard          # standard
├── display                       # DM显示hap代码
│   └── entry
│       └── src
│           └── main
│               ├── js            # DM PIN码显示ServiceExtensionAbility相关JS代码
│               └── resources     # DM PIN码显示ServiceExtensionAbility相关资源配置文件目录
├── figures
├── interfaces
│   ├── inner_kits                # 内部接口及实现存放目录
│   │   └── native_cpp            # 内部native接口及实现存放目录
│   │       ├── include
│   │       │   ├── ipc           # ipc头文件存放目录
│   │       │   │   ├── lite      # small
│   │       │   │   └── standard  # standard
│   │       │   └── notify        # ipc回调通知头文件目录
│   │       └── src
│   │           ├── ipc           # ipc功能代码
│   │           │   ├── lite      # small
│   │           │   └── standard  # standard
│   │           └── notify        # ipc回调通知功能代码
│   └── kits                      # 外部接口及实现存放目录
│       ├── js                    # 外部JS接口及实现存放目录
│       │   ├── include           # 外部JS接口及实现头文件存放目录
│       │   └── src               # 外部JS接口及实现代码
|       └── js4.0                 # 从Openharmony 4.0.9.2版本开始新增外部JS接口及实现存放目录
|           ├── include           # 新增外部JS接口及实现头文件存放目录
|           └── src               # 新增外部JS接口及实现代码
|
├── sa_profile                    # SA进程配置相关文件存放目录
├── services
│   ├── implementation            # devicemanagerservice服务实现核心代码
│   │   ├── include
│   │   │   ├── ability           # 与PIN码显示ServiceExtensionAbility拉起管理相关头文件
│   │   │   ├── adapter           # DM适配扩展功能相关头文件
│   │   │   ├── authentication    # device_auth交互相关头文件
│   │   │   ├── config            # DM适配扩展相关配置功能头文件
│   │   │   ├── credential        # 凭据管理功能相关头文件
│   │   │   ├── dependency        # 外部依赖模块相关头文件
│   │   │   │   ├── commonevent   # 事件处理功能相关头文件
│   │   │   │   ├── hichain       # 与hichain功能交互相关头文件
│   │   │   │   ├── mini          # mini
│   │   │   │   ├── multipleuser  # 多用户功能相关头文件
│   │   │   │   ├── softbus       # 与软总线功能交互相关头文件
│   │   │   │   └── timer         # 定时器处理相关头文件
│   │   │   ├── devicestate       # 设备状态管理功能相关头文件
│   │   │   ├── discovery         # 设备发现功能相关头文件
│   │   │   ├── dispath           # L0上功能实现相关头文件
│   │   │   └── publish           # 设备主动发现功能相关头文件
│   │   └── src
│   │       ├── ability           # 与PIN码显示ServiceExtensionAbility拉起管理相关功能代码
│   │       ├── adapter           # DM适配扩展功能代码
│   │       ├── authentication    # device_auth交互相关核心代码
│   │       ├── config            # DM适配扩展相关配置功能代码
│   │       ├── credential        # 凭据管理功能代码
│   │       ├── dependency        # 外部依赖模块功能代码
│   │       │   ├── commonevent   # 事件处理功能代码
│   │       │   ├── hichain       # 与hichain功能交互代码
│   │       │   ├── mini          # mini
│   │       │   ├── multipleuser  # 多用户功能代码
│   │       │   ├── softbus       # 与软总线功能交互代码
│   │       │   └── timer         # 定时器处理相关功能代码
│   │       ├── devicestate       # 设备状态管理功能代码
│   │       ├── discovery         # 设备发现功能代码
│   │       ├── dispath           # mini上功能实现代码
│   │       └── publish           # 设备主动发现功能
│   └── service                   # devicemanagerservice服务实现核心代码
│       ├── include
│       │   ├── ipc               # 进程间通信相关头文件
│       │   │   ├── lite          # small
│       │   │   └── standard      # standard
│       │   └── softbus           # 软总线相关头文件
│       └── src
│           ├── ipc               # 进程间通信相关功能代码
│           │   ├── lite          # small
│           │   └── standard      # standard
│           └── softbus           # 通道建立功能核心代码
└── utils                         # 公共能力头文件存放目录
    ├── include
    │   ├── fwkload               # 拉起其他sa功能相关头文件
    │   └── permission            # 权限校验相关头文件存放目录
    └── src
        ├── fwkload               # 拉起其他sa功能相关功能代码
        └── permission            # 权限校验相关功能代码

接口说明

接口参见interface_sdk-js仓库的 ohos.distributedDeviceManager.d.ts

  • 调用以下接口,需要申请ohos.permission.DISTRIBUTED_DATASYNC权限才能正常调用。
  • 使用DeviceManager相关接口之前,需要通过createDeviceManager接口创建DeviceManager实例;
  • 不使用DeviceManager接口的时候需要释放对应的DeviceManager实例。
  • 提供可信设备列表获取、可信设备状态监听、周边设备发现、设备认证等相关接口,支持三方应用调用。

下面罗列常用的接口

原型描述
createDeviceManager(bundleName: string): DeviceManager;创建一个设备管理实例。设备管理实例是分布式设备管理方法的调用入口。用于获取可信设备和本地设备的相关信息。
releaseDeviceManager(deviceManager: DeviceManager): void;设备管理实例不再使用后,通过该方法释放DeviceManager实例。
getAvailableDeviceListSync(): Array<DeviceBasicInfo>;同步获取所有可信设备列表。
getAvailableDeviceList(): Promise<Array<DeviceBasicInfo>>;获取所有可信设备列表。使用Promise异步回调。
startDiscovering(discoverParam: {[key: string]: Object} , filterOptions?: {[key: string]: Object} ): void;发现周边设备。发现状态持续两分钟,超过两分钟,会停止发现,最大发现数量99个。
stopDiscovering(): void;停止发现周边设备。
bindTarget(deviceId: string, bindParam: {[key: string]: Object} , callback: AsyncCallback<{deviceId: string}>): void;认证设备。
unbindTarget(deviceId: string): void;解除认证设备。
on(type: 'deviceStateChange', callback: Callback<{ action: DeviceStateChange, device: DeviceBasicInfo }>): void;注册设备状态回调。
off(type: 'deviceStateChange', callback?: Callback<{ action: DeviceStateChange, device: DeviceBasicInfo }>): void;取消注册设备状态回调。
on(type: 'discoverSuccess', callback: Callback<{ device: DeviceBasicInfo }>): void;注册发现设备成功回调监听。
off(type: 'discoverSuccess', callback?: Callback<{ device: DeviceBasicInfo }>): void;取消注册设备发现成功回调。
on(type: 'discoverFailure', callback: Callback<{ reason: number }>): void;注册设备发现失败回调监听。
off(type: 'discoverFailure', callback?: Callback<{ reason: number }>): void;取消注册设备发现失败回调。
on(type: 'serviceDie', callback?: Callback<{}>): void;注册设备管理服务死亡监听。
off(type: 'serviceDie', callback?: Callback<{}>): void;取消注册设备管理服务死亡监听。

调用示例

一个简单的分布式认证流程,最少需要调用以下罗列的API。

    // napi 导包   
    import deviceManager from '@ohos.distributedDeviceManager';  
    // 1 申请权限 ohos.permission.DISTRIBUTED_DATASYNC
    // 2 创建 deviceManager 实例
    let dmClass = deviceManager.createDeviceManager("ohos.samples.jshelloworld");
    // 3 注册设备管理服务死亡监听。
    dmClass.on("serviceDie", () => {
    console.info("serviceDie on");
    });
    // 4 注册设备状态监听
    dmClass.on('deviceStateChange', (data) => {
        console.info("deviceStateChange on:" + JSON.stringify(data));
        switch (data.action) {
            // 设备上线
            case deviceManager.DeviceStateChange.AVAILABLE:
                let list: deviceManager.DeviceBasicInfo[] = [];
                // 获取可信任列表,更新本地的缓存的可信设备列表
                list = this.deviceManager.getAvailableDeviceListSync();
            break;
            case deviceManager.DeviceStateChange.UNAVAILABLE:
                // 设备下线,移除本地可信设备列表的缓存的可信设备
            break;
        }
    });
    
    // 5 注册发现设备成功回调监听。
    dmClass.on('discoverSuccess', (data) => {
        // 发现设备成功,更新本地缓存的不可信设备列表
        console.info("discoverSuccess:" + JSON.stringify(data));
    });
    
    // 6 注册设备发现失败回调监听。
    dmClass.on('discoverFailure', (data) => {
        console.info("discoverFailure on:" + JSON.stringify(data));
    });
    
    // 7 同步获取所有可信设备列表
    let trustList = dmClass.getAvailableDeviceListSync();
    console.log("trustList:" + JSON.stringify(this.trustList));
    
    // 8 发现周边设备。
    let discoverParam = {
        'discoverTargetType': 1
    };
    let filterOptions = {
        'availableStatus': 1,
        'discoverDistance': 50,
        'authenticationStatus': 0,
        'authorizationType': 0
    };
    // 当有设备发现时,通过discoverSuccess回调通知给应用程序
    dmClass.startDiscovering(discoverParam, filterOptions); 
    
    // 9 设备认证
    let deviceId ="XXXXXXXX";
    let bindParam = {
        'bindType': 1,// 认证类型: 1 - 无帐号PIN码认证
        'targetPkgName': 'xxxx',
        'appName': 'xxxx',
        'appOperation': 'xxxx',
        'customDescription': 'xxxx'
    }
    // 当有设备认证成功后,通过deviceStateChange回调通知给应用程序
    dmClass.bindTarget(deviceId, bindParam, (err, data) => {
        console.info("bindTarget err:" + JSON.stringify(err));
        console.info("bindTarget data:" + JSON.stringify(data));
    });
    
    // 10 设备取消认证
    let result = dmClass.unbindTarget(deviceId);
    // 11 停止发现周边设备
    dmClass.stopDiscovering();
    // 12 取消注册设备发现成功回调
    dmClass.off('discoverSuccess');
    // 13 取消注册设备发现失败回调
    dmClass.off('discoverFailure');
    // 14  取消注册设备管理服务死亡监听。
    dmClass.off('serviceDie');
    // 15 取消注册注册设备状态监听
    dmClass.off('deviceStateChange');
    // 16 释放DeviceManager实例。
    deviceManager.releaseDeviceManager(dmClass);

DeviceManager_UI

由于当前版本只支持PIN码认证,DeviceManager_UI只提供PIN码认证的授权提示界面、PIN码显示界面、PIN码输入界面,该应用作为系统应用进行预置,应用包名为:com.ohos.devicemanagerui。

UI 源码位于 foundation/distributedhardware/device_manager/display。

应用界面简介

AbilityUI说明
ConfirmUIExtAbility.etsConfirmDialog.ets弹窗确认页面
PincodeUIExtAbility.etsPinDialog.etsPin码展示页面
InputUIExtAbility.etsInputPinDialog.etsPin码输入页面

DeviceManager_UI如何拉起?

DeviceManager_UI是通过 sceneboard 应用间接拉起,设备管理模块在拉起DeviceManager_UI时,通过AMS 提供的ConnectAbility方法连接 sceneboard 中的ServiceAbility,连接成功后,将涉及的参数通过IPC 通讯方式发送给sceneboard应用,sceneboard应用在接受到参数后,再启动DeviceManager_UI,具体代码如下:

如果连接sceneboard失败,会连接systemui中的systemdialog。

void DmDialogManager::ConnectExtension()
{
    AAFwk::Want want;
    std::string bundleName = "com.ohos.sceneboard"; // com.ohos.systemui
    std::string abilityName = "com.ohos.sceneboard.systemdialog";// com.ohos.systemui.dialog
    want.SetElementName(bundleName, abilityName);
    auto abilityManager = AAFwk::AbilityManagerClient::GetInstance();
    auto ret = abilityManager->ConnectAbility(want, dialogConnectionCallback_, INVALID_USERID);
}

void DmDialogManager::DialogAbilityConnection::OnAbilityConnectDone(
    const AppExecFwk::ElementName& element, const sptr<IRemoteObject>& remoteObject, int resultCode)
{
    ...
    MessageParcel data;
    MessageParcel reply;
    MessageOption option;
    data.WriteInt32(MESSAGE_PARCEL_KEY_SIZE);
    data.WriteString16(u"bundleName");
    data.WriteString16(Str8ToStr16(DmDialogManager::GetBundleName()));
    data.WriteString16(u"abilityName");
    data.WriteString16(Str8ToStr16(DmDialogManager::GetAbilityName()));
    nlohmann::json param;
    param["pinCode"] = DmDialogManager::GetPinCode();
    param["deviceName"] = DmDialogManager::GetDeviceName();
    std::string paramStr = param.dump();
    data.WriteString16(Str8ToStr16(paramStr));
    const uint32_t cmdCode = 1;
    int32_t ret = remoteObject->SendRequest(cmdCode, data, reply, option);
    ...
}

分布式设备管理模块如何拉起DeviceManager_UI详见dm_dialog_manager.cpp文件(foundation/distributedhardware/device_manager/services/implementation/src/ability/standard/dm_dialog_manager.cpp)。

分布式设备管理初始化和上下线流程

img

1:系统SA开机启动
ipc_server_stub.cpp SystemAbility (DISTRIBUTED_HARDWARE_DEVICEMANAGER_SA_ID 4802) 开机启动,生命周期 OnStart方法中初始化DM模快,并添加SOFTBUS_SERVER_SA_ID启动监听,在softbus 服务启动后,DM 模块初始化软总线模块的上下线监听。

ipc_server_stub.cpp

void IpcServerStub::OnStart()
{
    ......
    DeviceManagerService::GetInstance().InitDMServiceListener();
    AddSystemAbilityListener(SOFTBUS_SERVER_SA_ID);
    ......
}

void IpcServerStub::OnAddSystemAbility(int32_t systemAbilityId, const std::string& deviceId)
{
    if (systemAbilityId == SOFTBUS_SERVER_SA_ID) {
        DeviceManagerService::GetInstance().InitSoftbusListener();
    }
}

2:内部变量初始化

device_manager_service.cpp

int32_t DeviceManagerService::InitSoftbusListener()
{
    softbusListener_ = std::make_shared<SoftbusListener>();
    return DM_OK;
}
int32_t DeviceManagerService::InitDMServiceListener()
{
    listener_ = std::make_shared<DeviceManagerServiceListener>();
    advertiseMgr_ = std::make_shared<AdvertiseManager>(softbusListener_);
    discoveryMgr_ = std::make_shared<DiscoveryManager>(softbusListener_, listener_);
    pinHolder_ = std::make_shared<PinHolder>(listener_);
    return DM_OK;
}

3:注册软总线设备上下线监听,局域网内发布能力

softbus_listener.cpp

int32_t SoftbusListener::InitSoftbusListener()
{   
    // softbus 注册软总线节点状态事件回调
    RegNodeDeviceStateCb(DM_PKG_NAME, &softbusNodeStateCb_);
    return InitSoftPublishLNN();
}

// 发布DM 模块对外发现的能力
int32_t SoftbusListener::InitSoftPublishLNN()
{
    ......
    int32_t ret;
    PublishInfo publishInfo;
    publishInfo.publishId = DISTRIBUTED_HARDWARE_DEVICEMANAGER_SA_ID;
    publishInfo.mode = DiscoverMode::DISCOVER_MODE_ACTIVE;
    publishInfo.medium = ExchangeMedium::AUTO;
    publishInfo.freq = ExchangeFreq::HIGH;
    publishInfo.capability = DM_CAPABILITY_OSD;
    publishInfo.ranging = false;
    char discoverStatus[DISCOVER_STATUS_LEN + 1] = {0};
    GetParameter(DISCOVER_STATUS_KEY, "not exist", discoverStatus, DISCOVER_STATUS_LEN);
    ret = PublishLNN(DM_PKG_NAME, &publishInfo, &softbusPublishCallback_);
    g_publishStatus = PulishStatus::ALLOW_BE_DISCOVERY;
    ret = WatchParameter(DISCOVER_STATUS_KEY, &OnParameterChgCallback, nullptr);
    .......
    return ret;
}

void SoftbusListener::OnSoftbusDeviceOnline(NodeBasicInfo *info)
{
    // 设备上线 事件分发出去
}
void SoftbusListener::OnSoftbusDeviceOffline(NodeBasicInfo *info)
{
    // 设备下线 事件分发出去
}
void SoftbusListener::OnSoftbusDeviceInfoChanged(NodeBasicInfoType type, NodeBasicInfo *info)
{
    // 设备状态回调 事件分发出去
}

4:对其他模块提供的参数化DeviceManager方法

device_manager_impl.cpp 文件中的 DeviceManagerImpl::InitDeviceManager 是DM 模块对外暴露的初始化方法,DM 模块对外暴露的方法均需要调用该方法初始化后使用单例模式调用。其他模块在调用InitDeviceManager方法后,传入对应的bundleName模块名,该bundleName会作为后续的标记key ,用来分发事件。

例如 DM NAPI模块在创建DM对象时,调用InitDeviceManager方法初始化。

napi_value DeviceManagerNapi::Init(napi_env env, napi_value exports)
{
    ......
    napi_property_descriptor static_prop[] = {
        DECLARE_NAPI_STATIC_FUNCTION("createDeviceManager", CreateDeviceManager),
    };
    ......
    return exports;
}

napi_value DeviceManagerNapi::CreateDeviceManager(napi_env env, napi_callback_info info)
{ 
    ......
    int32_t ret = DeviceManager::GetInstance().InitDeviceManager(bundleName, initCallback);
    ......
    return result;
}

分布式硬件管理框架调用InitDeviceManager方法进行初始化


int32_t AccessManager::InitDeviceManager()
{
    // DH_FWK_PKG_NAME ohos.dhardware
    return DeviceManager::GetInstance().InitDeviceManager(DH_FWK_PKG_NAME, shared_from_this());
}

分布式设备管理初始化和上下线流程详见附件 分布式设备管理初始化和设备上下线通知流程图.eddx

分布式设备发现流程

设备发现的流程流程如下图所示

JSAPP 调用DM模块NAPI提供的发现接口,并设置对应的监听方法,DM内部去调用软总线的发现接口启动发现,发现局域网的设备后,软总线通知DM,DM 再通过NAPI 机制通知JSAPP。

img

分布式设备管理发现设备流程详见附件 分布式设备管理发现设备流程.eddx

分布式设备认证流程

分布式设备认证流程如下图所示

JSAPP 调用DM模块NAPI提供的认证接口,DM内部调用软总线的接口同另一台设备进行交互,交互完成后,通过设备认证模块进行互信认证,认证通过后,将认证结果通过NAPI 机制通知JSAPP。

img

分布式设备管理设备认证流程详见附件 分布式设备管理设备认证流程.eddx

相关文件下载
附件.rar
154.14 KB
下载
Logo

社区规范:仅讨论OpenHarmony相关问题。

更多推荐