html2apk 0.8.0 → 0.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +340 -4
- package/package.json +15 -4
- package/src/desktop/main.js +902 -0
- package/src/desktop/preload.js +1 -0
- package/src/desktop/renderer/index.html +12 -6
- package/src/desktop/renderer/renderer.js +1164 -59
- package/src/desktop/renderer/styles.css +199 -30
- package/src/runtime-manager/index.js +79 -17
- package/src/templates/cordova-plugin-html2apk-bridge/plugin.xml +50 -0
- package/src/templates/cordova-plugin-html2apk-bridge/src/android/FloatingIconService.java +33 -0
- package/src/templates/cordova-plugin-html2apk-bridge/src/android/Html2ApkBridge.java +5929 -403
- package/src/templates/cordova-plugin-html2apk-bridge/src/android/xml/html2apk_file_paths.xml +6 -0
- package/src/templates/cordova-plugin-html2apk-bridge/www/html2apk-bridge.js +882 -4
- package/src/templates/html2apk-early-bridge.js +879 -4
- package/src/templates/html2apk-runtime-console.js +321 -29
- package/examples/minimal/dist/MeuApp-1.0.0-debug.apk +0 -0
- package/examples/minimal/dist/MeuApp-1.0.0-release.aab +0 -0
package/src/desktop/main.js
CHANGED
|
@@ -395,6 +395,865 @@ function cleanBuildOptions(options = {}) {
|
|
|
395
395
|
return output;
|
|
396
396
|
}
|
|
397
397
|
|
|
398
|
+
function nativeFunctionLabHtml() {
|
|
399
|
+
return `<!doctype html>
|
|
400
|
+
<html lang="pt-BR">
|
|
401
|
+
<head>
|
|
402
|
+
<meta charset="utf-8">
|
|
403
|
+
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
404
|
+
<title>html2apk - Teste de funcoes</title>
|
|
405
|
+
<style>
|
|
406
|
+
:root {
|
|
407
|
+
color-scheme: light dark;
|
|
408
|
+
--bg: #f6f8fb;
|
|
409
|
+
--panel: #ffffff;
|
|
410
|
+
--text: #172033;
|
|
411
|
+
--muted: #65758b;
|
|
412
|
+
--line: #dbe3ee;
|
|
413
|
+
--blue: #126fff;
|
|
414
|
+
--green: #18864b;
|
|
415
|
+
--red: #c33b3b;
|
|
416
|
+
--code: #0c1117;
|
|
417
|
+
--soft-green: #e8f7ef;
|
|
418
|
+
--soft-amber: #fff6dd;
|
|
419
|
+
}
|
|
420
|
+
* { box-sizing: border-box; }
|
|
421
|
+
body {
|
|
422
|
+
margin: 0;
|
|
423
|
+
font-family: Inter, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
|
|
424
|
+
background: var(--bg);
|
|
425
|
+
color: var(--text);
|
|
426
|
+
line-height: 1.45;
|
|
427
|
+
}
|
|
428
|
+
header {
|
|
429
|
+
position: sticky;
|
|
430
|
+
top: 0;
|
|
431
|
+
z-index: 2;
|
|
432
|
+
background: color-mix(in srgb, var(--panel) 92%, transparent);
|
|
433
|
+
border-bottom: 1px solid var(--line);
|
|
434
|
+
padding: 14px 16px;
|
|
435
|
+
backdrop-filter: blur(14px);
|
|
436
|
+
}
|
|
437
|
+
h1 { margin: 0; font-size: 1.2rem; }
|
|
438
|
+
header p { margin: 6px 0 0; color: var(--muted); line-height: 1.35; }
|
|
439
|
+
main { display: grid; gap: 14px; padding: 14px; }
|
|
440
|
+
#groups { display: grid; gap: 14px; }
|
|
441
|
+
section {
|
|
442
|
+
border: 1px solid var(--line);
|
|
443
|
+
border-radius: 8px;
|
|
444
|
+
background: var(--panel);
|
|
445
|
+
overflow: hidden;
|
|
446
|
+
}
|
|
447
|
+
h2 {
|
|
448
|
+
margin: 0;
|
|
449
|
+
padding: 13px 14px;
|
|
450
|
+
font-size: .98rem;
|
|
451
|
+
border-bottom: 1px solid var(--line);
|
|
452
|
+
}
|
|
453
|
+
h2.with-action {
|
|
454
|
+
display: flex;
|
|
455
|
+
align-items: center;
|
|
456
|
+
justify-content: space-between;
|
|
457
|
+
gap: 10px;
|
|
458
|
+
}
|
|
459
|
+
h2.with-action button {
|
|
460
|
+
min-height: 32px;
|
|
461
|
+
width: auto;
|
|
462
|
+
padding: 6px 9px;
|
|
463
|
+
font-size: .78rem;
|
|
464
|
+
text-align: center;
|
|
465
|
+
white-space: nowrap;
|
|
466
|
+
}
|
|
467
|
+
.toolbar {
|
|
468
|
+
display: grid;
|
|
469
|
+
grid-template-columns: repeat(4, minmax(0, 1fr));
|
|
470
|
+
gap: 8px;
|
|
471
|
+
margin-top: 12px;
|
|
472
|
+
}
|
|
473
|
+
.toolbar input {
|
|
474
|
+
grid-column: 1 / -1;
|
|
475
|
+
min-height: 42px;
|
|
476
|
+
width: 100%;
|
|
477
|
+
border: 1px solid var(--line);
|
|
478
|
+
border-radius: 8px;
|
|
479
|
+
background: var(--panel);
|
|
480
|
+
color: var(--text);
|
|
481
|
+
padding: 9px 11px;
|
|
482
|
+
font: inherit;
|
|
483
|
+
}
|
|
484
|
+
.stats {
|
|
485
|
+
display: flex;
|
|
486
|
+
flex-wrap: wrap;
|
|
487
|
+
gap: 8px;
|
|
488
|
+
margin-top: 10px;
|
|
489
|
+
}
|
|
490
|
+
.chip {
|
|
491
|
+
border: 1px solid var(--line);
|
|
492
|
+
border-radius: 999px;
|
|
493
|
+
color: var(--muted);
|
|
494
|
+
background: var(--panel);
|
|
495
|
+
padding: 4px 9px;
|
|
496
|
+
font-size: .78rem;
|
|
497
|
+
font-weight: 800;
|
|
498
|
+
}
|
|
499
|
+
.grid {
|
|
500
|
+
display: grid;
|
|
501
|
+
grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
|
|
502
|
+
gap: 10px;
|
|
503
|
+
padding: 12px;
|
|
504
|
+
}
|
|
505
|
+
button {
|
|
506
|
+
min-height: 48px;
|
|
507
|
+
border: 1px solid var(--line);
|
|
508
|
+
border-radius: 8px;
|
|
509
|
+
background: #eef5ff;
|
|
510
|
+
color: var(--blue);
|
|
511
|
+
padding: 10px;
|
|
512
|
+
font-weight: 800;
|
|
513
|
+
text-align: left;
|
|
514
|
+
}
|
|
515
|
+
button[disabled] { opacity: .68; }
|
|
516
|
+
button:active { transform: translateY(1px); }
|
|
517
|
+
button.primary { background: var(--blue); border-color: var(--blue); color: #fff; }
|
|
518
|
+
button.safe { background: var(--soft-green); color: var(--green); }
|
|
519
|
+
button.listener { background: var(--soft-amber); color: #8a5f00; }
|
|
520
|
+
button.external { background: #f2edff; color: #6b46c1; }
|
|
521
|
+
button.running { outline: 2px solid var(--blue); }
|
|
522
|
+
button.ok { border-color: var(--green); }
|
|
523
|
+
button.fail { border-color: var(--red); }
|
|
524
|
+
button small { display: block; margin-top: 4px; color: var(--muted); font-weight: 600; line-height: 1.3; }
|
|
525
|
+
.danger { background: #fff0f0; color: var(--red); }
|
|
526
|
+
.notice {
|
|
527
|
+
margin: 12px;
|
|
528
|
+
padding: 10px 12px;
|
|
529
|
+
border-radius: 8px;
|
|
530
|
+
background: #fff8df;
|
|
531
|
+
color: #745400;
|
|
532
|
+
line-height: 1.42;
|
|
533
|
+
}
|
|
534
|
+
.output-head {
|
|
535
|
+
display: flex;
|
|
536
|
+
align-items: center;
|
|
537
|
+
justify-content: space-between;
|
|
538
|
+
gap: 10px;
|
|
539
|
+
padding: 12px;
|
|
540
|
+
border-bottom: 1px solid var(--line);
|
|
541
|
+
}
|
|
542
|
+
.output-head h2 { padding: 0; border: 0; }
|
|
543
|
+
.output-feed {
|
|
544
|
+
display: grid;
|
|
545
|
+
gap: 8px;
|
|
546
|
+
max-height: 360px;
|
|
547
|
+
overflow: auto;
|
|
548
|
+
padding: 12px;
|
|
549
|
+
}
|
|
550
|
+
.log-entry {
|
|
551
|
+
border: 1px solid var(--line);
|
|
552
|
+
border-left: 4px solid var(--blue);
|
|
553
|
+
border-radius: 8px;
|
|
554
|
+
padding: 9px;
|
|
555
|
+
background: color-mix(in srgb, var(--panel) 96%, var(--blue));
|
|
556
|
+
}
|
|
557
|
+
.log-entry.ok { border-left-color: var(--green); }
|
|
558
|
+
.log-entry.error { border-left-color: var(--red); }
|
|
559
|
+
.log-entry strong { display: block; font-size: .9rem; }
|
|
560
|
+
.log-entry time { display: block; margin-top: 2px; color: var(--muted); font-size: .74rem; }
|
|
561
|
+
.log-entry pre {
|
|
562
|
+
margin: 8px 0 0;
|
|
563
|
+
white-space: pre-wrap;
|
|
564
|
+
word-break: break-word;
|
|
565
|
+
color: #dfe9f8;
|
|
566
|
+
background: var(--code);
|
|
567
|
+
border-radius: 7px;
|
|
568
|
+
padding: 8px;
|
|
569
|
+
font: .78rem/1.45 ui-monospace, SFMono-Regular, Consolas, monospace;
|
|
570
|
+
}
|
|
571
|
+
.guide {
|
|
572
|
+
display: grid;
|
|
573
|
+
grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
|
|
574
|
+
gap: 10px;
|
|
575
|
+
padding: 12px;
|
|
576
|
+
}
|
|
577
|
+
.guide article {
|
|
578
|
+
border: 1px solid var(--line);
|
|
579
|
+
border-radius: 8px;
|
|
580
|
+
padding: 10px;
|
|
581
|
+
background: color-mix(in srgb, var(--panel) 96%, var(--blue));
|
|
582
|
+
}
|
|
583
|
+
.guide strong { display: block; margin-bottom: 4px; }
|
|
584
|
+
.guide p { margin: 0; color: var(--muted); font-size: .88rem; }
|
|
585
|
+
@media (prefers-color-scheme: dark) {
|
|
586
|
+
:root {
|
|
587
|
+
--bg: #10141b;
|
|
588
|
+
--panel: #151b24;
|
|
589
|
+
--text: #e6edf7;
|
|
590
|
+
--muted: #9aa8ba;
|
|
591
|
+
--line: #283243;
|
|
592
|
+
--soft-green: #122d22;
|
|
593
|
+
--soft-amber: #332a12;
|
|
594
|
+
}
|
|
595
|
+
button { background: #172642; }
|
|
596
|
+
.danger { background: #351c20; }
|
|
597
|
+
.notice { background: #2d2816; color: #f2cc60; }
|
|
598
|
+
}
|
|
599
|
+
@media (max-width: 720px) {
|
|
600
|
+
.toolbar { grid-template-columns: 1fr 1fr; }
|
|
601
|
+
h2.with-action { align-items: flex-start; flex-direction: column; }
|
|
602
|
+
}
|
|
603
|
+
</style>
|
|
604
|
+
</head>
|
|
605
|
+
<body>
|
|
606
|
+
<header>
|
|
607
|
+
<h1>Teste de funcoes html2apk</h1>
|
|
608
|
+
<p>Use botoes manuais, lotes seguros e eventos passivos para testar as funcoes interpretadas do APK. Os resultados aparecem aqui e tambem no console runtime.</p>
|
|
609
|
+
<div class="toolbar" aria-label="Controles do laboratorio">
|
|
610
|
+
<button id="runSafeButton" class="primary" type="button">Rodar testes seguros</button>
|
|
611
|
+
<button id="runPrepareButton" type="button">Preparar dados</button>
|
|
612
|
+
<button id="registerEventsButton" type="button">Registrar eventos</button>
|
|
613
|
+
<button id="clearLogButton" type="button">Limpar resultados</button>
|
|
614
|
+
<input id="filterInput" type="search" placeholder="Filtrar funcao, evento ou categoria">
|
|
615
|
+
</div>
|
|
616
|
+
<div id="stats" class="stats" aria-live="polite"></div>
|
|
617
|
+
</header>
|
|
618
|
+
<main>
|
|
619
|
+
<section aria-label="Resultado ao vivo">
|
|
620
|
+
<div class="output-head">
|
|
621
|
+
<h2>Resultado ao vivo</h2>
|
|
622
|
+
<span class="chip">Novos no topo</span>
|
|
623
|
+
</div>
|
|
624
|
+
<div id="outputFeed" class="output-feed" aria-live="polite"></div>
|
|
625
|
+
</section>
|
|
626
|
+
<section aria-label="Como testar eventos passivos">
|
|
627
|
+
<h2>Eventos que nao dependem de botao</h2>
|
|
628
|
+
<div class="guide">
|
|
629
|
+
<article><strong>USB, fone e volume</strong><p>Conecte/desconecte cabo, fone ou mude o volume fisico. O evento aparece no resultado ao vivo.</p></article>
|
|
630
|
+
<article><strong>Teclado</strong><p>Toque no campo de filtro para abrir o teclado; feche o teclado para testar o evento inverso.</p></article>
|
|
631
|
+
<article><strong>Sensores</strong><p>Sacuda o aparelho, vire a tela para baixo ou aproxime a mao do sensor de proximidade.</p></article>
|
|
632
|
+
<article><strong>Notificacao e share</strong><p>Use os botoes de notificacao/compartilhamento e observe os callbacks registrados automaticamente.</p></article>
|
|
633
|
+
</div>
|
|
634
|
+
</section>
|
|
635
|
+
<div id="groups"></div>
|
|
636
|
+
</main>
|
|
637
|
+
<script>
|
|
638
|
+
(function () {
|
|
639
|
+
var state = {
|
|
640
|
+
scheduledId: null,
|
|
641
|
+
loopId: null,
|
|
642
|
+
watchId: null,
|
|
643
|
+
stopLocationEvent: null,
|
|
644
|
+
lastImage: null,
|
|
645
|
+
lastPhoto: null,
|
|
646
|
+
micRecording: false,
|
|
647
|
+
eventsReady: false,
|
|
648
|
+
eventStops: [],
|
|
649
|
+
outputCount: 0,
|
|
650
|
+
sequenceRunning: false
|
|
651
|
+
};
|
|
652
|
+
var sampleImageBase64 = "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mP8/x8AAwMCAO+/p9sAAAAASUVORK5CYII=";
|
|
653
|
+
|
|
654
|
+
function fn(name) {
|
|
655
|
+
if (typeof window[name] !== "function") {
|
|
656
|
+
throw new Error(name + " nao esta disponivel neste APK.");
|
|
657
|
+
}
|
|
658
|
+
return window[name];
|
|
659
|
+
}
|
|
660
|
+
|
|
661
|
+
function delay(ms) {
|
|
662
|
+
return new Promise(function (resolve) {
|
|
663
|
+
setTimeout(resolve, ms);
|
|
664
|
+
});
|
|
665
|
+
}
|
|
666
|
+
|
|
667
|
+
function safeValue(value) {
|
|
668
|
+
if (value instanceof Error) {
|
|
669
|
+
return {
|
|
670
|
+
name: value.name,
|
|
671
|
+
message: value.message,
|
|
672
|
+
stack: value.stack
|
|
673
|
+
};
|
|
674
|
+
}
|
|
675
|
+
if (typeof value === "undefined") {
|
|
676
|
+
return undefined;
|
|
677
|
+
}
|
|
678
|
+
try {
|
|
679
|
+
return JSON.parse(JSON.stringify(value));
|
|
680
|
+
} catch (error) {
|
|
681
|
+
return String(value);
|
|
682
|
+
}
|
|
683
|
+
}
|
|
684
|
+
|
|
685
|
+
function valueToText(value) {
|
|
686
|
+
var normalized = safeValue(value);
|
|
687
|
+
if (typeof normalized === "undefined") {
|
|
688
|
+
return "";
|
|
689
|
+
}
|
|
690
|
+
if (typeof normalized === "string") {
|
|
691
|
+
return normalized;
|
|
692
|
+
}
|
|
693
|
+
return JSON.stringify(normalized, null, 2);
|
|
694
|
+
}
|
|
695
|
+
|
|
696
|
+
function appendOutput(title, value, kind) {
|
|
697
|
+
var feed = document.getElementById("outputFeed");
|
|
698
|
+
var entry;
|
|
699
|
+
var pre;
|
|
700
|
+
var textValue;
|
|
701
|
+
|
|
702
|
+
if (!feed) {
|
|
703
|
+
return;
|
|
704
|
+
}
|
|
705
|
+
|
|
706
|
+
state.outputCount += 1;
|
|
707
|
+
entry = document.createElement("article");
|
|
708
|
+
entry.className = "log-entry " + (kind === "error" ? "error" : (kind === "ok" ? "ok" : "info"));
|
|
709
|
+
entry.innerHTML = "<strong></strong><time></time>";
|
|
710
|
+
entry.querySelector("strong").textContent = title;
|
|
711
|
+
entry.querySelector("time").textContent = new Date().toLocaleTimeString();
|
|
712
|
+
|
|
713
|
+
textValue = valueToText(value);
|
|
714
|
+
if (textValue) {
|
|
715
|
+
pre = document.createElement("pre");
|
|
716
|
+
pre.textContent = textValue;
|
|
717
|
+
entry.appendChild(pre);
|
|
718
|
+
}
|
|
719
|
+
|
|
720
|
+
feed.prepend(entry);
|
|
721
|
+
while (feed.children.length > 80) {
|
|
722
|
+
feed.lastElementChild.remove();
|
|
723
|
+
}
|
|
724
|
+
updateStats();
|
|
725
|
+
}
|
|
726
|
+
|
|
727
|
+
function log(title, value, kind) {
|
|
728
|
+
var consoleKind = kind === "err" ? "error" : (kind === "ok" ? "ok" : "info");
|
|
729
|
+
var hasValue = value !== "" && typeof value !== "undefined";
|
|
730
|
+
appendOutput(title, hasValue ? value : undefined, consoleKind);
|
|
731
|
+
if (window.Html2ApkRuntimeConsole && typeof window.Html2ApkRuntimeConsole.log === "function") {
|
|
732
|
+
window.Html2ApkRuntimeConsole.log(consoleKind, title, hasValue ? safeValue(value) : undefined);
|
|
733
|
+
return;
|
|
734
|
+
}
|
|
735
|
+
if (consoleKind === "error") {
|
|
736
|
+
console.error(title, hasValue ? value : "");
|
|
737
|
+
} else if (consoleKind === "ok") {
|
|
738
|
+
console.log(title, hasValue ? value : "");
|
|
739
|
+
} else {
|
|
740
|
+
console.info(title, hasValue ? value : "");
|
|
741
|
+
}
|
|
742
|
+
}
|
|
743
|
+
|
|
744
|
+
async function run(id) {
|
|
745
|
+
var test = actions[id];
|
|
746
|
+
var button = document.querySelector("[data-action='" + id + "']");
|
|
747
|
+
var result;
|
|
748
|
+
if (!test) {
|
|
749
|
+
return;
|
|
750
|
+
}
|
|
751
|
+
if (button) {
|
|
752
|
+
button.classList.remove("ok", "fail");
|
|
753
|
+
button.classList.add("running");
|
|
754
|
+
button.disabled = true;
|
|
755
|
+
}
|
|
756
|
+
log("Executando " + test.title, "", "");
|
|
757
|
+
try {
|
|
758
|
+
result = await test.run();
|
|
759
|
+
log("OK: " + test.title, result, "ok");
|
|
760
|
+
if (button) {
|
|
761
|
+
button.classList.add("ok");
|
|
762
|
+
}
|
|
763
|
+
return { ok: true, result: result };
|
|
764
|
+
} catch (error) {
|
|
765
|
+
log("ERRO: " + test.title, error, "err");
|
|
766
|
+
if (button) {
|
|
767
|
+
button.classList.add("fail");
|
|
768
|
+
}
|
|
769
|
+
return { ok: false, error: error };
|
|
770
|
+
} finally {
|
|
771
|
+
if (button) {
|
|
772
|
+
button.classList.remove("running");
|
|
773
|
+
button.disabled = false;
|
|
774
|
+
}
|
|
775
|
+
}
|
|
776
|
+
}
|
|
777
|
+
|
|
778
|
+
async function runSequence(ids, label) {
|
|
779
|
+
var index;
|
|
780
|
+
if (state.sequenceRunning) {
|
|
781
|
+
log("Lote ignorado", { motivo: "Ja existe um lote em execucao." }, "info");
|
|
782
|
+
return;
|
|
783
|
+
}
|
|
784
|
+
state.sequenceRunning = true;
|
|
785
|
+
log("Inicio do lote: " + label, { total: ids.length }, "info");
|
|
786
|
+
try {
|
|
787
|
+
for (index = 0; index < ids.length; index += 1) {
|
|
788
|
+
await run(ids[index]);
|
|
789
|
+
await delay(160);
|
|
790
|
+
}
|
|
791
|
+
log("Fim do lote: " + label, { total: ids.length }, "ok");
|
|
792
|
+
} finally {
|
|
793
|
+
state.sequenceRunning = false;
|
|
794
|
+
}
|
|
795
|
+
}
|
|
796
|
+
|
|
797
|
+
function registerEvents() {
|
|
798
|
+
var registered = [];
|
|
799
|
+
var missing = [];
|
|
800
|
+
var failed = [];
|
|
801
|
+
|
|
802
|
+
function remember(stop) {
|
|
803
|
+
if (typeof stop === "function") {
|
|
804
|
+
state.eventStops.push(stop);
|
|
805
|
+
}
|
|
806
|
+
}
|
|
807
|
+
|
|
808
|
+
function listen(name, title) {
|
|
809
|
+
if (typeof window[name] !== "function") {
|
|
810
|
+
missing.push(name);
|
|
811
|
+
return;
|
|
812
|
+
}
|
|
813
|
+
try {
|
|
814
|
+
remember(window[name](function (event) {
|
|
815
|
+
log(title, event, "ok");
|
|
816
|
+
}));
|
|
817
|
+
registered.push(name);
|
|
818
|
+
} catch (error) {
|
|
819
|
+
failed.push({ name: name, message: error.message });
|
|
820
|
+
log("Falha ao registrar " + name, error, "err");
|
|
821
|
+
}
|
|
822
|
+
}
|
|
823
|
+
|
|
824
|
+
function event(type, title) {
|
|
825
|
+
if (typeof window.aoEvento !== "function") {
|
|
826
|
+
missing.push("aoEvento:" + type);
|
|
827
|
+
return;
|
|
828
|
+
}
|
|
829
|
+
try {
|
|
830
|
+
remember(window.aoEvento(type, function (detail) {
|
|
831
|
+
log(title, detail, "ok");
|
|
832
|
+
}));
|
|
833
|
+
registered.push("aoEvento:" + type);
|
|
834
|
+
} catch (error) {
|
|
835
|
+
failed.push({ name: "aoEvento:" + type, message: error.message });
|
|
836
|
+
log("Falha ao registrar evento " + type, error, "err");
|
|
837
|
+
}
|
|
838
|
+
}
|
|
839
|
+
|
|
840
|
+
if (state.eventsReady) {
|
|
841
|
+
return { registered: true, already: true };
|
|
842
|
+
}
|
|
843
|
+
state.eventsReady = true;
|
|
844
|
+
event("app:background", "evento app:background");
|
|
845
|
+
event("app:voltou", "evento app:voltou");
|
|
846
|
+
event("botao:voltar", "evento botao:voltar");
|
|
847
|
+
event("rede:mudou", "evento rede:mudou");
|
|
848
|
+
event("bateria:mudou", "evento bateria:mudou");
|
|
849
|
+
[
|
|
850
|
+
["aoMinimizar", "app minimizado"],
|
|
851
|
+
["aoVoltarParaApp", "app voltou"],
|
|
852
|
+
["aoAbrirLink", "link recebido"],
|
|
853
|
+
["aoReceberCompartilhamento", "compartilhamento recebido"],
|
|
854
|
+
["aoMudarRede", "rede mudou"],
|
|
855
|
+
["aoMudarBateria", "bateria mudou"],
|
|
856
|
+
["aoConectarUSB", "usb conectado"],
|
|
857
|
+
["aoDesconectarUSB", "usb desconectado"],
|
|
858
|
+
["aoConectarFone", "fone conectado"],
|
|
859
|
+
["aoDesconectarFone", "fone desconectado"],
|
|
860
|
+
["aoMudarVolume", "volume mudou"],
|
|
861
|
+
["aoAbrirTeclado", "teclado abriu"],
|
|
862
|
+
["aoFecharTeclado", "teclado fechou"],
|
|
863
|
+
["aoMudarOrientacao", "orientacao mudou"],
|
|
864
|
+
["aoSacudirCelular", "celular sacudido"],
|
|
865
|
+
["aoVirarCelularParaBaixo", "tela para baixo"],
|
|
866
|
+
["aoAproximarObjeto", "objeto proximo"],
|
|
867
|
+
["aoTirarPrint", "print detectado"],
|
|
868
|
+
["aoNFC", "nfc recebido"],
|
|
869
|
+
["aoReceberNotificacao", "notificacao recebida"],
|
|
870
|
+
["aoClicarNotificacao", "notificacao clicada"],
|
|
871
|
+
["aoConectarBT", "bluetooth conectado"],
|
|
872
|
+
["aoReceberDadosBT", "dados bluetooth"],
|
|
873
|
+
["aoDarErroBT", "erro bluetooth"],
|
|
874
|
+
["aoConectarWiFi", "wifi conectado"],
|
|
875
|
+
["aoReceberDadosWiFi", "dados wifi"],
|
|
876
|
+
["aoDarErroWiFi", "erro wifi"]
|
|
877
|
+
].forEach(function (item) {
|
|
878
|
+
listen(item[0], item[1]);
|
|
879
|
+
});
|
|
880
|
+
return { registered: registered.length, missing: missing, failed: failed };
|
|
881
|
+
}
|
|
882
|
+
|
|
883
|
+
var actions = {
|
|
884
|
+
toast: { title: "toast()", run: function () { return fn("toast")("Mensagem do app de teste"); } },
|
|
885
|
+
vibrar: { title: "vibrar()", run: function () { return fn("vibrar")(250); } },
|
|
886
|
+
aguardar: { title: "aguardar(1000)", run: function () { return fn("aguardar")(1000); } },
|
|
887
|
+
copiarTexto: { title: "copiarTexto()", run: function () { return fn("copiarTexto")("Texto copiado pelo html2apk"); } },
|
|
888
|
+
lerTextoCopiado: { title: "lerTextoCopiado()", run: function () { return fn("lerTextoCopiado")(); } },
|
|
889
|
+
compartilharTexto: { title: "compartilharTexto()", run: function () { return fn("compartilharTexto")("Compartilhado pelo app de teste html2apk"); } },
|
|
890
|
+
compartilhar: { title: "compartilhar()", run: function () { return fn("compartilhar")({ texto: "Teste html2apk", url: "https://example.com" }); } },
|
|
891
|
+
compartilharApp: { title: "share_me()", run: function () { return fn("share_me")({ titulo: "Compartilhar app de teste" }); } },
|
|
892
|
+
receberCompartilhamento: { title: "aoReceberCompartilhamento()", run: function () { if (state.stopShareEvent) { state.stopShareEvent(); } state.stopShareEvent = fn("aoReceberCompartilhamento")(function (event) { log("compartilhamento recebido", event, "ok"); }); return { listening: true }; } },
|
|
893
|
+
compartilhamentoInicial: { title: "obterCompartilhamentoInicial()", run: function () { return fn("obterCompartilhamentoInicial")(); } },
|
|
894
|
+
iniciarBt: { title: "aoConectarBT()", run: function () { if (state.stopBtConnect) { state.stopBtConnect(); } state.stopBtConnect = fn("aoConectarBT")(function (event) { state.bluetoothConnected = true; log("bluetooth conectado", event, "ok"); }); if (state.stopBtData) { state.stopBtData(); } state.stopBtData = fn("aoReceberDadosBT")(function (data) { log("dados bluetooth", data, "ok"); }); if (state.stopBtError) { state.stopBtError(); } state.stopBtError = fn("aoDarErroBT")(function (error) { log("erro bluetooth", error, "err"); }); return { listening: true }; } },
|
|
895
|
+
procurarBt: { title: "procurarBT()", run: async function () { var devices = await fn("procurarBT")({ timeoutMs: 10000 }); state.bluetoothDevices = devices || []; state.bluetoothDeviceId = state.bluetoothDevices[0] && state.bluetoothDevices[0].id; return devices; } },
|
|
896
|
+
conectarBt: { title: "conectarBT()", run: async function () { if (!state.bluetoothDeviceId) { var devices = await fn("procurarBT")({ timeoutMs: 10000 }); state.bluetoothDevices = devices || []; state.bluetoothDeviceId = state.bluetoothDevices[0] && state.bluetoothDevices[0].id; } if (!state.bluetoothDeviceId) { return { connected: false, message: "Nenhum dispositivo encontrado." }; } return fn("conectarBT")(state.bluetoothDeviceId); } },
|
|
897
|
+
enviarBt: { title: "enviarBT()", run: function () { return fn("enviarBT")({ origem: "laboratorio-html2apk", mensagem: "Ola via Bluetooth", quando: Date.now() }); } },
|
|
898
|
+
iniciarWifi: { title: "aoConectarWiFi()", run: function () { if (state.stopWifiConnect) { state.stopWifiConnect(); } state.stopWifiConnect = fn("aoConectarWiFi")(function (event) { state.wifiConnected = true; log("wifi conectado", event, "ok"); }); if (state.stopWifiData) { state.stopWifiData(); } state.stopWifiData = fn("aoReceberDadosWiFi")(function (data) { log("dados wifi", data, "ok"); }); if (state.stopWifiError) { state.stopWifiError(); } state.stopWifiError = fn("aoDarErroWiFi")(function (error) { log("erro wifi", error, "err"); }); return { listening: true }; } },
|
|
899
|
+
procurarWifi: { title: "procurarWiFi()", run: async function () { var devices = await fn("procurarWiFi")({ timeoutMs: 10000 }); state.wifiDevices = devices || []; state.wifiDeviceId = state.wifiDevices[0] && state.wifiDevices[0].id; return devices; } },
|
|
900
|
+
conectarWifi: { title: "conectarWiFi()", run: async function () { if (!state.wifiDeviceId) { var devices = await fn("procurarWiFi")({ timeoutMs: 10000 }); state.wifiDevices = devices || []; state.wifiDeviceId = state.wifiDevices[0] && state.wifiDevices[0].id; } if (!state.wifiDeviceId) { return { connected: false, message: "Nenhum dispositivo Wi-Fi encontrado." }; } return fn("conectarWiFi")(state.wifiDeviceId); } },
|
|
901
|
+
enviarWifi: { title: "enviarWiFi()", run: function () { return fn("enviarWiFi")({ origem: "laboratorio-html2apk", mensagem: "Ola via Wi-Fi", quando: Date.now() }); } },
|
|
902
|
+
|
|
903
|
+
notificar: { title: "notificar()", run: function () { return fn("notificar")({ titulo: "html2apk", texto: "Notificacao imediata", aoClicar: { funcao: "toast", argumentos: ["Notificacao clicada"] } }); } },
|
|
904
|
+
agendarNotificacao: { title: "agendarNotificacao()", run: async function () { var result = await fn("agendarNotificacao")({ titulo: "html2apk", texto: "Agendada para 10 segundos", quando: Date.now() + 10000 }); state.scheduledId = result && result.id; return result; } },
|
|
905
|
+
agendarNotificacoes: { title: "agendarNotificacoes()", run: function () { return fn("agendarNotificacoes")([{ titulo: "Lista 1", texto: "Primeira notificacao", quando: Date.now() + 12000 }, { titulo: "Lista 2", texto: "Segunda notificacao", quando: Date.now() + 18000 }]); } },
|
|
906
|
+
cancelarNotificacao: { title: "cancelarNotificacao()", run: function () { return fn("cancelarNotificacao")(state.scheduledId || 0); } },
|
|
907
|
+
agendarLoopNotificacoes: { title: "agendarLoopNotificacoes()", run: async function () { var result = await fn("agendarLoopNotificacoes")({ aCada: "30s", notificacoes: [{ titulo: "Loop 1", texto: "Primeiro item" }, { titulo: "Loop 2", texto: "Segundo item" }] }); state.loopId = result && result.id; return result; } },
|
|
908
|
+
cancelarLoopNotificacoes: { title: "cancelarLoopNotificacoes()", run: function () { return fn("cancelarLoopNotificacoes")(state.loopId || 0); } },
|
|
909
|
+
pushInfo: { title: "Push OneSignal", run: function () { if (typeof window.solicitarPermissaoPush !== "function") { return { available: false, message: "Configure OneSignal App ID no app real para testar push remoto." }; } return window.solicitarPermissaoPush(); } },
|
|
910
|
+
|
|
911
|
+
statusPermissoes: { title: "statusPermissoes()", run: function () { return fn("statusPermissoes")(["CAMERA", "RECORD_AUDIO", "ACCESS_FINE_LOCATION", "ACCESS_COARSE_LOCATION", "POST_NOTIFICATIONS", "SET_WALLPAPER", "BLUETOOTH_SCAN", "BLUETOOTH_CONNECT", "NFC", "SYSTEM_ALERT_WINDOW"]); } },
|
|
912
|
+
permissaoNotificacao: { title: "solicitarPermissaoNotificacoes()", run: function () { return fn("solicitarPermissaoNotificacoes")(); } },
|
|
913
|
+
statusPermissaoNotificacoes: { title: "statusPermissaoNotificacoes()", run: function () { return fn("statusPermissaoNotificacoes")(); } },
|
|
914
|
+
permissaoCamera: { title: "solicitarPermissaoCamera()", run: function () { return fn("solicitarPermissaoCamera")(); } },
|
|
915
|
+
permissaoMicrofone: { title: "solicitarPermissaoMicrofone()", run: function () { return fn("solicitarPermissaoMicrofone")(); } },
|
|
916
|
+
statusMicrofone: { title: "statusMicrofone()", run: function () { return fn("statusMicrofone")(); } },
|
|
917
|
+
alarmeExato: { title: "podeAgendarNotificacaoExata()", run: function () { return fn("podeAgendarNotificacaoExata")(); } },
|
|
918
|
+
abrirAlarmeExato: { title: "abrirConfiguracaoAlarmeExato()", run: function () { return fn("abrirConfiguracaoAlarmeExato")(); } },
|
|
919
|
+
statusSobreposicao: { title: "statusPermissaoSobreposicao()", run: function () { return fn("statusPermissaoSobreposicao")(); } },
|
|
920
|
+
solicitarSobreposicao: { title: "solicitarPermissaoSobreposicao()", run: function () { return fn("solicitarPermissaoSobreposicao")(); } },
|
|
921
|
+
abrirSobreposicao: { title: "abrirConfiguracaoSobreposicao()", run: function () { return fn("abrirConfiguracaoSobreposicao")(); } },
|
|
922
|
+
|
|
923
|
+
fullscreenOn: { title: "fullscreen(true)", run: function () { return fn("fullscreen")(true); } },
|
|
924
|
+
fullscreenOff: { title: "fullscreen(false)", run: function () { return fn("fullscreen")(false); } },
|
|
925
|
+
telaAcordadaOn: { title: "manterTelaAcordada(true)", run: function () { return fn("manterTelaAcordada")(true); } },
|
|
926
|
+
telaAcordadaOff: { title: "manterTelaAcordada(false)", run: function () { return fn("manterTelaAcordada")(false); } },
|
|
927
|
+
brilhoTela: { title: "brilhoTela()", run: function () { return fn("brilhoTela")(0.72); } },
|
|
928
|
+
corTema: { title: "definirCorTema()", run: function () { return fn("definirCorTema")({ statusBarColor: "#126fff", navigationBarColor: "#10141b", darkIcons: false }); } },
|
|
929
|
+
corBarrasSistema: { title: "definirCorBarrasSistema()", run: function () { return fn("definirCorBarrasSistema")({ statusBarColor: "#18864b", navigationBarColor: "#10141b", darkIcons: false }); } },
|
|
930
|
+
lanternaOn: { title: "lanterna(true)", run: function () { return fn("lanterna")(true); } },
|
|
931
|
+
lanternaOff: { title: "lanterna(false)", run: function () { return fn("lanterna")(false); } },
|
|
932
|
+
lanterna: { title: "alternarLanterna()", run: function () { return fn("alternarLanterna")(); } },
|
|
933
|
+
statusLanterna: { title: "statusLanterna()", run: function () { return fn("statusLanterna")(); } },
|
|
934
|
+
capturarTela: { title: "capturarTela()", run: function () { return fn("capturarTela")({ formato: "png" }); } },
|
|
935
|
+
tirarPrint: { title: "tirarPrint()", run: function () { return fn("tirarPrint")({ formato: "png" }); } },
|
|
936
|
+
volumeAtual: { title: "volumeAtual()", run: function () { return fn("volumeAtual")(); } },
|
|
937
|
+
definirVolume: { title: "definirVolume('midia', 0.5)", run: function () { return fn("definirVolume")("midia", 0.5, { mostrarUI: true }); } },
|
|
938
|
+
aumentarVolume: { title: "aumentarVolume()", run: function () { return fn("aumentarVolume")("midia", 1, { mostrarUI: true }); } },
|
|
939
|
+
diminuirVolume: { title: "diminuirVolume()", run: function () { return fn("diminuirVolume")("midia", 1, { mostrarUI: true }); } },
|
|
940
|
+
iniciarIconeFlutuante: { title: "iniciarIconeFlutuante()", run: function () { return fn("iniciarIconeFlutuante")({ opacidade: 0.85 }); } },
|
|
941
|
+
configurarIconeFlutuante: { title: "configurarIconeFlutuante()", run: function () { return fn("configurarIconeFlutuante")({ opacidade: 0.65, tamanho: 58 }); } },
|
|
942
|
+
definirOpacidadeIconeFlutuante: { title: "definirOpacidadeIconeFlutuante()", run: function () { return fn("definirOpacidadeIconeFlutuante")(0.55); } },
|
|
943
|
+
pararIconeFlutuante: { title: "pararIconeFlutuante()", run: function () { return fn("pararIconeFlutuante")(); } },
|
|
944
|
+
minimizarApp: { title: "minimizarApp()", run: function () { return fn("minimizarApp")(); } },
|
|
945
|
+
fecharApp: { title: "fecharApp()", run: function () { return fn("fecharApp")(); } },
|
|
946
|
+
|
|
947
|
+
tirarFoto: { title: "tirarFoto()", run: async function () { var result = await fn("tirarFoto")({ base64: true }); state.lastPhoto = result; return result; } },
|
|
948
|
+
capturarVideo: { title: "capturarVideo()", run: function () { return fn("capturarVideo")({ duracaoSegundos: 5 }); } },
|
|
949
|
+
escanearQRCode: { title: "escanearQRCode()", run: function () { return fn("escanearQRCode")(); } },
|
|
950
|
+
ouvirMic: { title: "ouvirMic()", run: async function () { state.micRecording = true; return fn("ouvirMic")(); } },
|
|
951
|
+
pararMic: { title: "pararMic()", run: async function () { state.micRecording = false; return fn("pararMic")(); } },
|
|
952
|
+
falar: { title: "falar()", run: function () { return fn("falar")("Ola, eu sou o html2apk", { idioma: "pt-BR", velocidade: 1 }); } },
|
|
953
|
+
pararFala: { title: "pararFala()", run: function () { return fn("pararFala")(); } },
|
|
954
|
+
ouvir: { title: "ouvir()", run: function () { return fn("ouvir")({ idioma: "pt-BR", prompt: "Fale uma frase para testar" }); } },
|
|
955
|
+
ocr: { title: "ocr(imagem)", run: async function () { if (!state.lastImage) { state.lastImage = await fn("escolherImagem")(); } if (!state.lastImage || !state.lastImage.uri) { return { canceled: true }; } return fn("ocr")(state.lastImage); } },
|
|
956
|
+
|
|
957
|
+
escolherImagem: { title: "escolherImagem()", run: async function () { var result = await fn("escolherImagem")(); state.lastImage = result; return result; } },
|
|
958
|
+
escolherImagens: { title: "escolherImagens()", run: function () { return fn("escolherImagens")({ multiplas: true }); } },
|
|
959
|
+
escolherArquivo: { title: "escolherArquivo()", run: function () { return fn("escolherArquivo")({ tipos: ["text/*", "application/json", "image/*"] }); } },
|
|
960
|
+
escolherArquivos: { title: "escolherArquivos()", run: function () { return fn("escolherArquivos")({ multiplo: true }); } },
|
|
961
|
+
escolherVideo: { title: "escolherVideo()", run: function () { return fn("escolherVideo")(); } },
|
|
962
|
+
escolherPasta: { title: "escolherPasta()", run: function () { return fn("escolherPasta")(); } },
|
|
963
|
+
salvarArquivoPicker: { title: "salvarArquivo({ nome })", run: function () { return fn("salvarArquivo")({ nome: "teste-html2apk.txt", mimeType: "text/plain", conteudo: "Arquivo salvo pelo teste html2apk" }); } },
|
|
964
|
+
salvarArquivoCrud: { title: "salvarArquivo('lab.json')", run: function () { return fn("salvarArquivo")("lab.json", { criadoEm: Date.now(), origem: "teste-funcoes" }); } },
|
|
965
|
+
lerArquivo: { title: "lerArquivo()", run: function () { return fn("lerArquivo")("lab.json"); } },
|
|
966
|
+
lerArquivoCompleto: { title: "lerArquivoCompleto()", run: function () { return fn("lerArquivoCompleto")("lab.json"); } },
|
|
967
|
+
listarArquivos: { title: "listarArquivos()", run: function () { return fn("listarArquivos")(); } },
|
|
968
|
+
infoArquivo: { title: "infoArquivo()", run: function () { return fn("infoArquivo")("lab.json"); } },
|
|
969
|
+
arquivoExiste: { title: "arquivoExiste()", run: function () { return fn("arquivoExiste")("lab.json"); } },
|
|
970
|
+
abrirArquivo: { title: "abrirArquivo()", run: function () { return fn("abrirArquivo")("lab.json"); } },
|
|
971
|
+
compartilharArquivo: { title: "compartilharArquivo()", run: function () { return fn("compartilharArquivo")("lab.json"); } },
|
|
972
|
+
baixarArquivo: { title: "baixarArquivo()", run: function () { return fn("baixarArquivo")("https://example.com/", "example.html"); } },
|
|
973
|
+
baixarBase64: { title: "baixarBase64()", run: function () { return fn("baixarBase64")("pixel-download.png", sampleImageBase64, { mimeType: "image/png" }); } },
|
|
974
|
+
baixarArquivoLocal: { title: "baixarArquivoLocal()", run: async function () { var file = await fn("escolherArquivo")(); if (!file) { return { canceled: true }; } return fn("baixarArquivoLocal")(file, "copia-" + (file.name || file.nome || "arquivo")); } },
|
|
975
|
+
excluirArquivo: { title: "excluirArquivo()", run: function () { return fn("excluirArquivo")("lab.json"); } },
|
|
976
|
+
|
|
977
|
+
abrirNoApp: { title: "abrirNoApp()", run: function () { return fn("abrirNoApp")("#teste-funcoes"); } },
|
|
978
|
+
abrirForaDoApp: { title: "abrirForaDoApp()", run: function () { return fn("abrirForaDoApp")("https://example.com"); } },
|
|
979
|
+
abrirUrl: { title: "abrirUrl()", run: function () { return fn("abrirUrl")("https://example.com"); } },
|
|
980
|
+
abrirUrlExterno: { title: "abrirUrlExterno()", run: function () { return fn("abrirUrlExterno")("https://example.com"); } },
|
|
981
|
+
discar: { title: "discar()", run: function () { return fn("discar")("11999999999"); } },
|
|
982
|
+
abrirMapa: { title: "abrirMapa()", run: function () { return fn("abrirMapa")("Sao Paulo"); } },
|
|
983
|
+
abrirWhatsapp: { title: "abrirWhatsapp()", run: function () { return fn("abrirWhatsapp")("5511999999999", "Teste html2apk"); } },
|
|
984
|
+
|
|
985
|
+
infoDispositivo: { title: "infoDispositivo()", run: function () { return fn("infoDispositivo")(); } },
|
|
986
|
+
infoRede: { title: "infoRede()", run: function () { return fn("infoRede")(); } },
|
|
987
|
+
infoBateria: { title: "infoBateria()", run: function () { return fn("infoBateria")(); } },
|
|
988
|
+
infoMemoria: { title: "infoMemoria()", run: function () { return fn("infoMemoria")(); } },
|
|
989
|
+
infoArmazenamento: { title: "infoArmazenamento()", run: function () { return fn("infoArmazenamento")(); } },
|
|
990
|
+
infoDesempenho: { title: "infoDesempenho()", run: function () { return fn("infoDesempenho")(); } },
|
|
991
|
+
appsAbertos: { title: "appsAbertos()", run: function () { return fn("appsAbertos")(); } },
|
|
992
|
+
infoAppsAbertos: { title: "infoAppsAbertos()", run: function () { return fn("infoAppsAbertos")(); } },
|
|
993
|
+
|
|
994
|
+
obterLocalizacao: { title: "obterLocalizacao()", run: function () { return fn("obterLocalizacao")({ altaPrecisao: true, timeoutMs: 10000 }); } },
|
|
995
|
+
acompanharLocalizacao: { title: "acompanharLocalizacao()", run: async function () { var result = await fn("acompanharLocalizacao")({ intervaloMs: 5000 }); state.watchId = result && result.watchId; return result; } },
|
|
996
|
+
pararLocalizacao: { title: "pararLocalizacao()", run: function () { return fn("pararLocalizacao")(state.watchId || ""); } },
|
|
997
|
+
aoMudarLocalizacao: { title: "aoMudarLocalizacao()", run: function () { if (state.stopLocationEvent) { state.stopLocationEvent(); } state.stopLocationEvent = fn("aoMudarLocalizacao")(function (event) { log("localizacao:mudou", event, "ok"); }); return { listening: true }; } },
|
|
998
|
+
autenticarBiometria: { title: "autenticarBiometria()", run: function () { return fn("autenticarBiometria")({ titulo: "Teste html2apk", descricao: "Confirme para testar a bridge" }); } },
|
|
999
|
+
salvarSeguro: { title: "salvarSeguro()", run: function () { return fn("salvarSeguro")("tokenTeste", { token: "abc123", criadoEm: Date.now() }); } },
|
|
1000
|
+
lerSeguro: { title: "lerSeguro()", run: function () { return fn("lerSeguro")("tokenTeste"); } },
|
|
1001
|
+
lerSeguroCompleto: { title: "lerSeguroCompleto()", run: function () { return fn("lerSeguroCompleto")("tokenTeste"); } },
|
|
1002
|
+
listarSeguro: { title: "listarSeguro()", run: function () { return fn("listarSeguro")(); } },
|
|
1003
|
+
removerSeguro: { title: "removerSeguro()", run: function () { return fn("removerSeguro")("tokenTeste"); } },
|
|
1004
|
+
limparSeguro: { title: "limparSeguro()", run: function () { return fn("limparSeguro")(); } },
|
|
1005
|
+
|
|
1006
|
+
infoPapelParede: { title: "infoPapelParede()", run: function () { return fn("infoPapelParede")(); } },
|
|
1007
|
+
definirPapelParede: { title: "definirPapelParede()", run: function () { return fn("definirPapelParede")({ base64: sampleImageBase64, mimeType: "image/png", alvo: "inicio" }); } },
|
|
1008
|
+
abrirConfigPapel: { title: "abrirConfiguracaoPapelParede()", run: function () { return fn("abrirConfiguracaoPapelParede")(); } },
|
|
1009
|
+
definirImagemEscolhida: { title: "imagem escolhida -> papel de parede", run: async function () { if (!state.lastImage) { state.lastImage = await fn("escolherImagem")(); } if (!state.lastImage || !state.lastImage.uri) { return { canceled: true }; } return fn("definirPapelParede")({ uri: state.lastImage.uri, alvo: "inicio", mimeType: state.lastImage.mimeType || "image/*" }); } },
|
|
1010
|
+
|
|
1011
|
+
registrarEventos: { title: "registrar eventos", run: function () { return registerEvents(); } },
|
|
1012
|
+
obterNotificacaoInicial: { title: "obterNotificacaoInicial()", run: function () { return fn("obterNotificacaoInicial")(); } },
|
|
1013
|
+
obterLinkInicial: { title: "obterLinkInicial()", run: function () { return fn("obterLinkInicial")(); } }
|
|
1014
|
+
};
|
|
1015
|
+
|
|
1016
|
+
var groups = [
|
|
1017
|
+
{ title: "Feedback e compartilhamento", ids: ["toast", "vibrar", "aguardar", "copiarTexto", "lerTextoCopiado", "compartilharTexto", "compartilhar", "compartilharApp", "receberCompartilhamento", "compartilhamentoInicial"] },
|
|
1018
|
+
{ title: "Bluetooth", ids: ["iniciarBt", "procurarBt", "conectarBt", "enviarBt"] },
|
|
1019
|
+
{ title: "Wi-Fi local", ids: ["iniciarWifi", "procurarWifi", "conectarWifi", "enviarWifi"] },
|
|
1020
|
+
{ title: "Notificacoes", ids: ["notificar", "agendarNotificacao", "agendarNotificacoes", "cancelarNotificacao", "agendarLoopNotificacoes", "cancelarLoopNotificacoes", "pushInfo"] },
|
|
1021
|
+
{ title: "Permissoes e configuracoes", ids: ["statusPermissoes", "permissaoNotificacao", "statusPermissaoNotificacoes", "permissaoCamera", "permissaoMicrofone", "statusMicrofone", "alarmeExato", "abrirAlarmeExato", "statusSobreposicao", "solicitarSobreposicao", "abrirSobreposicao"] },
|
|
1022
|
+
{ title: "Tela e hardware", ids: ["fullscreenOn", "fullscreenOff", "telaAcordadaOn", "telaAcordadaOff", "brilhoTela", "corTema", "corBarrasSistema", "lanternaOn", "lanternaOff", "lanterna", "statusLanterna", "capturarTela", "tirarPrint", "volumeAtual", "definirVolume", "aumentarVolume", "diminuirVolume", "iniciarIconeFlutuante", "configurarIconeFlutuante", "definirOpacidadeIconeFlutuante", "pararIconeFlutuante", "minimizarApp", "fecharApp"] },
|
|
1023
|
+
{ title: "Camera, QR Code e microfone", ids: ["tirarFoto", "capturarVideo", "escanearQRCode", "ouvirMic", "pararMic"] },
|
|
1024
|
+
{ title: "Texto e voz", ids: ["ocr", "falar", "pararFala", "ouvir"] },
|
|
1025
|
+
{ title: "Arquivos e midia", ids: ["escolherImagem", "escolherImagens", "escolherArquivo", "escolherArquivos", "escolherVideo", "escolherPasta", "salvarArquivoPicker", "salvarArquivoCrud", "lerArquivo", "lerArquivoCompleto", "listarArquivos", "infoArquivo", "arquivoExiste", "abrirArquivo", "compartilharArquivo", "baixarArquivo", "baixarBase64", "baixarArquivoLocal", "excluirArquivo"] },
|
|
1026
|
+
{ title: "Abrir apps externos", ids: ["abrirNoApp", "abrirForaDoApp", "abrirUrl", "abrirUrlExterno", "discar", "abrirMapa", "abrirWhatsapp"] },
|
|
1027
|
+
{ title: "Diagnostico", ids: ["infoDispositivo", "infoRede", "infoBateria", "infoMemoria", "infoArmazenamento", "infoDesempenho", "appsAbertos", "infoAppsAbertos"] },
|
|
1028
|
+
{ title: "Localizacao e seguranca", ids: ["obterLocalizacao", "acompanharLocalizacao", "pararLocalizacao", "aoMudarLocalizacao", "autenticarBiometria", "salvarSeguro", "lerSeguro", "lerSeguroCompleto", "listarSeguro", "removerSeguro", "limparSeguro"] },
|
|
1029
|
+
{ title: "Papel de parede", ids: ["infoPapelParede", "definirPapelParede", "abrirConfigPapel", "definirImagemEscolhida"] },
|
|
1030
|
+
{ title: "Eventos", ids: ["registrarEventos", "obterNotificacaoInicial", "obterLinkInicial"] }
|
|
1031
|
+
];
|
|
1032
|
+
|
|
1033
|
+
var safeActionIds = [
|
|
1034
|
+
"registrarEventos", "statusPermissoes", "statusPermissaoNotificacoes", "statusMicrofone",
|
|
1035
|
+
"alarmeExato", "statusSobreposicao", "statusLanterna", "volumeAtual",
|
|
1036
|
+
"infoDispositivo", "infoRede", "infoBateria", "infoMemoria", "infoArmazenamento",
|
|
1037
|
+
"infoDesempenho", "appsAbertos", "infoAppsAbertos", "listarArquivos", "arquivoExiste",
|
|
1038
|
+
"compartilhamentoInicial", "obterNotificacaoInicial", "obterLinkInicial", "infoPapelParede",
|
|
1039
|
+
"aguardar", "lerTextoCopiado"
|
|
1040
|
+
];
|
|
1041
|
+
var setupActionIds = [
|
|
1042
|
+
"salvarArquivoCrud", "lerArquivo", "lerArquivoCompleto", "infoArquivo", "salvarSeguro",
|
|
1043
|
+
"lerSeguro", "lerSeguroCompleto", "listarSeguro", "baixarBase64"
|
|
1044
|
+
];
|
|
1045
|
+
var listenerActionIds = [
|
|
1046
|
+
"registrarEventos", "receberCompartilhamento", "iniciarBt", "iniciarWifi", "aoMudarLocalizacao"
|
|
1047
|
+
];
|
|
1048
|
+
var externalActionIds = [
|
|
1049
|
+
"compartilharTexto", "compartilhar", "compartilharApp", "abrirForaDoApp", "abrirUrl",
|
|
1050
|
+
"abrirUrlExterno", "discar", "abrirMapa", "abrirWhatsapp", "abrirAlarmeExato",
|
|
1051
|
+
"abrirSobreposicao", "abrirConfigPapel", "escolherImagem", "escolherImagens",
|
|
1052
|
+
"escolherArquivo", "escolherArquivos", "escolherVideo", "escolherPasta",
|
|
1053
|
+
"salvarArquivoPicker", "baixarArquivoLocal", "tirarFoto", "capturarVideo",
|
|
1054
|
+
"escanearQRCode", "ouvir", "autenticarBiometria"
|
|
1055
|
+
];
|
|
1056
|
+
var dangerActionIds = ["fecharApp", "minimizarApp", "limparSeguro", "excluirArquivo", "pararIconeFlutuante"];
|
|
1057
|
+
var initialSmokeIds = ["registrarEventos", "statusPermissoes", "infoDispositivo", "infoRede", "infoBateria", "volumeAtual"];
|
|
1058
|
+
|
|
1059
|
+
function toSet(ids) {
|
|
1060
|
+
return ids.reduce(function (map, id) {
|
|
1061
|
+
map[id] = true;
|
|
1062
|
+
return map;
|
|
1063
|
+
}, {});
|
|
1064
|
+
}
|
|
1065
|
+
|
|
1066
|
+
var safeActionSet = toSet(safeActionIds);
|
|
1067
|
+
var setupActionSet = toSet(setupActionIds);
|
|
1068
|
+
var listenerActionSet = toSet(listenerActionIds);
|
|
1069
|
+
var externalActionSet = toSet(externalActionIds);
|
|
1070
|
+
var dangerActionSet = toSet(dangerActionIds);
|
|
1071
|
+
|
|
1072
|
+
function actionMode(id) {
|
|
1073
|
+
if (listenerActionSet[id]) {
|
|
1074
|
+
return "listener";
|
|
1075
|
+
}
|
|
1076
|
+
if (safeActionSet[id]) {
|
|
1077
|
+
return "safe";
|
|
1078
|
+
}
|
|
1079
|
+
if (setupActionSet[id]) {
|
|
1080
|
+
return "setup";
|
|
1081
|
+
}
|
|
1082
|
+
if (externalActionSet[id]) {
|
|
1083
|
+
return "external";
|
|
1084
|
+
}
|
|
1085
|
+
return "manual";
|
|
1086
|
+
}
|
|
1087
|
+
|
|
1088
|
+
function actionHint(id) {
|
|
1089
|
+
var mode = actionMode(id);
|
|
1090
|
+
if (mode === "listener") {
|
|
1091
|
+
return "Registra e fica escutando";
|
|
1092
|
+
}
|
|
1093
|
+
if (mode === "safe") {
|
|
1094
|
+
return "Pode rodar no lote seguro";
|
|
1095
|
+
}
|
|
1096
|
+
if (mode === "setup") {
|
|
1097
|
+
return "Prepara ou consulta dados de teste";
|
|
1098
|
+
}
|
|
1099
|
+
if (mode === "external") {
|
|
1100
|
+
return "Abre permissao, seletor ou app externo";
|
|
1101
|
+
}
|
|
1102
|
+
if (dangerActionSet[id]) {
|
|
1103
|
+
return "Afeta estado do app";
|
|
1104
|
+
}
|
|
1105
|
+
return "Toque para executar";
|
|
1106
|
+
}
|
|
1107
|
+
|
|
1108
|
+
function groupRunnableIds(group) {
|
|
1109
|
+
return group.ids.filter(function (id) {
|
|
1110
|
+
return safeActionSet[id] || setupActionSet[id];
|
|
1111
|
+
});
|
|
1112
|
+
}
|
|
1113
|
+
|
|
1114
|
+
function updateStats() {
|
|
1115
|
+
var stats = document.getElementById("stats");
|
|
1116
|
+
var total = Object.keys(actions).length;
|
|
1117
|
+
if (!stats) {
|
|
1118
|
+
return;
|
|
1119
|
+
}
|
|
1120
|
+
stats.innerHTML = [
|
|
1121
|
+
"<span class='chip'>" + total + " testes no laboratorio</span>",
|
|
1122
|
+
"<span class='chip'>" + safeActionIds.length + " seguros em lote</span>",
|
|
1123
|
+
"<span class='chip'>" + listenerActionIds.length + " grupos de escuta</span>",
|
|
1124
|
+
"<span class='chip'>" + state.outputCount + " resultados</span>"
|
|
1125
|
+
].join("");
|
|
1126
|
+
}
|
|
1127
|
+
|
|
1128
|
+
function applyFilter() {
|
|
1129
|
+
var filter = document.getElementById("filterInput");
|
|
1130
|
+
var term = filter ? filter.value.trim().toLowerCase() : "";
|
|
1131
|
+
document.querySelectorAll("#groups section").forEach(function (section) {
|
|
1132
|
+
var visible = 0;
|
|
1133
|
+
var groupTitle = section.querySelector("h2").textContent.toLowerCase();
|
|
1134
|
+
section.querySelectorAll("[data-action]").forEach(function (button) {
|
|
1135
|
+
var text = button.textContent.toLowerCase();
|
|
1136
|
+
var match = !term || text.indexOf(term) !== -1 || groupTitle.indexOf(term) !== -1;
|
|
1137
|
+
button.hidden = !match;
|
|
1138
|
+
if (match) {
|
|
1139
|
+
visible += 1;
|
|
1140
|
+
}
|
|
1141
|
+
});
|
|
1142
|
+
section.hidden = visible === 0;
|
|
1143
|
+
});
|
|
1144
|
+
}
|
|
1145
|
+
|
|
1146
|
+
function render() {
|
|
1147
|
+
var root = document.getElementById("groups");
|
|
1148
|
+
var notice = "<p class='notice'>Os lotes seguros evitam camera, seletores, apps externos e acoes que fecham/minimizam. Para eventos passivos, deixe o app aberto e provoque o evento fisico no aparelho.</p>";
|
|
1149
|
+
root.innerHTML = groups.map(function (group) {
|
|
1150
|
+
var runnable = groupRunnableIds(group);
|
|
1151
|
+
var runButton = runnable.length
|
|
1152
|
+
? "<button type='button' data-run-group='" + runnable.join(",") + "'>Rodar seguros (" + runnable.length + ")</button>"
|
|
1153
|
+
: "";
|
|
1154
|
+
return "<section><h2 class='with-action'><span>" + group.title + "</span>" + runButton + "</h2><div class='grid'>" + group.ids.map(function (id) {
|
|
1155
|
+
var item = actions[id];
|
|
1156
|
+
var mode = actionMode(id);
|
|
1157
|
+
var classes = [mode];
|
|
1158
|
+
if (dangerActionSet[id]) {
|
|
1159
|
+
classes.push("danger");
|
|
1160
|
+
}
|
|
1161
|
+
return "<button type='button' class='" + classes.join(" ") + "' data-action='" + id + "'><span>" + item.title + "</span><small>" + actionHint(id) + "</small></button>";
|
|
1162
|
+
}).join("") + "</div></section>";
|
|
1163
|
+
}).join("") + notice;
|
|
1164
|
+
updateStats();
|
|
1165
|
+
applyFilter();
|
|
1166
|
+
}
|
|
1167
|
+
|
|
1168
|
+
document.addEventListener("click", function (event) {
|
|
1169
|
+
var groupButton = event.target.closest("[data-run-group]");
|
|
1170
|
+
var button = event.target.closest("[data-action]");
|
|
1171
|
+
if (groupButton) {
|
|
1172
|
+
runSequence(groupButton.getAttribute("data-run-group").split(","), "grupo");
|
|
1173
|
+
return;
|
|
1174
|
+
}
|
|
1175
|
+
if (button) {
|
|
1176
|
+
run(button.getAttribute("data-action"));
|
|
1177
|
+
}
|
|
1178
|
+
});
|
|
1179
|
+
|
|
1180
|
+
document.addEventListener("input", function (event) {
|
|
1181
|
+
if (event.target && event.target.id === "filterInput") {
|
|
1182
|
+
applyFilter();
|
|
1183
|
+
}
|
|
1184
|
+
});
|
|
1185
|
+
|
|
1186
|
+
document.getElementById("runSafeButton").addEventListener("click", function () {
|
|
1187
|
+
runSequence(safeActionIds, "testes seguros");
|
|
1188
|
+
});
|
|
1189
|
+
|
|
1190
|
+
document.getElementById("runPrepareButton").addEventListener("click", function () {
|
|
1191
|
+
runSequence(setupActionIds, "preparar dados");
|
|
1192
|
+
});
|
|
1193
|
+
|
|
1194
|
+
document.getElementById("registerEventsButton").addEventListener("click", function () {
|
|
1195
|
+
run("registrarEventos");
|
|
1196
|
+
});
|
|
1197
|
+
|
|
1198
|
+
document.getElementById("clearLogButton").addEventListener("click", function () {
|
|
1199
|
+
var feed = document.getElementById("outputFeed");
|
|
1200
|
+
if (feed) {
|
|
1201
|
+
feed.innerHTML = "";
|
|
1202
|
+
}
|
|
1203
|
+
state.outputCount = 0;
|
|
1204
|
+
updateStats();
|
|
1205
|
+
});
|
|
1206
|
+
|
|
1207
|
+
document.addEventListener("deviceready", function () {
|
|
1208
|
+
log("deviceready", { ready: true }, "ok");
|
|
1209
|
+
runSequence(initialSmokeIds, "diagnostico inicial");
|
|
1210
|
+
}, false);
|
|
1211
|
+
|
|
1212
|
+
render();
|
|
1213
|
+
}());
|
|
1214
|
+
</script>
|
|
1215
|
+
</body>
|
|
1216
|
+
</html>`;
|
|
1217
|
+
}
|
|
1218
|
+
|
|
1219
|
+
async function createNativeFunctionLabProject() {
|
|
1220
|
+
const projectRoot = await fs.mkdtemp(path.join(app.getPath("temp"), "html2apk-function-lab-"));
|
|
1221
|
+
const config = {
|
|
1222
|
+
appName: "html2apk Function Lab",
|
|
1223
|
+
packageId: "dev.html2apk.functionlab",
|
|
1224
|
+
version: "1.0.0",
|
|
1225
|
+
buildFormat: "apk",
|
|
1226
|
+
mode: "standalone",
|
|
1227
|
+
orientation: "vertical",
|
|
1228
|
+
minSdkVersion: 24,
|
|
1229
|
+
themeMode: "fixed",
|
|
1230
|
+
themeColor: "#126fff",
|
|
1231
|
+
showRuntimeLogs: true,
|
|
1232
|
+
permissions: [
|
|
1233
|
+
"INTERNET",
|
|
1234
|
+
"POST_NOTIFICATIONS",
|
|
1235
|
+
"VIBRATE",
|
|
1236
|
+
"CAMERA",
|
|
1237
|
+
"RECORD_AUDIO",
|
|
1238
|
+
"ACCESS_FINE_LOCATION",
|
|
1239
|
+
"ACCESS_COARSE_LOCATION",
|
|
1240
|
+
"SET_WALLPAPER",
|
|
1241
|
+
"BLUETOOTH_SCAN",
|
|
1242
|
+
"BLUETOOTH_CONNECT",
|
|
1243
|
+
"NFC",
|
|
1244
|
+
"MODIFY_AUDIO_SETTINGS",
|
|
1245
|
+
"SYSTEM_ALERT_WINDOW",
|
|
1246
|
+
"ACCESS_NETWORK_STATE",
|
|
1247
|
+
"ACCESS_WIFI_STATE",
|
|
1248
|
+
"CHANGE_WIFI_MULTICAST_STATE"
|
|
1249
|
+
]
|
|
1250
|
+
};
|
|
1251
|
+
|
|
1252
|
+
await fs.writeFile(path.join(projectRoot, "index.html"), nativeFunctionLabHtml(), "utf8");
|
|
1253
|
+
await fs.writeFile(path.join(projectRoot, "app.json"), JSON.stringify(config, null, 2), "utf8");
|
|
1254
|
+
return projectRoot;
|
|
1255
|
+
}
|
|
1256
|
+
|
|
398
1257
|
function quoteForCmd(value) {
|
|
399
1258
|
const text = String(value);
|
|
400
1259
|
if (!text.length) {
|
|
@@ -837,6 +1696,49 @@ ipcMain.handle("build:run-usb-debug", async (event, options) => {
|
|
|
837
1696
|
}
|
|
838
1697
|
});
|
|
839
1698
|
|
|
1699
|
+
ipcMain.handle("codes:run-function-lab", async (event) => {
|
|
1700
|
+
const sendLog = (line, kind = "raw") => {
|
|
1701
|
+
event.sender.send("build:log", {
|
|
1702
|
+
line,
|
|
1703
|
+
kind,
|
|
1704
|
+
time: new Date().toISOString()
|
|
1705
|
+
});
|
|
1706
|
+
};
|
|
1707
|
+
let projectRoot = null;
|
|
1708
|
+
|
|
1709
|
+
try {
|
|
1710
|
+
sendLog("Creating html2apk interpreted functions test app.", "system");
|
|
1711
|
+
projectRoot = await createNativeFunctionLabProject();
|
|
1712
|
+
sendLog(`Function test project: ${projectRoot}`, "system");
|
|
1713
|
+
sendLog("USB required: connect an Android phone with USB debugging authorized.", "system");
|
|
1714
|
+
const result = await runDebugUsb({
|
|
1715
|
+
projectRoot,
|
|
1716
|
+
debug: false,
|
|
1717
|
+
release: false,
|
|
1718
|
+
showRuntimeLogs: true,
|
|
1719
|
+
onLog: (line) => sendLog(line)
|
|
1720
|
+
});
|
|
1721
|
+
sendLog(`Function test app opened on device: ${result.device?.id || "Android device"}`, "success");
|
|
1722
|
+
return {
|
|
1723
|
+
ok: true,
|
|
1724
|
+
result: {
|
|
1725
|
+
...result,
|
|
1726
|
+
projectRoot,
|
|
1727
|
+
distPath: path.join(projectRoot, "dist")
|
|
1728
|
+
}
|
|
1729
|
+
};
|
|
1730
|
+
} catch (error) {
|
|
1731
|
+
sendLog(error.message, "error");
|
|
1732
|
+
return {
|
|
1733
|
+
ok: false,
|
|
1734
|
+
message: error.message,
|
|
1735
|
+
logs: error.logs || [],
|
|
1736
|
+
buildDir: error.buildDir || null,
|
|
1737
|
+
projectRoot
|
|
1738
|
+
};
|
|
1739
|
+
}
|
|
1740
|
+
});
|
|
1741
|
+
|
|
840
1742
|
ipcMain.handle("shell:open-path", async (_event, targetPath) => {
|
|
841
1743
|
if (!targetPath) {
|
|
842
1744
|
return false;
|