[Service] Refactor and fix message-port issue 20/284320/6
authorDongHyun Song <dh81.song@samsung.com>
Tue, 15 Nov 2022 12:38:35 +0000 (21:38 +0900)
committerDongHyun Song <dh81.song@samsung.com>
Wed, 16 Nov 2022 05:50:35 +0000 (14:50 +0900)
when the app calls RemoteMessageport.sendMessage(), its second
parameter should be an LocalMessagePort function which is created
in pure message-port webapis.
From the bi-direction support, because LocalMessagePort becomes
an wrapper object by device_api_router, this makes an error by
type validator of webapis core.

Thus, this patch's main idea is going to unwrap the object to pass
the pure message-port object as the second parameter, also refactors
message-port implementation source code on mesage_port_router.

Change-Id: I226d9521df7cb5edc84530b3d65ba63a155905d8
Signed-off-by: DongHyun Song <dh81.song@samsung.com>
wrt_app/service/device_api_router.ts
wrt_app/service/message_port_router.ts [new file with mode: 0644]

index 16cfa9e..96b8384 100644 (file)
@@ -1,6 +1,7 @@
 import { wrt } from '../browser/wrt';
-import * as ServiceMessage from '../common/service_message';
+import * as serviceMessage from '../common/service_message';
 import { parentPort } from 'worker_threads';
