1e484b35bSopenharmony_ci/*
2e484b35bSopenharmony_ci * Licensed to the Apache Software Foundation (ASF) under one
3e484b35bSopenharmony_ci * or more contributor license agreements.  See the NOTICE file
4e484b35bSopenharmony_ci * distributed with this work for additional information
5e484b35bSopenharmony_ci * regarding copyright ownership.  The ASF licenses this file
6e484b35bSopenharmony_ci * to you under the Apache License, Version 2.0 (the
7e484b35bSopenharmony_ci * "License"); you may not use this file except in compliance
8e484b35bSopenharmony_ci * with the License.  You may obtain a copy of the License at
9e484b35bSopenharmony_ci *
10e484b35bSopenharmony_ci *   http://www.apache.org/licenses/LICENSE-2.0
11e484b35bSopenharmony_ci *
12e484b35bSopenharmony_ci * Unless required by applicable law or agreed to in writing,
13e484b35bSopenharmony_ci * software distributed under the License is distributed on an
14e484b35bSopenharmony_ci * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15e484b35bSopenharmony_ci * KIND, either express or implied.  See the License for the
16e484b35bSopenharmony_ci * specific language governing permissions and limitations
17e484b35bSopenharmony_ci * under the License.
18e484b35bSopenharmony_ci */
19e484b35bSopenharmony_ci/*
20e484b35bSopenharmony_ci * 2021.01.08 - The function 'standardization' is simpler and more accurate.
21e484b35bSopenharmony_ci * And extend function 'send' to fit framework.
22e484b35bSopenharmony_ci * Copyright (c) 2021 Huawei Device Co., Ltd.
23e484b35bSopenharmony_ci */
24e484b35bSopenharmony_ci
25e484b35bSopenharmony_ciimport {
26e484b35bSopenharmony_ci  Log,
27e484b35bSopenharmony_ci  typof,
28e484b35bSopenharmony_ci  bufferToBase64
29e484b35bSopenharmony_ci} from '../../../utils/index';
30e484b35bSopenharmony_ciimport CallbackManager from './CallbackManager';
31e484b35bSopenharmony_ci
32e484b35bSopenharmony_citype OptionsType = Partial<Record<'action' | 'module' | 'method' | 'ref', string>>
33e484b35bSopenharmony_ci
34e484b35bSopenharmony_ci/**
35e484b35bSopenharmony_ci * <p>Tasks processing center.</p>
36e484b35bSopenharmony_ci * <p>Instructs the Native module to perform operations based on the message sent by the listener.</p>
37e484b35bSopenharmony_ci * <p>Then the Native module invokes the callNative() callback function in sendTasks()<br>
38e484b35bSopenharmony_ci * to send the message to the Native module.</p>
39e484b35bSopenharmony_ci */
40e484b35bSopenharmony_ciexport class TaskCenter {
41e484b35bSopenharmony_ci  public instanceId: string;
42e484b35bSopenharmony_ci  public callbackManager: CallbackManager;
43e484b35bSopenharmony_ci
44e484b35bSopenharmony_ci  constructor(id: string) {
45e484b35bSopenharmony_ci    this.instanceId = id;
46e484b35bSopenharmony_ci    this.callbackManager = new CallbackManager(id);
47e484b35bSopenharmony_ci  }
48e484b35bSopenharmony_ci
49e484b35bSopenharmony_ci  /**
50e484b35bSopenharmony_ci   * Execute the consume() function from callbackManager class.
51e484b35bSopenharmony_ci   * @param {number} callbackId - Callback id.
52e484b35bSopenharmony_ci   * @param {Object} data - Data that needed.
53e484b35bSopenharmony_ci   * @param {boolean} ifKeepAlive - If keepAlive is false, delete this callback.
54e484b35bSopenharmony_ci   * @return {*}
55e484b35bSopenharmony_ci   */
56e484b35bSopenharmony_ci  public consumeCallback(callbackId: number, data: object, ifKeepAlive: boolean): any | Error {
57e484b35bSopenharmony_ci    return this.callbackManager.consume(callbackId, data, ifKeepAlive);
58e484b35bSopenharmony_ci  }
59e484b35bSopenharmony_ci
60e484b35bSopenharmony_ci  /**
61e484b35bSopenharmony_ci   * Execute the close() function from callbackManager class.
62e484b35bSopenharmony_ci   * @param {number} callbackId - Callback id.
63e484b35bSopenharmony_ci   */
64e484b35bSopenharmony_ci  public destroyCallback(): void {
65e484b35bSopenharmony_ci    return this.callbackManager.destroy();
66e484b35bSopenharmony_ci  }
67e484b35bSopenharmony_ci
68e484b35bSopenharmony_ci  /**
69e484b35bSopenharmony_ci   * Execute the remove() function from callbackManager class.
70e484b35bSopenharmony_ci   * @param {number} callbackId - Callback id.
71e484b35bSopenharmony_ci   */
72e484b35bSopenharmony_ci  public removeCallback(callbackId: number): void {
73e484b35bSopenharmony_ci    this.callbackManager.remove(callbackId);
74e484b35bSopenharmony_ci  }
75e484b35bSopenharmony_ci
76e484b35bSopenharmony_ci  /**
77e484b35bSopenharmony_ci   * Execute the isEmpty() function from callbackManager class.
78e484b35bSopenharmony_ci   * @param {number} callbackId - Callback id.
79e484b35bSopenharmony_ci   * @return {boolean} If callbacklist object is empty, return true. Otherwise return false.
80e484b35bSopenharmony_ci   */
81e484b35bSopenharmony_ci  public callbackIsEmpty(): boolean {
82e484b35bSopenharmony_ci    return this.callbackManager.isEmpty();
83e484b35bSopenharmony_ci  }
84e484b35bSopenharmony_ci
85e484b35bSopenharmony_ci  /**
86e484b35bSopenharmony_ci   * Normalize args.
87e484b35bSopenharmony_ci   * @param  {*} v - Original args.
88e484b35bSopenharmony_ci   * @return {*} - Normalized args.
89e484b35bSopenharmony_ci   */
90e484b35bSopenharmony_ci  public normalizePrimitive(v: any): any {
91e484b35bSopenharmony_ci    const type = typof(v);
92e484b35bSopenharmony_ci
93e484b35bSopenharmony_ci    switch (type) {
94e484b35bSopenharmony_ci      case 'undefined':
95e484b35bSopenharmony_ci      case 'null':
96e484b35bSopenharmony_ci        return '';
97e484b35bSopenharmony_ci
98e484b35bSopenharmony_ci      case 'regexp':
99e484b35bSopenharmony_ci        return v.toString();
100e484b35bSopenharmony_ci      case 'date':
101e484b35bSopenharmony_ci        return v.toISOString();
102e484b35bSopenharmony_ci
103e484b35bSopenharmony_ci      case 'number':
104e484b35bSopenharmony_ci      case 'string':
105e484b35bSopenharmony_ci      case 'boolean':
106e484b35bSopenharmony_ci      case 'array':
107e484b35bSopenharmony_ci      case 'object':
108e484b35bSopenharmony_ci        return v;
109e484b35bSopenharmony_ci
110e484b35bSopenharmony_ci      case 'arraybuffer':
111e484b35bSopenharmony_ci        return {
112e484b35bSopenharmony_ci          '@type': 'binary',
113e484b35bSopenharmony_ci          dataType: type,
114e484b35bSopenharmony_ci          base64: bufferToBase64(v)
115e484b35bSopenharmony_ci        };
116e484b35bSopenharmony_ci
117e484b35bSopenharmony_ci      case 'int8array':
118e484b35bSopenharmony_ci      case 'uint8array':
119e484b35bSopenharmony_ci      case 'uint8clampedarray':
120e484b35bSopenharmony_ci      case 'int16array':
121e484b35bSopenharmony_ci      case 'uint16array':
122e484b35bSopenharmony_ci      case 'int32array':
123e484b35bSopenharmony_ci      case 'uint32array':
124e484b35bSopenharmony_ci      case 'float32array':
125e484b35bSopenharmony_ci      case 'float64array':
126e484b35bSopenharmony_ci        return {
127e484b35bSopenharmony_ci          '@type': 'binary',
128e484b35bSopenharmony_ci          dataType: type,
129e484b35bSopenharmony_ci          base64: bufferToBase64(v.buffer)
130e484b35bSopenharmony_ci        };
131e484b35bSopenharmony_ci
132e484b35bSopenharmony_ci      default:
133e484b35bSopenharmony_ci        return JSON.stringify(v);
134e484b35bSopenharmony_ci    }
135e484b35bSopenharmony_ci  }
136e484b35bSopenharmony_ci
137e484b35bSopenharmony_ci  /**
138e484b35bSopenharmony_ci   * Standardizing a value. Specially, if the value is a function, generate a function id.
139e484b35bSopenharmony_ci   * @param  {*} arg - Any type.
140e484b35bSopenharmony_ci   * @return {*}
141e484b35bSopenharmony_ci   */
142e484b35bSopenharmony_ci  public standardization(arg: any): any {
143e484b35bSopenharmony_ci    const type = typof(arg);
144e484b35bSopenharmony_ci    if (type === 'object') {
145e484b35bSopenharmony_ci      const ans = {};
146e484b35bSopenharmony_ci      Object.keys(arg).forEach(key => {
147e484b35bSopenharmony_ci        ans[key] = this.standardization(arg[key]);
148e484b35bSopenharmony_ci      });
149e484b35bSopenharmony_ci      return ans;
150e484b35bSopenharmony_ci    } else if (type === 'function') {
151e484b35bSopenharmony_ci      return this.callbackManager.add(arg).toString();
152e484b35bSopenharmony_ci    } else if (type === 'array') {
153e484b35bSopenharmony_ci      return arg.map(i => this.standardization(i));
154e484b35bSopenharmony_ci    } else {
155e484b35bSopenharmony_ci      return this.normalizePrimitive(arg);
156e484b35bSopenharmony_ci    }
157e484b35bSopenharmony_ci  }
158e484b35bSopenharmony_ci
159e484b35bSopenharmony_ci  /**
160e484b35bSopenharmony_ci   * Instruct the Native module to perform operations based on the message sent by the listener.
161e484b35bSopenharmony_ci   * @param {string} type - Such as dom, module and component.
162e484b35bSopenharmony_ci   * @param {OptionsType} options - Include action, module and method.
163e484b35bSopenharmony_ci   * @param {*} args - Args of a Vm.
164e484b35bSopenharmony_ci   */
165e484b35bSopenharmony_ci  public send(type: string, options: OptionsType, args: any): any {
166e484b35bSopenharmony_ci    const {
167e484b35bSopenharmony_ci      action,
168e484b35bSopenharmony_ci      module,
169e484b35bSopenharmony_ci      method
170e484b35bSopenharmony_ci    } = options;
171e484b35bSopenharmony_ci    if (type !== 'dom') {
172e484b35bSopenharmony_ci      args = args.map(arg => this.standardization(arg));
173e484b35bSopenharmony_ci    }
174e484b35bSopenharmony_ci    switch (type) {
175e484b35bSopenharmony_ci      case 'dom':
176e484b35bSopenharmony_ci        if (typeof ace !== 'undefined' &&
177e484b35bSopenharmony_ci            typeof ace.domCreateBody !== 'undefined' &&
178e484b35bSopenharmony_ci            typeof ace.domAddElement !== 'undefined') {
179e484b35bSopenharmony_ci          if (action === 'createBody') {
180e484b35bSopenharmony_ci            ace.domCreateBody(
181e484b35bSopenharmony_ci              0,
182e484b35bSopenharmony_ci              args[0].type,
183e484b35bSopenharmony_ci              args[0].attr,
184e484b35bSopenharmony_ci              args[0].style,
185e484b35bSopenharmony_ci              args[0].event
186e484b35bSopenharmony_ci            );
187e484b35bSopenharmony_ci          } else if (action === 'addElement') {
188e484b35bSopenharmony_ci            ace.domAddElement(
189e484b35bSopenharmony_ci              args[0],
190e484b35bSopenharmony_ci              args[1].ref,
191e484b35bSopenharmony_ci              args[1].type,
192e484b35bSopenharmony_ci              args[1].attr,
193e484b35bSopenharmony_ci              args[1].style,
194e484b35bSopenharmony_ci              args[1].event,
195e484b35bSopenharmony_ci              args[1].customComponent,
196e484b35bSopenharmony_ci              args[2],
197e484b35bSopenharmony_ci              this.instanceId
198e484b35bSopenharmony_ci            );
199e484b35bSopenharmony_ci          } else if (action === 'updateAttrs') {
200e484b35bSopenharmony_ci            ace.updateElementAttrs(
201e484b35bSopenharmony_ci              args[0],
202e484b35bSopenharmony_ci              args[1],
203e484b35bSopenharmony_ci              this.instanceId
204e484b35bSopenharmony_ci            );
205e484b35bSopenharmony_ci          } else if (action === 'updateStyle') {
206e484b35bSopenharmony_ci            ace.updateElementStyles(
207e484b35bSopenharmony_ci              args[0],
208e484b35bSopenharmony_ci              args[1],
209e484b35bSopenharmony_ci              this.instanceId
210e484b35bSopenharmony_ci            );
211e484b35bSopenharmony_ci          } else if (action === 'createFinish') {
212e484b35bSopenharmony_ci            ace.onCreateFinish();
213e484b35bSopenharmony_ci            return;
214e484b35bSopenharmony_ci          } else if (action === 'updateFinish') {
215e484b35bSopenharmony_ci            ace.onUpdateFinish();
216e484b35bSopenharmony_ci            return;
217e484b35bSopenharmony_ci          } else if (action === 'removeElement') {
218e484b35bSopenharmony_ci            ace.removeElement(
219e484b35bSopenharmony_ci              args[0],
220e484b35bSopenharmony_ci              this.instanceId
221e484b35bSopenharmony_ci            );
222e484b35bSopenharmony_ci          } else {
223e484b35bSopenharmony_ci            Log.error(
224e484b35bSopenharmony_ci              'TaskCenter.js: send() unsupported action. IGNORING!'
225e484b35bSopenharmony_ci            );
226e484b35bSopenharmony_ci          }
227e484b35bSopenharmony_ci          return;
228e484b35bSopenharmony_ci        } else {
229e484b35bSopenharmony_ci          Log.error(
230e484b35bSopenharmony_ci            'TaskCenter.js: attempting acev1 method for calling native'
231e484b35bSopenharmony_ci          );
232e484b35bSopenharmony_ci          return;
233e484b35bSopenharmony_ci        }
234e484b35bSopenharmony_ci
235e484b35bSopenharmony_ci      case 'module':
236e484b35bSopenharmony_ci        switch (module) {
237e484b35bSopenharmony_ci          case 'system.fetch':
238e484b35bSopenharmony_ci            if (method === 'fetch') {
239e484b35bSopenharmony_ci              Log.error(
240e484b35bSopenharmony_ci                'TaskCenter.js: send: module system.fetch. calling ace.fetch.'
241e484b35bSopenharmony_ci              );
242e484b35bSopenharmony_ci              ace.onFetchRequest(args[1], JSON.stringify(args));
243e484b35bSopenharmony_ci              return;
244e484b35bSopenharmony_ci            } else {
245e484b35bSopenharmony_ci              Log.error(
246e484b35bSopenharmony_ci                'TaskCenter.js: send: module system.fetch. unrecognized method. Ignoring.'
247e484b35bSopenharmony_ci              );
248e484b35bSopenharmony_ci            }
249e484b35bSopenharmony_ci            break;
250e484b35bSopenharmony_ci          case 'system.device':
251e484b35bSopenharmony_ci            return ace.callNative(JSON.stringify(options), args[args.length - 1]);
252e484b35bSopenharmony_ci          case 'system.router':
253e484b35bSopenharmony_ci            return ace.callNative(JSON.stringify(options), JSON.stringify(args[0]));
254e484b35bSopenharmony_ci          case 'system.prompt':
255e484b35bSopenharmony_ci            return ace.callNative(JSON.stringify(options), JSON.stringify(args[0]));
256e484b35bSopenharmony_ci          case 'system.app':
257e484b35bSopenharmony_ci            return ace.callNative(JSON.stringify(options), args);
258e484b35bSopenharmony_ci          case 'system.configuration':
259e484b35bSopenharmony_ci            return ace.callNative(JSON.stringify(options), JSON.stringify(args[0]));
260e484b35bSopenharmony_ci          case 'system.grid':
261e484b35bSopenharmony_ci            return ace.callNative(JSON.stringify(options), args);
262e484b35bSopenharmony_ci          case 'internal.jsResult':
263e484b35bSopenharmony_ci            return ace.callNative(JSON.stringify(options), args);
264e484b35bSopenharmony_ci          case 'timer':
265e484b35bSopenharmony_ci            return ace.callNative(JSON.stringify(options), args);
266e484b35bSopenharmony_ci          case 'system.offscreenCanvas':
267e484b35bSopenharmony_ci            return ace.callNative(JSON.stringify(options), JSON.stringify(args[0]));
268e484b35bSopenharmony_ci          case 'system.image':
269e484b35bSopenharmony_ci            return ace.callNative(JSON.stringify(options), JSON.stringify(args[0]));
270e484b35bSopenharmony_ci          case 'system.mediaquery':
271e484b35bSopenharmony_ci            return ace.callNative(JSON.stringify(options), args);
272e484b35bSopenharmony_ci          case 'animation':
273e484b35bSopenharmony_ci            return ace.callNative(JSON.stringify(options), args[0]);
274e484b35bSopenharmony_ci          case 'system.resource':
275e484b35bSopenharmony_ci            return ace.callNative(JSON.stringify(options), args);
276e484b35bSopenharmony_ci          case 'ohos.animator':
277e484b35bSopenharmony_ci            return ace.callNative(JSON.stringify(options), JSON.stringify(args[0]));
278e484b35bSopenharmony_ci          default:
279e484b35bSopenharmony_ci            break;
280e484b35bSopenharmony_ci        }
281e484b35bSopenharmony_ci        break;
282e484b35bSopenharmony_ci
283e484b35bSopenharmony_ci      case 'component':
284e484b35bSopenharmony_ci        return ace.callComponent(options.ref, method, JSON.stringify(args));
285e484b35bSopenharmony_ci      default:
286e484b35bSopenharmony_ci        break;
287e484b35bSopenharmony_ci    }
288e484b35bSopenharmony_ci  }
289e484b35bSopenharmony_ci}
290