955fc7d15d9fe9c99af5594ac6078136727a57e1
[platform/framework/web/wrtjs.git] / wrt_app / service / device_api_router.ts
1 import { wrt } from '../browser/wrt';
2
3 export class DeviceAPIRouter {
4   currentApplication: any;
5   funcCurrentApplication: any;
6   funcRequestedAppcontrol: any;
7   funcGetAppInfo: any;
8   funcGetAppcerts: any;
9   funcGetContext: any;
10   funcGetSharedUri: any;
11   funcGetMetadata: any;
12   funcGetPackageInfo: any;
13   funcRequestLocalMessagePort: any;
14   funcRequestTrustedLocalMessagePort: any;
15
16   id: string;
17   serviceId: string;
18   packageId: string;
19   callerAppId: string;
20   permissions: string[];
21   pkgApiVersion: string;
22
23   constructor(id: string, isGlobal: boolean) {
24     this.id = id;
25     let ids = id.split(':');
26     this.serviceId = ids[0];
27     this.callerAppId = ids[1] ?? '';
28     this.packageId = wrt.getPackageId(id);
29     this.permissions = [];
30     this.pkgApiVersion = '';
31
32     this.initWebapis();
33     if (isGlobal) {
34       this.permissions = wrt.getPrivileges(this.id);
35       this.pkgApiVersion = wrt.getPkgApiVersion(this.id);
36       this.refineApplicationApis();
37       this.refinePackageApis();
38       this.refineFilesystemApis()
39       this.refineMessagePortApis()
40       this.refineXwalkUtilApis();
41     }
42   }
43
44   initWebapis() {
45     global.webapis = global.webapis ?? {};
46     global.webapis.getCallerAppId = () => {
47       return this.callerAppId;
48     }
49     global.webapis.getServiceId = () => {
50       return this.serviceId;
51     }
52     global.webapis.getPackageId = () => {
53       return this.packageId;
54     }
55     global.webapis.postPlainNotification = (title: string, message: string, timeout?: number) => {
56       return wrt.postPlainNotification(title, message, timeout ?? 10);
57     }
58     Object.defineProperties(global.webapis, {
59       getCallerAppId: { writable: false, enumerable: true },
60       getPackageId: { writable: false, enumerable: true },
61       getServiceId: { writable: false, enumerable: true },
62       postPlainNotification: { writable: false, enumerable: true },
63     });
64     this.initMDEWebapis();
65     this.initEdgeWebapis();
66     this.initProductWebapis();
67   }
68
69   initMDEWebapis() {
70     if (wrt['mde'] && !global.webapis.mde) {
71       let mde = wrt.mde as NativeWRTjs.MDEExtension;
72       global.webapis.mde = {};
73       if (wrt.tv) {
74         global.webapis.mde.deInitVirtualEventGenerator = (type: number) => {
75           return mde.deInitVirtualEventGenerator(type);
76         }
77         global.webapis.mde.generateVirtualKeyEvent = (keycode: number, state: number) => {
78           return mde.generateVirtualKeyEvent(keycode, state);
79         }
80         global.webapis.mde.generateVirtualMouseButtonEvent = (button: number, status: number) => {
81           return mde.generateVirtualMouseButtonEvent(button, status);
82         }
83         global.webapis.mde.generateVirtualMouseMoveEvent = (x: number, y: number, move_count: number) => {
84           return mde.generateVirtualMouseMoveEvent(x, y, move_count);
85         }
86         global.webapis.mde.initVirtualEventGenerator = (type: number) => {
87           return mde.initVirtualEventGenerator(type);
88         }
89       }
90       global.webapis.mde.getCurrentLoginId = () => {
91         return mde.getCurrentLoginId();
92       }
93       global.webapis.mde.getDeviceName = () => {
94         return mde.getDeviceName();
95       }
96       global.webapis.mde.launchBrowserFromUrl = (url: string) => {
97         return mde.launchBrowserFromUrl(url);
98       }
99       Object.defineProperty(global.webapis, 'mde', { writable: false, enumerable: true });
100     }
101   }
102
103   initEdgeWebapis() {
104     if ((wrt as any)['edge'] && !global.webapis.edge) {
105       let edge = (wrt as any).edge as any;
106       global.webapis.edge = {
107         orchestrationGetDevicelist: (service_name: string, exec_type: string) => {
108           return edge?.orchestrationGetDevicelist(service_name, exec_type);
109         },
110         orchestrationReadCapability: (ip: string) => {
111           return edge?.orchestrationReadCapability(ip);
112         },
113         orchestrationRequestService: (app_name: string, self_select: boolean, exec_type: string, exec_parameter: string) => {
114           return edge?.orchestrationRequestService(app_name, self_select, exec_type, exec_parameter);
115         },
116         orchestrationRequestServiceOnDevice: (app_name: string, self_select: boolean, exec_type: string, exec_parameter: string, ip: string) => {
117           return edge?.orchestrationRequestServiceOnDevice(app_name, self_select, exec_type, exec_parameter, ip);
118         },
119         orchestrationWriteCapability: (json: string) => {
120           return edge?.orchestrationWriteCapability(json);
121         },
122       }
123       Object.defineProperty(global.webapis, 'edge', { writable: false, enumerable: true });
124     }
125   }
126
127   initProductWebapis() {
128     // for TV profile
129     if (wrt.tv && !global.webapis.productinfo) {
130       global.webapis.cachedProperty = global.webapis.cachedProperty ?? {};
131       let getCachedValue = (name: string) => {
132         if (global.webapis.cachedProperty[name]) {
133           return global.webapis.cachedProperty[name];
134         }
135         let tv = wrt.tv as NativeWRTjs.TVExtension;
136         return (global.webapis.cachedProperty[name] = tv.queryProductValue(name));
137       }
138       global.webapis.productinfo = {
139         getDuid: () => {
140           return getCachedValue('getDuid');
141         },
142         getFirmware: () => {
143           return getCachedValue('getFirmware');
144         },
145         getLocalSet: () => {
146           return getCachedValue('getLocalSet');
147         },
148         getModel: () => {
149           return getCachedValue('getModel');
150         },
151         getModelCode: () => {
152           return getCachedValue('getModelCode');
153         },
154         getRealModel: () => {
155           return getCachedValue('getRealModel');
156         },
157         getSmartTVServerVersion: () => {
158           return getCachedValue('getSmartTVServerVersion');
159         },
160         getSmartTVServerType: () => {
161           return Number(getCachedValue('getSmartTVServerType'));
162         },
163         isWallModel: () => {
164           return (getCachedValue('isWallModel') === 'true');
165         },
166         isUHDAModel: () => {
167           return (getCachedValue('isUHDAModel') === 'true');
168         },
169         is8KPanelSupported: () => {
170           return (getCachedValue('is8KPanelSupported') === 'true');
171         }
172       };
173
174       global.webapis.productinfo.ProductInfoSiServerType = {
175           SI_TYPE_OPERATIING_SERVER: 0,
176           SI_TYPE_DEVELOPMENT_SERVER: 1,
177           SI_TYPE_DEVELOPING_SERVER: 2
178       };
179     }
180   }
181
182   getServiceId() {
183     return global.webapis.getServiceId();
184   }
185
186   getPackageId() {
187     return global.webapis.getPackageId();
188   }
189
190   hasNoneOrNull(args: any[]) {
191     return !args.length || null === args[0];
192   }
193
194   refineApplicationApis() {
195     // tizen.application.getCurrentApplication()
196     this.funcCurrentApplication = global.tizen.application.getCurrentApplication;
197     global.tizen.application.getCurrentApplication = () => {
198       console.debug(`Routing - getCurrentApplication() : ${this.getServiceId()}`);
199       if (this.currentApplication)
200         return this.currentApplication;
201       this.currentApplication = {};
202       const originCurrentApplication = this.funcCurrentApplication();
203       for (let key in originCurrentApplication) {
204         if (key === 'appInfo') {
205           this.currentApplication.appInfo = this.funcGetAppInfo(this.getServiceId());
206         } else {
207           if (key === 'broadcastEvent' || key === 'broadcastTrustedEvent') {
208             this.currentApplication[key] = originCurrentApplication[key].bind(originCurrentApplication);
209           } else {
210             this.currentApplication[key] = originCurrentApplication[key];
211           }
212         }
213       }
214       Object.defineProperties(this.currentApplication.appInfo, {
215         categories: { writable: false, enumerable: true },
216         iconPath: { writable: false, enumerable: true },
217         id: { writable: false, enumerable: true },
218         installDate: { writable: false, enumerable: true },
219         name: { writable: false, enumerable: true },
220         packageId: { writable: false, enumerable: true },
221         show: { writable: false, enumerable: true },
222         size: { enumerable: true },
223         version: { writable: false, enumerable: true }
224       });
225       Object.defineProperties(this.currentApplication, {
226         appInfo: { enumerable: true },
227         contextId: { writable: false, enumerable: true }
228       });
229       // tizen.application.getCurrentApplication().getRequestedAppControl()
230       this.funcRequestedAppcontrol = this.currentApplication.getRequestedAppControl;
231       this.currentApplication.getRequestedAppControl = () => {
232         console.debug(`Routing - getRequestedAppControl() : ${this.getServiceId()}`);
233         return this.funcRequestedAppcontrol();
234       }
235       return this.currentApplication;
236     }
237     // tizen.application.getAppInfo()
238     this.funcGetAppInfo = global.tizen.application.getAppInfo;
239     global.tizen.application.getAppInfo = (...args: any[]) => {
240       let app_id = args[0];
241       if (this.hasNoneOrNull(args))
242         app_id = this.getServiceId();
243       console.debug(`Routing - getAppInfo(${app_id})`);
244       return this.funcGetAppInfo(app_id);
245     }
246     // tizen.application.getAppCerts()
247     this.funcGetAppcerts = global.tizen.application.getAppCerts;
248     global.tizen.application.getAppCerts = (...args: any[]) => {
249       let app_id = args[0];
250       if (this.hasNoneOrNull(args))
251         app_id = this.getServiceId();
252       console.debug(`Routing - getAppCerts() ` + app_id);
253       return this.funcGetAppcerts(app_id);
254     }
255     // tizen.application.getAppContext()
256     this.funcGetContext = global.tizen.application.getAppContext;
257     global.tizen.application.getAppContext = (...args: any[]) => {
258       console.debug(`Routing - getAppContext()`);
259       if (this.hasNoneOrNull(args)) {
260         const context = {"id": this.funcGetContext().id, "appId": this.getServiceId()};
261         Object.defineProperties(context, {
262           appId: { writable: false, enumerable: true },
263           id: { writable: false, enumerable: true }
264         });
265         return context;
266       }
267       return this.funcGetContext(args[0]);
268     }
269     // tizen.application.getAppSharedURI()
270     this.funcGetSharedUri = global.tizen.application.getAppSharedURI;
271     global.tizen.application.getAppSharedURI = (...args: any[]) => {
272       let app_id = args[0];
273       if (this.hasNoneOrNull(args))
274         app_id = this.getServiceId();
275       console.debug(`Routing - getAppSharedURI()`);
276       return this.funcGetSharedUri(app_id);
277     }
278     // tizen.application.getAppMetaData()
279     this.funcGetMetadata = global.tizen.application.getAppMetaData;
280     global.tizen.application.getAppMetaData = (...args: any[]) => {
281       let app_id = args[0];
282       if (this.hasNoneOrNull(args))
283         app_id = this.getServiceId();
284       console.debug(`Routing - getAppMetaData()`);
285       return this.funcGetMetadata(app_id);
286     }
287   }
288
289   refinePackageApis() {
290     // tizen.package.getPackageInfo()
291     this.funcGetPackageInfo = global.tizen.package.getPackageInfo;
292     global.tizen.package.getPackageInfo = (...args: any[]) => {
293       let package_id = args[0];
294       if (this.hasNoneOrNull(args))
295         package_id = this.getPackageId();
296       console.debug(`Routing - getPackageInfo() : ${package_id}`);
297       return this.funcGetPackageInfo(package_id);
298     }
299   }
300
301   refineFilesystemApis() {
302     try {
303       let virtualPath = ['wgt-private', 'wgt-private-tmp', 'wgt-package'];
304       virtualPath.forEach(name => {
305         let realPath = wrt.resolveVirtualRoot(this.id, name);
306         global.tizen.filesystem.setVirtualPath(name, realPath, 'INTERVAL', 'MOUNTED');
307       });
308     } catch (e) {
309       console.debug(`refineFilesystemApis has an error ${e}`);
310     }
311   }
312
313   refineXwalkUtilApis() {
314     global.xwalk.utils.checkPrivilegeAccess = (privilege: string) => {
315       if (!this.permissions.includes(privilege)) {
316         throw 'Permission denied';
317       }
318     }
319     global.xwalk.utils.getPkgApiVersion = () => {
320       return this.pkgApiVersion;
321     }
322   }
323
324   refineMessagePortApis() {
325     this.funcRequestLocalMessagePort =
326       global.tizen.messageport.requestLocalMessagePort;
327     this.funcRequestTrustedLocalMessagePort =
328       global.tizen.messageport.requestTrustedLocalMessagePort;
329
330     const registerMessagePort = (name: string, portName: string) => {
331       let data_payload = [
332         new global.tizen.ApplicationControlData(name, [ portName ]),
333
334       ];
335       let appControl = new global.tizen.ApplicationControl(
336           "http://tizen.org/appcontrol/operation/default", null, null, null,
337           data_payload, null);
338       global.tizen.application.launchAppControl(appControl, this.serviceId,
339         () => console.debug(`'${this.serviceId}::${name}' is requsted`));
340     }
341
342     global.tizen.messageport.requestLocalMessagePort = (portName: string) => {
343       registerMessagePort('requestLocalMessagePort', portName);
344       return this.funcRequestLocalMessagePort(portName);
345     }
346     global.tizen.messageport.requestTrustedLocalMessagePort = (portName: string) => {
347       registerMessagePort('requestTrustedLocalMessagePort', portName);
348       return this.funcRequestLocalMessagePort(portName);
349     }
350   }
351 }
352
353 let instance: DeviceAPIRouter | undefined;
354 export const initialize = (id: string, isGlobal: boolean) => {
355   instance = new DeviceAPIRouter(id, isGlobal);
356 }
357
358 export const cleanup = () => {
359   delete global.webapis;
360   instance = undefined;
361 }