• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# UI-based Driver Development
2
3## When to Use
4
5UI-based basic drivers are applicable to a wide variety of composite devices. When developing these drivers, you may set the corresponding unique driver capabilities through the UI, or display the information retrieved from the devices on the UI. Examples of such devices include mice with side buttons, handwriting tablets, and ID card readers.
6
7## Environment Setup
8
9Before you get started, make necessary preparations by following instructions in [Environment Preparation](environmental-preparation.md).
10
11## Available APIs
12
13The following table describes the basic peripheral management capabilities. For details, see [API Reference](../../reference/apis-driverdevelopment-kit/js-apis-driver-deviceManager.md).
14
15**Table 1** APIs for basic peripheral management
16
17| Name                                                      | Description                                                        |
18| ------------------------------------------------------------ | ------------------------------------------------------------ |
19| queryDevices(busType?: number): Array<Readonly<Device>> | Queries the peripheral list.                                          |
20| bindDriverWithDeviceId(deviceId: number, onDisconnect: AsyncCallback<number>): Promise<RemoteDeviceDriver>; | Binds a peripheral. This API uses a promise to return the result. It is supported since API version 18.                      |
21| unbindDriverWithDeviceId(deviceId: number): Promise<number> | Unbinds a peripheral device. This API uses a promise to return the result. It is supported since API version 18.                      |
22
23<!--Del-->
24The following table lists the APIs for extended peripheral management. For details, see [deviceManager API Reference](../../reference/apis-driverdevelopment-kit/js-apis-driver-deviceManager-sys.md).
25
26**Table 2** APIs for extended peripheral management
27
28| Name                                                                         | Description             |
29|------------------------------------------------------------------------------|-----------------|
30| queryDeviceInfo(deviceId?: number): Array&lt;Readonly&lt;DeviceInfo&gt;&gt;  | Obtains the list of detailed information about peripherals.  |
31| queryDriverInfo(driverUid?: string): Array&lt;Readonly&lt;DriverInfo&gt;&gt; | Obtains the list of detailed information about peripheral drivers.|
32<!--DelEnd-->
33
34## How to Develop
35
36You can use the APIs to query and bind peripheral devices so as to use the customized driver capabilities of the peripherals.
37
38The following sample code is a demo that illustrates how to develop both the client and server and implement IPC.
39
401. Create an OpenHarmony project. For details, see [Creating a Project] (https://developer.huawei.com/consumer/en/doc/harmonyos-guides/ide-create-new-project).
41
42    **NOTE**
43
44    > To develop a driver client, select the **Empty Ability** template.
45    >
46    > To develop the driver server, select the **Native C++** template.
47    >
48    >To develop both the driver client and server, select the **Native C++** template.
49
50
512. Import the related kit, and declare the product ID, vendor ID, and code of the USB device to be bound.
52
53    **NOTE**
54
55    > Write following sample code in the **entry/src/main/ets/pages/Index.ets** file.
56
57    ```ts
58    import { hilog } from '@kit.PerformanceAnalysisKit';
59    import { deviceManager } from '@kit.DriverDevelopmentKit';
60    import { BusinessError } from '@kit.BasicServicesKit';
61    import { rpc } from '@kit.IPCKit';
62
63    const REQUEST_CODE: number = 99; // Custom communication code, which is for reference only.
64    const productId: number = 4258; // Declare the product ID of the connected USB device.
65    const vendorId: number = 4817; // Declare the vendor ID of the connected USB device.
66    ```
67
683. Define the **message** variable and remote object variable for communication with the driver.
69
70    **NOTE**
71
72    > The following APIs are defined in **struct Index{}**.
73
74    ```ts
75    @State message: string = 'Hello';
76    private remote: rpc.IRemoteObject | null = null;
77    ```
78
794. Define the **queryDevices** API, and use it to obtain the device ID of the peripheral.
80
81    ```ts
82    private async queryTargetDeviceId(): Promise<number> {
83    try {
84      const devices: Array<deviceManager.Device> = deviceManager.queryDevices(deviceManager.BusType.USB);
85      const index = devices.findIndex((item: deviceManager.Device) => {
86        let usbDevice = item as deviceManager.USBDevice;
87        // If the product ID and vendor ID of the peripheral are unknown, you can view the information about the connected USB device in the log.
88        hilog.info(0, 'testTag', `usbDevice.productId = ${usbDevice.productId}, usbDevice.vendorId = ${usbDevice.vendorId}`);
89        return usbDevice.productId === productId && usbDevice.vendorId === vendorId;
90      });
91      if (index < 0) {
92        hilog.error(0, 'testTag', 'can not find device');
93        return -1;
94      }
95      return devices[index].deviceId;
96    } catch (error) {
97      hilog.error(0, 'testTag', `queryDevice failed, err: ${JSON.stringify(error)}`);
98    }
99    return -1;
100    }
101    ```
102
1035. Define the **bindDriverWithDeviceId** API, and use it to obtain the remote driver object.
104
105    ```ts
106    private async getDriverRemote(deviceId: number): Promise<rpc.IRemoteObject | null> {
107    try {
108      let remoteDeviceDriver: deviceManager.RemoteDeviceDriver = await deviceManager.bindDriverWithDeviceId(deviceId,
109        (err: BusinessError, id: number) => {
110        hilog.info(0, 'testTag', `device[${id}] id disconnect, err: ${JSON.stringify(err)}}`);
111      });
112      return remoteDeviceDriver.remote;
113    } catch (error) {
114      hilog.error(0, 'testTag', `bindDriverWithDeviceId failed, err: ${JSON.stringify(error)}`);
115    }
116      return null;
117    }
118    ```
119
1206. Defines the **sendMessageRequest** API, and use it to perform IPC with the remote driver object.
121
122    ```ts
123    private async communicateWithRemote(): Promise<void> {
124      const deviceId: number = await this.queryTargetDeviceId();
125      if (deviceId < 0) {
126        hilog.error(0, 'testTag', 'can not find target device');
127        return;
128      }
129      this.remote = await this.getDriverRemote(deviceId);
130      if (this.remote === null) {
131        hilog.error(0, 'testTag', `getDriverRemote failed`);
132        return;
133      }
134
135      let option = new rpc.MessageOption();
136      let data = new rpc.MessageSequence();
137      let reply = new rpc.MessageSequence();
138
139      // Send "Hello" to the driver.
140      data.writeString(this.message);
141
142      try {
143        await this.remote.sendMessageRequest(REQUEST_CODE, data, reply, option);
144        // Obtain the "Hello world" information returned by the driver.
145        this.message = reply.readString();
146        hilog.info(0, 'testTag', `sendMessageRequest, message: ${this.message}}`);
147      } catch (error) {
148        hilog.error(0, 'testTag', `sendMessageRequest failed, err: ${JSON.stringify(error)}`);
149      }
150    }
151    ```
152
1537. Render the UI. For details about UI development, see [UI Development](https://developer.huawei.com/consumer/en/doc/harmonyos-guides-V5/arkts-ui-development-V5).
154
155    ```ts
156    build() {
157      Row() {
158        Column() {
159          Text (this.message) // "Hello" is displayed.
160            .fontSize(60)
161            .fontWeight(FontWeight.Bold)
162            .onClick (() => { // Click Hello to communicate with the remote driver object. The message "Hello World" is displayed.
163              this.communicateWithRemote();
164            })
165        }
166        .width('100%')
167      }
168      .height('100%')
169    }
170    ```
171
1728. Develop peripheral drivers by following instructions in [UI-free Driver Development](driverextensionability.md).
173
174<!--Del-->
175System applications can query detailed information about peripherals and drivers to implement management. The development procedure is as follows:
176
1771. Import the related kits.
178
179    ```ts
180     import { deviceManager } from '@kit.DriverDevelopmentKit';
181     import { BusinessError } from '@kit.BasicServicesKit';
182    ```
183
1842. Obtain the list of detailed information about peripherals.
185
186    ```ts
187    try {
188       // For example, deviceId is 12345678. You can use queryDevices() to obtain the deviceId.
189       let deviceInfos : Array<deviceManager.DeviceInfo> = deviceManager.queryDeviceInfo(12345678);
190       for (let item of deviceInfos) {
191          console.info(`Device id is ${item.deviceId}`)
192       }
193     } catch (error) {
194       let err: BusinessError = error as BusinessError;
195       console.error(`Failed to query device info. Code is ${err.code}, message is ${err.message}`);
196     }
197    ```
198
1993. Obtains the list of detailed information about peripheral drivers.
200
201    ```ts
202    try {
203       // In this example, driver-12345 is the driver UID. During application development, you can use queryDeviceInfo to query the driver UID and use it as the input parameter.
204       let driverInfos : Array<deviceManager.DriverInfo> = deviceManager.queryDriverInfo("driver-12345");
205       for (let item of driverInfos) {
206          console.info(`driver name is ${item.driverName}`)
207       }
208    } catch (error) {
209       let err: BusinessError = error as BusinessError;
210       console.error(`Failed to query driver info. Code is ${err.code}, message is ${err.message}`);
211    }
212    ```
213<!--DelEnd-->
214<!--RP1-->
215## Application Signing
216
217**NOTE**<br>Configure the permission before enabling automatic signing.
218
219You need to configure a signature file for your application to run on a device. Besides, to develop a peripheral driver client, you need to declare the **ohos.permission.ACCESS_EXTENSIONAL_DEVICE_DRIVER** and **ohos.permission.ACCESS_DDK_DRIVERS** permissions for the peripheral.
220- ohos.permission.ACCESS_EXTENSIONAL_DEVICE_DRIVER (This permission is required for API version 10 or later.)
221
222  To obtain authorization on this access permission, [declare it](../../security/AccessToken/declare-permissions.md) in the **requestPermissions** field in the **module.json5** file.
223
224- ohos.permission.ACCESS_DDK_DRIVERS (This permission is required for API version 18 or later.)
225
226  1. [Declare the required permissions](../../security/AccessToken/declare-permissions.md) in the **requestPermissions** field in the **module.json5** file.
227  2. Modify the **acls** field in the **HarmonyAppProvision** configuration file to request permissions via ACL. For details, see [Requesting Restricted Permissions](../../security/AccessToken/declare-permissions-in-acl.md).
228  3. In the **HarmonyAppProvision** configuration file (that is, **Sdk/openharmony/_{Version} _/toolchains /lib/UnsgnedReleasedProfileTemplate.json** file), configure the bundle name of the driver server to connect. If there are multiple servers, separate their bundle names with a comma.
229
230      The configuration procedure is as follows:
231
232      Add the **app-services-capabilities** node to the root node of the file and configure the node as follows:
233      ```json
234      "app-services-capabilities": {
235        "ohos.permission.ACCESS_DDK_DRIVERS": {"bundleNames": "bundleName0,bundleName1,bundleName2"}
236      }
237      ```
238
239Automatic signing: [Signing Your App/Service Automatically](https://developer.huawei.com/consumer/en/doc/harmonyos-guides-V13/ide-signing-V13#section18815157237)
240<!--RP1End-->
241