+import { LocalMessagePort, RemoteMessagePort, RemoteTrustedMessagePort } from './message_port_router';
 
 export class DeviceAPIRouter {
   currentApplication: any;
@@ -13,6 +14,7 @@ export class DeviceAPIRouter {
   funcGetMetadata: any;
   funcGetPackageInfo: any;
   funcRequestLocalMessagePort: any;
+  funcRequestRemoteMessagePort: any;
 
   id: string;
   serviceId: string;
@@ -20,7 +22,6 @@ export class DeviceAPIRouter {
   callerAppId: string;
   permissions: string[];
   pkgApiVersion: string;
-  messagePortInfo: any;
   messageListeners: any;
 
   constructor(id: string, isGlobal: boolean) {
@@ -31,7 +32,6 @@ export class DeviceAPIRouter {
     this.packageId = wrt.getPackageId(id);
     this.permissions = [];
     this.pkgApiVersion = '';
-    this.messagePortInfo = {};
     this.messageListeners = {};
 
     this.initWebapis();
@@ -146,7 +146,7 @@ export class DeviceAPIRouter {
         }
         global.webapis.mde.updateRemoteInput = (inputString: string) => {
           mde.updateRemoteInput(inputString);
-          ServiceMessage.notifyServiceMessage('remote-input', inputString);
+          serviceMessage.notifyServiceMessage('remote-input', inputString);
         }
         global.webapis.mde.selectRemoteInput = () => {
           mde.selectRemoteInput();
@@ -415,85 +415,25 @@ export class DeviceAPIRouter {
   }
 
   refineMessagePortApis() {
-    this.funcRequestLocalMessagePort =
-      global.tizen.messageport.requestLocalMessagePort;
+    this.funcRequestLocalMessagePort = global.tizen.messageport.requestLocalMessagePort;
+    this.funcRequestRemoteMessagePort = global.tizen.messageport.requestRemoteMessagePort;
 
-    const registerMessagePort = (name: string, portName: string, appId?: string, callback?: any) => {
-      let portInfo = `${name}::${this.serviceId}::${portName}`;
-      if (this.messagePortInfo[portInfo] === 'created') {
-        callback?.();
-        return;
-      }
-      let data_payload = [
-        new global.tizen.ApplicationControlData(name, [portName]),
-      ];
-      if (appId) {
-        data_payload.push(new global.tizen.ApplicationControlData('appId', [appId]));
-      }
-      let appControl = new global.tizen.ApplicationControl(
-        "http://tizen.org/appcontrol/operation/default", null, null, null,
-        data_payload, null);
-      global.tizen.application.launchAppControl(appControl, this.serviceId,
-        () => {
-          console.debug(`'${portInfo}' is requsted`)
-          callback?.();
-          this.messagePortInfo[portInfo] = 'created';
-        });
-    }
-
-    const makeMessagePort = (portName: string, isTrusted: boolean) => {
-      const messagePort = this.funcRequestLocalMessagePort(portName);
-      return {
-        messagePortName: portName,
-        isTrusted,
-        addMessagePortListener: (listener: any) => {
-          const listenerWrapper = (message: any) => {
-            let remoteAppId = '';
-            let remotePort = '';
-            message.forEach((bundle: any) => {
-              if (bundle.key === 'org_remote_app_id') {
-                remoteAppId = bundle.value;
-              } else if (bundle.key === 'org_remote_port') {
-                remotePort = bundle.value;
-              }
-            });
-            message = message.filter((bundle: any) => {
-              return !bundle.key.includes('org_remote');
-            });
-            let remoteMessagePort = null;
-            if (remoteAppId && remotePort)
-              remoteMessagePort = global.tizen.messageport.requestRemoteMessagePort(remoteAppId, remotePort);
-            return listener(message, remoteMessagePort);
-          }
-          return messagePort.addMessagePortListener(listenerWrapper);
-        },
-        removeMessagePortListener: (watchId: any) => {
-          return messagePort.removeMessagePortListener(watchId);
-        }
-      }
-    }
+    LocalMessagePort.setPrototype(this.funcRequestLocalMessagePort, this.funcRequestRemoteMessagePort);
 
     global.tizen.messageport.requestLocalMessagePort = (portName: string) => {
-      registerMessagePort('requestLocalMessagePort', portName);
-      return makeMessagePort(portName, false);
+      const messagePortObj = this.funcRequestLocalMessagePort(portName);
+      return new LocalMessagePort(messagePortObj, portName, false, this.serviceId);
     }
     global.tizen.messageport.requestTrustedLocalMessagePort = (portName: string) => {
-      registerMessagePort('requestTrustedLocalMessagePort', portName);
-      return makeMessagePort(portName, true);
+      const messagePortObj = this.funcRequestLocalMessagePort(portName);
+      return new LocalMessagePort(messagePortObj, portName, true, this.serviceId);
+    }
+    global.tizen.messageport.requestRemoteMessagePort = (appId: string, portName: string) => {
+      const messagePortObj = this.funcRequestRemoteMessagePort(appId, portName);
+      return new RemoteMessagePort(messagePortObj, appId, portName);
     }
     global.tizen.messageport.requestTrustedRemoteMessagePort = (appId: string, portName: string) => {
-      return {
-        messagePortName: portName,
-        appId,
-        isTrusted: true,
-        sendMessage: (data: any, localMessagePort?: any) => {
-          registerMessagePort('requestTrustedRemoteMessagePort', portName, appId,
-            () => {
-              let remotePort = global.tizen.messageport.requestRemoteMessagePort(this.serviceId, portName);
-              remotePort.sendMessage(data, localMessagePort);
-            });
-        }
-      }
+      return new RemoteTrustedMessagePort(appId, portName, this.serviceId);
     }
   }
 }
diff --git a/wrt_app/service/message_port_router.ts b/wrt_app/service/message_port_router.ts
new file mode 100644 (file)
index 0000000..bf5927c
--- /dev/null
@@ -0,0 +1,149 @@
+
+let messagePortInfo: any = {};
+
+function registerMessagePort(name: string, portName: string, serviceId: string, appId?: string, callback?: any) {
+  let portInfo = `${name}::${serviceId}::${portName}`;
+  if (messagePortInfo[portInfo] === 'created') {
+    callback?.();
+    return;
+  }
+  let data_payload = [
+    new global.tizen.ApplicationControlData(name, [portName]),
+  ];
+  if (appId) {
+    data_payload.push(new global.tizen.ApplicationControlData('appId', [appId]));
+  }
+  let appControl = new global.tizen.ApplicationControl(
+    "http://tizen.org/appcontrol/operation/default", null, null, null,
+    data_payload, null);
+  global.tizen.application.launchAppControl(appControl, serviceId,
+    () => {
+      console.debug(`'${portInfo}' is requsted`)
+      callback?.();
+      messagePortInfo[portInfo] = 'created';
+    });
+}
+
+export class LocalMessagePort {
+  messagePortObj: any;
+  messagePortName: string;
+  serviceAppId: string;
+  isTrusted: boolean;
+  _id: any;
+
+  static funcLocalMessagePort: any;
+  static funcRemoteMessagePort: any;
+
+  constructor(messagePortObj: any, messagePortName: string, isTrusted: boolean, serviceAppId: string) {
+    this.messagePortObj = messagePortObj;
+    this.messagePortName = messagePortName;
+    this.isTrusted = isTrusted;
+    this.serviceAppId = serviceAppId;
+    this._id = messagePortObj._id;
+
+    if (isTrusted) {
+      registerMessagePort('requestTrustedLocalMessagePort', messagePortName, serviceAppId);
+    } else {
+      registerMessagePort('requestLocalMessagePort', messagePortName, serviceAppId);
+    }
+  }
+
+  static setPrototype(funcLocalMessagePort: any, funcRemoteMessagePort: any) {
+    this.funcLocalMessagePort = funcLocalMessagePort;
+    this.funcRemoteMessagePort = funcRemoteMessagePort;
+  }
+
+  addMessagePortListener(listener: any) {
+    const listenerWrapper = (message: any) => {
+      let remoteAppId = '';
+      let remotePort = '';
+      message.forEach((bundle: any) => {
+        if (bundle.key === 'org_remote_app_id') {
+          remoteAppId = bundle.value;
+        } else if (bundle.key === 'org_remote_port') {
+          remotePort = bundle.value;
+        }
+      });
+      message = message.filter((bundle: any) => {
+        return !bundle.key.includes('org_remote');
+      });
+      let remoteMessagePort = undefined;
+      if (remoteAppId && remotePort)
+        remoteMessagePort = LocalMessagePort.funcRemoteMessagePort(remoteAppId, remotePort);
+      return listener(message, remoteMessagePort);
+    }
+    this.messagePortObj.addMessagePortListener(listenerWrapper);
+  }
+
+  removeMessagePortListener(watchId: any) {
+    this.messagePortObj.removeMessagePortListener(watchId);
+  }
+
+  toString() {
+    return 'LocalMessagePortRouter';
+  }
+
+  get() {
+    return this.messagePortObj;
+  }
+}
+
+export class RemoteMessagePort {
+  messagePortObj: any;
+  messagePortName: string;
+  remoteAppId: string;
+
+  constructor(messagePortObj: any, remoteAppId: string, messagePortName: string) {
+    this.messagePortObj = messagePortObj;
+    this.messagePortName = messagePortName;
+    this.remoteAppId = remoteAppId;
+  }
+
+  sendMessage(data: any, localMessagePort?: any) {
+    if (localMessagePort == 'LocalMessagePortRouter') {
+      localMessagePort = localMessagePort.get();
+    }
+    if (!this.messagePortObj) {
+      console.debug('this.messagePortObj is not set');
+      return;
+    }
+    if (localMessagePort) {
+      this.messagePortObj.sendMessage(data, localMessagePort);
+    } else {
+      this.messagePortObj.sendMessage(data);
+    }
+  }
+}
+
+export class RemoteTrustedMessagePort {
+  messagePortName: string;
+  remoteAppId: string;
+  serviceAppId: string;
+  remoteMessagePort: any;
+
+  constructor(remoteAppId: string, messagePortName: string, serviceAppid: string) {
+    this.messagePortName = messagePortName;
+    this.remoteAppId = remoteAppId;
+    this.serviceAppId = serviceAppid;
+  }
+
+  sendMessage(data: any, localMessagePort?: any) {
+    if (localMessagePort == 'LocalMessagePortRouter') {
+      localMessagePort = localMessagePort.get();
+    }
+    registerMessagePort(
+      'requestTrustedRemoteMessagePort',
+      this.messagePortName,
+      this.serviceAppId,
+      this.remoteAppId,
+      () => {
+        let remotePort = LocalMessagePort.funcRemoteMessagePort(this.serviceAppId, this.messagePortName);
+        if (localMessagePort) {
+          remotePort.sendMessage(data, localMessagePort);
+        } else {
+          remotePort.sendMessage(data);
+        }
+      }
+    );
+  }
+}