001package Torello.Browser.BrowserAPI;
002
003// *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
004// Java-HTML Imports
005// *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
006
007import Torello.Browser.*;
008import Torello.Browser.helper.*;
009import Torello.Browser.JavaScriptAPI.*;
010import Torello.JSON.*;
011
012import Torello.Java.ReadOnly.ReadOnlyList;
013import Torello.Java.ReadOnly.ReadOnlyArrayList;
014
015import Torello.JavaDoc.Annotations.StaticFunctional;
016import Torello.JavaDoc.Annotations.JDHeaderBackgroundImg;
017
018import Torello.Browser.BrowserAPI.NestedHelpers.Commands.PWA$$Commands;
019
020
021// *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
022// JDK Imports
023// *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
024
025import javax.json.JsonObject;
026import javax.json.JsonValue;
027
028/**
029 * <SPAN CLASS=COPIEDJDK><B>This domain allows interacting with the browser to control PWAs.</B></SPAN>
030 * <EMBED CLASS='external-html' DATA-FILE-ID=CDP.CODE_GEN_NOTE>
031 */
032@StaticFunctional@JDHeaderBackgroundImg(EmbedTagFileID="CDP.WOOD_PLANK_NOTE")
033public class PWA
034{
035    // No Pubic Constructors
036    private PWA() { }
037
038
039    // ********************************************************************************************
040    // ********************************************************************************************
041    // Enumerated String Constants Lists
042    // ********************************************************************************************
043    // ********************************************************************************************
044
045
046    /**
047     * If user prefers opening the app in browser or an app window.
048     * <BR /><BR /><B CLASS=StrEnumType>String-Enumeration Type</B>
049     */
050    public static final ReadOnlyList<String> DisplayMode = new ReadOnlyArrayList<>
051        (String.class, "browser", "standalone");
052
053
054
055    // ********************************************************************************************
056    // ********************************************************************************************
057    // Basic Types
058    // ********************************************************************************************
059    // ********************************************************************************************
060
061
062    /**
063     * <CODE>[No Description Provided by Google]</CODE>
064     * 
065     * <EMBED CLASS=globalDefs DATA-DOMAIN=PWA DATA-API=BrowserAPI>
066     */
067    @JDHeaderBackgroundImg(EmbedTagFileID="CDP.NESTED_TYPE_JDHBI")
068    public static class FileHandler
069        extends BaseType<FileHandler>
070        implements java.io.Serializable
071    {
072        /** <EMBED CLASS='external-html' DATA-FILE-ID=SVUID> */
073        protected static final long serialVersionUID = 1;
074
075        private static final NestedHelper<PWA.FileHandler> singleton =
076            Torello.Browser.BrowserAPI.NestedHelpers.Types.
077                PWA$$FileHandler$$.singleton;
078
079        /** <CODE>[No Description Provided by Google]</CODE> */
080        public final String action;
081
082        /** <CODE>[No Description Provided by Google]</CODE> */
083        public final PWA.FileHandlerAccept[] accepts;
084
085        /** <CODE>[No Description Provided by Google]</CODE> */
086        public final String displayName;
087
088        /** Constructor.  Please review this class' fields for documentation. */
089        public FileHandler(
090                ReadOnlyList<Boolean> isPresent, String action, FileHandlerAccept[] accepts,
091                String displayName
092            )
093        {
094            super(singleton, Domains.PWA, "FileHandler", 3);
095
096            this.action         = action;
097            this.accepts        = accepts;
098            this.displayName    = displayName;
099
100            this.isPresent = (isPresent == null)
101                ? singleton.generateIsPresentList(this)
102                : THROWS.check(isPresent, 3, "PWA.FileHandler");
103        }
104
105        /** Creates an instance of this class from a {@link JsonObject}.*/
106        public static FileHandler fromJSON(JsonObject jo)
107        { return singleton.fromJSON(jo); }
108
109        /** Returns this class's {@link NestedDescriptor} singleton-instance. class / type.*/
110        public static NestedDescriptor<FileHandler> descriptor()
111        { return singleton.descriptor(); }
112    }
113
114    /**
115     * The following types are the replica of
116     * https://crsrc.org/c/chrome/browser/web_applications/proto/web_app_os_integration_state.proto;drc=9910d3be894c8f142c977ba1023f30a656bc13fc;l=67
117     * 
118     * <EMBED CLASS=globalDefs DATA-DOMAIN=PWA DATA-API=BrowserAPI>
119     */
120    @JDHeaderBackgroundImg(EmbedTagFileID="CDP.NESTED_TYPE_JDHBI")
121    public static class FileHandlerAccept
122        extends BaseType<FileHandlerAccept>
123        implements java.io.Serializable
124    {
125        /** <EMBED CLASS='external-html' DATA-FILE-ID=SVUID> */
126        protected static final long serialVersionUID = 1;
127
128        private static final NestedHelper<PWA.FileHandlerAccept> singleton =
129            Torello.Browser.BrowserAPI.NestedHelpers.Types.
130                PWA$$FileHandlerAccept$$.singleton;
131
132        /**
133         * New name of the mimetype according to
134         * https://www.iana.org/assignments/media-types/media-types.xhtml
135         */
136        public final String mediaType;
137
138        /** <CODE>[No Description Provided by Google]</CODE> */
139        public final String[] fileExtensions;
140
141        /** Constructor.  Please review this class' fields for documentation. */
142        public FileHandlerAccept
143            (ReadOnlyList<Boolean> isPresent, String mediaType, String[] fileExtensions)
144        {
145            super(singleton, Domains.PWA, "FileHandlerAccept", 2);
146
147            this.mediaType      = mediaType;
148            this.fileExtensions = fileExtensions;
149
150            this.isPresent = (isPresent == null)
151                ? singleton.generateIsPresentList(this)
152                : THROWS.check(isPresent, 2, "PWA.FileHandlerAccept");
153        }
154
155        /** Creates an instance of this class from a {@link JsonObject}.*/
156        public static FileHandlerAccept fromJSON(JsonObject jo)
157        { return singleton.fromJSON(jo); }
158
159        /** Returns this class's {@link NestedDescriptor} singleton-instance. class / type.*/
160        public static NestedDescriptor<FileHandlerAccept> descriptor()
161        { return singleton.descriptor(); }
162    }
163
164
165    // ********************************************************************************************
166    // ********************************************************************************************
167    // Command-Return Types
168    // ********************************************************************************************
169    // ********************************************************************************************
170
171
172    /**
173     * Returns the following OS state for the given manifest id.
174     * 
175     * <EMBED CLASS=globalDefs DATA-DOMAIN=PWA DATA-API=BrowserAPI DATA-CMD=getOsAppState>
176     * @see PWA#getOsAppState
177     */
178    @JDHeaderBackgroundImg(EmbedTagFileID="CDP.NESTED_CMD_JDHBI")
179    public static class getOsAppState$$RET
180        extends BaseType<getOsAppState$$RET>
181        implements java.io.Serializable
182    {
183        /** <EMBED CLASS='external-html' DATA-FILE-ID=SVUID> */
184        protected static final long serialVersionUID = 1;
185
186        private static final NestedHelper<PWA.getOsAppState$$RET> singleton =
187            Torello.Browser.BrowserAPI.NestedHelpers.CmdReturns.
188                PWA$$getOsAppState$$RET.singleton;
189
190        /** <CODE>[No Description Provided by Google]</CODE> */
191        public final int badgeCount;
192
193        /** <CODE>[No Description Provided by Google]</CODE> */
194        public final PWA.FileHandler[] fileHandlers;
195
196        /** Constructor.  Please review this class' fields for documentation. */
197        public getOsAppState$$RET
198            (ReadOnlyList<Boolean> isPresent, int badgeCount, FileHandler[] fileHandlers)
199        {
200            super(singleton, Domains.PWA, "getOsAppState", 2);
201
202            this.badgeCount     = badgeCount;
203            this.fileHandlers   = fileHandlers;
204
205            this.isPresent = (isPresent == null)
206                ? singleton.generateIsPresentList(this)
207                : THROWS.check(isPresent, 2, "PWA.getOsAppState$$RET");
208        }
209
210        /** Creates an instance of this class from a {@link JsonObject}.*/
211        public static getOsAppState$$RET fromJSON(JsonObject jo)
212        { return singleton.fromJSON(jo); }
213
214        /** Returns this class's {@link NestedDescriptor} singleton-instance. class / type.*/
215        public static NestedDescriptor<getOsAppState$$RET> descriptor()
216        { return singleton.descriptor(); }
217    }
218
219
220
221
222    // ********************************************************************************************
223    // ********************************************************************************************
224    // Commands
225    // ********************************************************************************************
226    // ********************************************************************************************
227
228
229    /**
230     * Changes user settings of the web app identified by its manifestId. If the
231     * app was not installed, this command returns an error. Unset parameters will
232     * be ignored; unrecognized values will cause an error.
233     * 
234     * Unlike the ones defined in the manifest files of the web apps, these
235     * settings are provided by the browser and controlled by the users, they
236     * impact the way the browser handling the web apps.
237     * 
238     * See the comment of each parameter.
239     * 
240     * @param manifestId -
241     * 
242     * @param linkCapturing 
243     * If user allows the links clicked on by the user in the app's scope, or
244     * extended scope if the manifest has scope extensions and the flags
245     * <CODE>DesktopPWAsLinkCapturingWithScopeExtensions</CODE> and
246     * <CODE>WebAppEnableScopeExtensions</CODE> are enabled.
247     * 
248     * Note, the API does not support resetting the linkCapturing to the
249     * initial value, uninstalling and installing the web app again will reset
250     * it.
251     * 
252     * TODO(crbug.com/339453269): Setting this value on ChromeOS is not
253     * supported yet.
254     * <BR /><B CLASS=Opt-Top>OPTIONAL</B>
255     * 
256     * @param displayMode -
257     * <BR /><B CLASS=Opt-Top>OPTIONAL</B>
258     * 
259     * @return An instance of <CODE>{@link Script}&lt;Void&gt;</CODE>
260     *
261     * <BR /><BR />This {@code Script} instance must be <B STYLE='color:red'>executed</B> before the
262     * browser receives the invocation-request.
263     *
264     * <BR /><BR /><DIV CLASS=JDHint>
265     * This Browser-Function <I>does not have</I> a return-value.  You may choose to
266     * <B STYLE='color: red'>await</B> the {@link Promise}{@code <Void>} to ensure that
267     * the Browser Function has run to completion.
268     * </DIV>
269     */
270    public static Script<Void> changeAppUserSettings
271        (String manifestId, Boolean linkCapturing, String displayMode)
272    {
273        // Convert all Method Parameters into a JSON Request-Object (as a String)
274        final String requestJSON = WriteJSON.get(
275            PWA$$Commands.changeAppUserSettings$$, "PWA.changeAppUserSettings",
276            manifestId, linkCapturing, displayMode
277        );
278
279        return Script.NO_RET(Domains.PWA, "changeAppUserSettings", requestJSON);
280    }
281
282    /**
283     * Returns the following OS state for the given manifest id.
284     * 
285     * @param manifestId 
286     * The id from the webapp's manifest file, commonly it's the url of the
287     * site installing the webapp. See
288     * https://web.dev/learn/pwa/web-app-manifest.
289     * 
290     * @return An instance of <CODE>{@link Script}&lt;{@link getOsAppState$$RET}&gt;</CODE>
291     * 
292     * <BR /><BR />This <B>script</B> may be <B STYLE='color: red'>executed</B>, using
293     * {@link Script#exec(WebSocketSender) Script.exec}, and afterwards, a {@link Promise}
294     * <CODE>&lt;{@link getOsAppState$$RET}&gt;</CODE> will be returned
295     *
296     * <BR /><BR />Finally, the <B>{@code Promise}</B> may be <B STYLE='color: red'>awaited</B>,
297     * using {@link Promise#await()}, <I>and the returned result of this Browser Function may
298     * be retrieved.</I>
299     *
300     * <BR /><BR /><DIV CLASS=JDHint>
301     * This Browser Function's {@code Promise} returns:{@link getOsAppState$$RET}
302     * A dedicated return type implies that the browser may return more than 1 datum
303     * </DIV>
304     */
305    public static Script<getOsAppState$$RET> getOsAppState(String manifestId)
306    {
307        // Build the JSON Request-Object (as a String); only 1 Parameter is passed
308        final String requestJSON = WriteJSON.get
309            (CDPTypes.STRING, "manifestId", false, "PWA.getOsAppState", manifestId);
310
311        return new Script<>(
312            Domains.PWA, "getOsAppState", requestJSON,
313            getOsAppState$$RET::fromJSON,
314            getOsAppState$$RET.class
315        );
316    }
317
318    /**
319     * Installs the given manifest identity, optionally using the given installUrlOrBundleUrl
320     * 
321     * IWA-specific install description:
322     * manifestId corresponds to isolated-app:// + web_package::SignedWebBundleId
323     * 
324     * File installation mode:
325     * The installUrlOrBundleUrl can be either file:// or http(s):// pointing
326     * to a signed web bundle (.swbn). In this case SignedWebBundleId must correspond to
327     * The .swbn file's signing key.
328     * 
329     * Dev proxy installation mode:
330     * installUrlOrBundleUrl must be http(s):// that serves dev mode IWA.
331     * web_package::SignedWebBundleId must be of type dev proxy.
332     * 
333     * The advantage of dev proxy mode is that all changes to IWA
334     * automatically will be reflected in the running app without
335     * reinstallation.
336     * 
337     * To generate bundle id for proxy mode:
338     * 1. Generate 32 random bytes.
339     * 2. Add a specific suffix 0x00 at the end.
340     * 3. Encode the entire sequence using Base32 without padding.
341     * 
342     * If Chrome is not in IWA dev
343     * mode, the installation will fail, regardless of the state of the allowlist.
344     * 
345     * @param manifestId -
346     * 
347     * @param installUrlOrBundleUrl 
348     * The location of the app or bundle overriding the one derived from the
349     * manifestId.
350     * <BR /><B CLASS=Opt-Top>OPTIONAL</B>
351     * 
352     * @return An instance of <CODE>{@link Script}&lt;Void&gt;</CODE>
353     *
354     * <BR /><BR />This {@code Script} instance must be <B STYLE='color:red'>executed</B> before the
355     * browser receives the invocation-request.
356     *
357     * <BR /><BR /><DIV CLASS=JDHint>
358     * This Browser-Function <I>does not have</I> a return-value.  You may choose to
359     * <B STYLE='color: red'>await</B> the {@link Promise}{@code <Void>} to ensure that
360     * the Browser Function has run to completion.
361     * </DIV>
362     */
363    public static Script<Void> install(String manifestId, String installUrlOrBundleUrl)
364    {
365        // Convert all Method Parameters into a JSON Request-Object (as a String)
366        final String requestJSON = WriteJSON.get(
367            PWA$$Commands.install$$, "PWA.install",
368            manifestId, installUrlOrBundleUrl
369        );
370
371        return Script.NO_RET(Domains.PWA, "install", requestJSON);
372    }
373
374    /**
375     * Launches the installed web app, or an url in the same web app instead of the
376     * default start url if it is provided. Returns a page Target.TargetID which
377     * can be used to attach to via Target.attachToTarget or similar APIs.
378     * 
379     * @param manifestId -
380     * 
381     * @param url -
382     * <BR /><B CLASS=Opt-Top>OPTIONAL</B>
383     * 
384     * @return An instance of <CODE>{@link Script}&lt;String&gt;</CODE>
385     * 
386     * <BR /><BR />This <B>script</B> may be <B STYLE='color: red'>executed</B>, using
387     * {@link Script#exec(WebSocketSender) Script.exec}, and afterwards, a {@link Promise}
388     * <CODE>&lt;String&gt;</CODE> will be returned
389     *
390     * <BR /><BR />Finally, the <B>{@code Promise}</B> may be <B STYLE='color: red'>awaited</B>,
391     * using {@link Promise#await()}, <I>and the returned result of this Browser Function may
392     * be retrieved.</I>
393     *
394     * <BR /><BR /><DIV CLASS=JDHint>
395     * This Browser Function's {@code Promise} returns:
396     * <CODE>String (<B>targetId</B>)</CODE>
397     * <BR />
398     * ID of the tab target created as a result.
399     * </DIV>
400     */
401    public static Script<String> launch(String manifestId, String url)
402    {
403        // Convert all Method Parameters into a JSON Request-Object (as a String)
404        final String requestJSON = WriteJSON.get(
405            PWA$$Commands.launch$$, "PWA.launch",
406            manifestId, url
407        );
408
409        return new Script<>(
410            Domains.PWA, "launch", requestJSON,
411            jo -> ReadJSON.getString(jo, "targetId", true, false),
412            String.class
413        );
414    }
415
416    /**
417     * Opens one or more local files from an installed web app identified by its
418     * manifestId. The web app needs to have file handlers registered to process
419     * the files. The API returns one or more page Target.TargetIDs which can be
420     * used to attach to via Target.attachToTarget or similar APIs.
421     * If some files in the parameters cannot be handled by the web app, they will
422     * be ignored. If none of the files can be handled, this API returns an error.
423     * If no files are provided as the parameter, this API also returns an error.
424     * 
425     * According to the definition of the file handlers in the manifest file, one
426     * Target.TargetID may represent a page handling one or more files. The order
427     * of the returned Target.TargetIDs is not guaranteed.
428     * 
429     * TODO(crbug.com/339454034): Check the existences of the input files.
430     * 
431     * @param manifestId -
432     * 
433     * @param files -
434     * 
435     * @return An instance of <CODE>{@link Script}&lt;String[]&gt;</CODE>
436     * 
437     * <BR /><BR />This <B>script</B> may be <B STYLE='color: red'>executed</B>, using
438     * {@link Script#exec(WebSocketSender) Script.exec}, and afterwards, a {@link Promise}
439     * <CODE>&lt;String[]&gt;</CODE> will be returned
440     *
441     * <BR /><BR />Finally, the <B>{@code Promise}</B> may be <B STYLE='color: red'>awaited</B>,
442     * using {@link Promise#await()}, <I>and the returned result of this Browser Function may
443     * be retrieved.</I>
444     *
445     * <BR /><BR /><DIV CLASS=JDHint>
446     * This Browser Function's {@code Promise} returns:
447     * <CODE>String[] (<B>targetIds</B>)</CODE>
448     * <BR />
449     * IDs of the tab targets created as the result.
450     * </DIV>
451     */
452    public static Script<String[]> launchFilesInApp(String manifestId, String[] files)
453    {
454        // Convert all Method Parameters into a JSON Request-Object (as a String)
455        final String requestJSON = WriteJSON.get(
456            PWA$$Commands.launchFilesInApp$$, "PWA.launchFilesInApp",
457            manifestId, files
458        );
459
460        return new Script<>(
461            Domains.PWA, "launchFilesInApp", requestJSON,
462            PWA$$Commands::launchFilesInApp,
463            String[].class
464        );
465    }
466
467    /**
468     * Opens the current page in its web app identified by the manifest id, needs
469     * to be called on a page target. This function returns immediately without
470     * waiting for the app to finish loading.
471     * 
472     * @param manifestId -
473     * 
474     * @return An instance of <CODE>{@link Script}&lt;Void&gt;</CODE>
475     *
476     * <BR /><BR />This {@code Script} instance must be <B STYLE='color:red'>executed</B> before the
477     * browser receives the invocation-request.
478     *
479     * <BR /><BR /><DIV CLASS=JDHint>
480     * This Browser-Function <I>does not have</I> a return-value.  You may choose to
481     * <B STYLE='color: red'>await</B> the {@link Promise}{@code <Void>} to ensure that
482     * the Browser Function has run to completion.
483     * </DIV>
484     */
485    public static Script<Void> openCurrentPageInApp(String manifestId)
486    {
487        // Build the JSON Request-Object (as a String); only 1 Parameter is passed
488        final String requestJSON = WriteJSON.get
489            (CDPTypes.STRING, "manifestId", false, "PWA.openCurrentPageInApp", manifestId);
490
491        return Script.NO_RET(Domains.PWA, "openCurrentPageInApp", requestJSON);
492    }
493
494    /**
495     * Uninstalls the given manifest_id and closes any opened app windows.
496     * 
497     * @param manifestId -
498     * 
499     * @return An instance of <CODE>{@link Script}&lt;Void&gt;</CODE>
500     *
501     * <BR /><BR />This {@code Script} instance must be <B STYLE='color:red'>executed</B> before the
502     * browser receives the invocation-request.
503     *
504     * <BR /><BR /><DIV CLASS=JDHint>
505     * This Browser-Function <I>does not have</I> a return-value.  You may choose to
506     * <B STYLE='color: red'>await</B> the {@link Promise}{@code <Void>} to ensure that
507     * the Browser Function has run to completion.
508     * </DIV>
509     */
510    public static Script<Void> uninstall(String manifestId)
511    {
512        // Build the JSON Request-Object (as a String); only 1 Parameter is passed
513        final String requestJSON = WriteJSON.get
514            (CDPTypes.STRING, "manifestId", false, "PWA.uninstall", manifestId);
515
516        return Script.NO_RET(Domains.PWA, "uninstall", requestJSON);
517    }
518
519
520}