• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright (c) 2025 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16import rpc from '@ohos.rpc';
17import Want from '@ohos.app.ability.Want';
18import common from '@ohos.app.ability.common';
19import hilog from '@ohos.hilog';
20import { BusinessError } from '@kit.BasicServicesKit';
21import { obtainResult } from '../../pages/Index';
22import { util } from '@kit.ArkTS';
23
24const TAG = 'ClientIpc_App1';
25const DOMAIN = 0x0000;
26
27let proxy: rpc.IRemoteObject | undefined;
28let connectid: number | undefined;
29let want: Want = {
30  bundleName: 'com.samples.ipc_service',
31  abilityName: 'IpcServiceExtAbility',
32}
33
34// Parcelable对象
35class MyParcelable implements rpc.Parcelable {
36  public num: number = 0;
37  public str: string = '';
38
39  constructor(num: number, str: string) {
40    this.num = num;
41    this.str = str;
42  }
43
44  marshalling(messageSequence: rpc.MessageSequence): boolean {
45    messageSequence.writeInt(this.num);
46    messageSequence.writeString(this.str);
47    return true;
48  }
49
50  unmarshalling(messageSequence: rpc.MessageSequence): boolean {
51    this.num = messageSequence.readInt();
52    this.str = messageSequence.readString();
53    return true;
54  }
55}
56
57export class ClientIpc {
58  static bindAbi(context:
59    common.UIAbilityContext, callback: () => void) {
60    connectIpc(context, callback);
61  }
62
63  static unBindAbi(context: common.UIAbilityContext) {
64    disConnectIpc(context);
65  }
66
67  // 处理Parcelable数据,调用sendData发送至服务端
68  static sendParcelable(str: string) {
69    if (proxy == undefined) {
70      hilog.info(DOMAIN, TAG, 'undefined proxy');
71      return;
72    }
73    let option = new rpc.MessageOption();
74    let data = rpc.MessageSequence.create();
75    let reply = rpc.MessageSequence.create();
76
77    // 取决于MyParcelable类如何定义,或需要序列化时准备传递什么数据类型,本示例中MyParcelable是以number和string为例,且服务端接收string
78    let parcelable = new MyParcelable(1, str);
79    try {
80      // 进行校验
81      data.writeInterfaceToken(proxy.getDescriptor());
82      // 写入Parcelable
83      data.writeParcelable(parcelable);
84    } catch (error) {
85      let e: BusinessError = error as BusinessError;
86      hilog.error(DOMAIN, TAG, 'ipc write parcelable fail, errorCode ' + e.code + 'errorMessage:' + e.message);
87    }
88
89    sendData(proxy, 1001, data, reply, option);
90  }
91
92  // 处理arraybuffer数据,调用sendData发送至服务端
93  static sendArrayBuffer(str: string) {
94    if (proxy == undefined) {
95      hilog.info(DOMAIN, TAG, 'undefined proxy');
96      return;
97    }
98    let option = new rpc.MessageOption();
99    let data = rpc.MessageSequence.create();
100    let reply = rpc.MessageSequence.create();
101
102    // 将str转为ArrayBuffer
103    const encoder = new util.TextEncoder('utf-8');
104
105    // 使用TextEncoder将字符串编码为Uint8Array
106    const uint8Array = encoder.encodeInto(str);
107
108    // 将Uint8Array转换为ArrayBuffer
109    const arrayBuffer = uint8Array.buffer;
110    try {
111      // 进行校验
112      data.writeInterfaceToken(proxy.getDescriptor());
113      // 写入ArrayBuffer
114      hilog.error(DOMAIN, TAG, 'arraybuffer:' + uint8Array.toString());
115      data.writeArrayBuffer(arrayBuffer, rpc.TypeCode.UINT8_ARRAY);
116    } catch (error) {
117      let e: BusinessError = error as BusinessError;
118      hilog.error(DOMAIN, TAG, 'ipc write parcelable fail, errorCode ' + e.code + 'errorMessage:' + e.message);
119    }
120
121    sendData(proxy, 1002, data, reply, option);
122  }
123}
124
125// 连接服务端
126function connectIpc(context: common.UIAbilityContext, callback: () => void) {
127  let connect: common.ConnectOptions = {
128    onConnect: (elementName, remoteProxy) => {
129      hilog.info(DOMAIN, TAG, 'IpcClient:onConnect.callend(server),elementName:' +
130      JSON.stringify(elementName));
131      proxy = remoteProxy;
132      obtainResult.result = 'success';
133      callback();
134    },
135    onDisconnect: (elementName) => {
136      hilog.info(DOMAIN, TAG, 'IpcClient onDisconnect:' + elementName);
137    },
138    onFailed: (code: number) => {
139      obtainResult.result = 'error ' + code;
140      hilog.info(DOMAIN, TAG, 'IpcClient onFailed,code:' + code);
141      callback();
142    },
143  }
144
145  connectid = context.connectServiceExtensionAbility(want, connect);
146  hilog.info(DOMAIN, TAG, 'IpcClient connectid:' + connectid);
147}
148
149function disConnectIpc(context: common.UIAbilityContext) {
150  if (connectid != undefined) {
151    context.disconnectServiceExtensionAbility(connectid);
152    proxy = undefined;
153  }
154}
155
156// 发送信息,arraybuffer和parcelable均调用此处发送至服务端
157function sendData(proxy: rpc.IRemoteObject, code: number, data: rpc.MessageSequence, reply: rpc.MessageSequence,
158  options: rpc.MessageOption) {
159  if (proxy == undefined) {
160    hilog.info(DOMAIN, TAG, 'undefined proxy');
161    return;
162  }
163  // 用连接服务成功后返回的对象proxy,进行消息发送
164  proxy.sendMessageRequest(code, data, reply, options)
165    .then((result: rpc.RequestResult) => {
166      if (result.errCode === 0) {
167        hilog.info(DOMAIN, TAG, 'sendMessageRequest got result');
168        try {
169          let rsp = result.reply.readString();
170          hilog.info(DOMAIN, TAG, 'IpcClient result.' + rsp);
171        } catch (error) {
172          let e: BusinessError = error as BusinessError;
173          hilog.error(DOMAIN, TAG, 'rpc read exception fail, error is ' + e);
174        }
175      } else {
176        hilog.error(DOMAIN, TAG, 'RPCTest: sendMessageRequest failed, errCode: ' + result.errCode);
177      }
178    }).catch((e: Error) => {
179    hilog.error(DOMAIN, TAG, 'RPCTest: sendMessageRequest got exception: ' + e);
180  }).finally(() => {
181    hilog.info(DOMAIN, TAG, 'RPCTest: sendMessageRequest ends, reclaim parcel');
182    data.reclaim();
183    reply.reclaim();
184  });
185}
186