@capgo/capacitor-zebra-datawedge 8.2.3 → 8.2.5

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.
@@ -4,9 +4,11 @@ import android.content.BroadcastReceiver;
4
4
  import android.content.Context;
5
5
  import android.content.Intent;
6
6
  import android.content.IntentFilter;
7
+ import android.os.Build;
7
8
  import android.os.Bundle;
8
9
  import android.os.Handler;
9
10
  import android.os.Looper;
11
+ import android.os.Process;
10
12
  import androidx.core.content.ContextCompat;
11
13
  import com.getcapacitor.JSArray;
12
14
  import com.getcapacitor.JSObject;
@@ -15,6 +17,7 @@ import com.getcapacitor.PluginCall;
15
17
  import com.getcapacitor.PluginMethod;
16
18
  import com.getcapacitor.annotation.CapacitorPlugin;
17
19
  import java.util.ArrayList;
20
+ import java.util.Arrays;
18
21
  import java.util.Collections;
19
22
  import java.util.LinkedHashSet;
20
23
  import java.util.List;
@@ -32,15 +35,58 @@ public class ZebraDataWedgePlugin extends Plugin {
32
35
  private static final long REQUEST_TIMEOUT_MS = 8000L;
33
36
  private static final long SCAN_TIMEOUT_MS = 15000L;
34
37
 
38
+ // Correlation and parsing share the same keys, including documented alternatives and existing fallbacks.
39
+ private static final String[] ACTIVE_PROFILE_RESULTS = { ZebraDataWedge.RESULT_GET_ACTIVE_PROFILE, "PROFILE_NAME" };
40
+ private static final String[] CONFIG_RESULTS = {
41
+ ZebraDataWedge.RESULT_GET_CONFIG,
42
+ "com.symbol.datawedge.api.GET_CONFIG_RESULT",
43
+ ZebraDataWedge.RESULT_GET_CONFIG_LEGACY
44
+ };
45
+ private static final String[] DATAWEDGE_STATUS_RESULTS = { ZebraDataWedge.RESULT_GET_DATAWEDGE_STATUS, "DATAWEDGE_STATUS" };
46
+ private static final String[] PROFILES_LIST_RESULTS = { ZebraDataWedge.RESULT_GET_PROFILES_LIST };
47
+ private static final String[] SCANNER_STATUS_RESULTS = { ZebraDataWedge.RESULT_GET_SCANNER_STATUS, "SCANNER_STATUS" };
48
+ private static final String[] VERSION_INFO_RESULTS = { ZebraDataWedge.RESULT_GET_VERSION_INFO, "GET_VERSION_INFO_RESULT" };
49
+ private static final String[] DISABLED_APPS_RESULTS = { ZebraDataWedge.RESULT_GET_DISABLED_APP_LIST };
50
+ private static final String[] IGNORE_DISABLED_RESULTS = {
51
+ ZebraDataWedge.RESULT_GET_IGNORE_DISABLED_PROFILES,
52
+ "IGNORE_DISABLED_PROFILES"
53
+ };
54
+ private static final String[] TRIGGER_RESULTS = { ZebraDataWedge.RESULT_ENUMERATE_TRIGGERS, "ENUMERATE_TRIGGERS" };
55
+ private static final String[] SCANNER_ENUMERATION_RESULTS = {
56
+ ZebraDataWedge.RESULT_ENUMERATE_SCANNERS,
57
+ ZebraDataWedge.RESULT_ENUMERATED_SCANNER_LIST
58
+ };
59
+
35
60
  private final Handler handler = new Handler(Looper.getMainLooper());
36
61
  private final Map<String, PendingRequest> pendingRequests = new ConcurrentHashMap<>();
37
62
  private final Map<String, ScanRequest> pendingScans = new ConcurrentHashMap<>();
38
63
  private final Set<String> manualIntentActions = Collections.synchronizedSet(new LinkedHashSet<>());
39
64
  private final Map<String, Set<String>> profileScanIntentActions = new ConcurrentHashMap<>();
40
65
  private final Set<String> registeredIntentActions = Collections.synchronizedSet(new LinkedHashSet<>());
66
+ private final DataWedgeDiagnostics diagnostics = new DataWedgeDiagnostics();
41
67
  private BroadcastReceiver receiver;
42
68
  private boolean receiverRegistered = false;
43
69
 
70
+ @PluginMethod
71
+ public void configureDiagnostics(PluginCall call) {
72
+ Integer capacity = call.getInt("maxEntries");
73
+ if ((call.getData().has("maxEntries") && capacity == null) || (capacity != null && (capacity < 1 || capacity > 1000))) {
74
+ call.reject("maxEntries must be between 1 and 1000.", "PARAMETER_INVALID");
75
+ return;
76
+ }
77
+ diagnostics.configure(
78
+ Boolean.TRUE.equals(call.getBoolean("enabled", false)),
79
+ capacity,
80
+ Boolean.TRUE.equals(call.getBoolean("reset", false))
81
+ );
82
+ call.resolve();
83
+ }
84
+
85
+ @PluginMethod
86
+ public void getDiagnostics(PluginCall call) {
87
+ call.resolve(diagnostics.snapshot(getContext()));
88
+ }
89
+
44
90
  @Override
45
91
  public void load() {
46
92
  ensureReceiver();
@@ -55,7 +101,9 @@ public class ZebraDataWedgePlugin extends Plugin {
55
101
  } catch (IllegalArgumentException ignored) {}
56
102
  receiverRegistered = false;
57
103
  }
58
- for (PendingRequest request : pendingRequests.values()) {
104
+ for (Map.Entry<String, PendingRequest> entry : pendingRequests.entrySet()) {
105
+ PendingRequest request = entry.getValue();
106
+ diagnostics.record(entry.getKey(), "CANCELLED");
59
107
  handler.removeCallbacks(request.timeoutRunnable);
60
108
  request.call.reject("Timed out waiting for DataWedge response.");
61
109
  }
@@ -530,7 +578,13 @@ public class ZebraDataWedgePlugin extends Plugin {
530
578
  receiver = new BroadcastReceiver() {
531
579
  @Override
532
580
  public void onReceive(Context context, Intent intent) {
533
- handleIntent(intent);
581
+ int sentFromUid = Process.INVALID_UID;
582
+ String sentFromPackage = null;
583
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
584
+ sentFromUid = getSentFromUid();
585
+ sentFromPackage = getSentFromPackage();
586
+ }
587
+ handleIntent(context, intent, sentFromUid, sentFromPackage);
534
588
  }
535
589
  };
536
590
  }
@@ -615,20 +669,37 @@ public class ZebraDataWedgePlugin extends Plugin {
615
669
  receiverRegistered = true;
616
670
  }
617
671
 
618
- private void handleIntent(Intent intent) {
672
+ void deliverResultIntentForTest(Context context, Intent intent, int sentFromUid, String sentFromPackage) {
673
+ handleIntent(context, intent, sentFromUid, sentFromPackage);
674
+ }
675
+
676
+ private void handleIntent(Context context, Intent intent, int sentFromUid, String sentFromPackage) {
619
677
  String action = intent.getAction();
620
678
  if (action == null) {
621
679
  return;
622
680
  }
623
681
  if (ZebraDataWedge.RESULT_ACTION.equals(action)) {
624
682
  String commandId = intent.getStringExtra(ZebraDataWedge.EXTRA_COMMAND_IDENTIFIER);
625
- if (commandId != null) {
626
- PendingRequest request = pendingRequests.remove(commandId);
627
- if (request != null) {
628
- handler.removeCallbacks(request.timeoutRunnable);
629
- resolvePendingRequest(request, intent);
683
+ PendingRequest request = commandId == null ? null : pendingRequests.get(commandId);
684
+ if (request == null && commandId == null) {
685
+ if (!allowIdentifierFreeQueryCorrelation(context, sentFromUid, sentFromPackage)) {
630
686
  return;
631
687
  }
688
+ for (Map.Entry<String, PendingRequest> entry : pendingRequests.entrySet()) {
689
+ if (entry.getValue().hasQueryPayload(intent)) {
690
+ if (request != null) return; // Never guess between concurrent query owners.
691
+ commandId = entry.getKey();
692
+ request = entry.getValue();
693
+ }
694
+ }
695
+ }
696
+ if (request != null) {
697
+ boolean failure = ZebraDataWedge.RESULT_FAILURE.equalsIgnoreCase(intent.getStringExtra(ZebraDataWedge.EXTRA_RESULT));
698
+ if (!failure && request.resultExtras.length > 0 && !request.hasQueryPayload(intent)) return;
699
+ if (!pendingRequests.remove(commandId, request)) return;
700
+ handler.removeCallbacks(request.timeoutRunnable);
701
+ resolvePendingRequest(request, intent, commandId);
702
+ return;
632
703
  }
633
704
  }
634
705
 
@@ -643,24 +714,98 @@ public class ZebraDataWedgePlugin extends Plugin {
643
714
  }
644
715
  }
645
716
 
717
+ /**
718
+ * Identifier-free typed query replies use payload correlation, not sender authentication.
719
+ * When the platform exposes sender identity (API 34+), require the DataWedge package.
720
+ * When identity is unavailable (API 24-33, or API 34+ without shared identity), keep
721
+ * documented identifier-free compatibility and rely on ambiguity guards below. Residual
722
+ * spoofing risk for that mode is tracked in https://github.com/Cap-go/capacitor-zebra-datawedge/issues/25
723
+ */
724
+ private boolean allowIdentifierFreeQueryCorrelation(Context context, int sentFromUid, String sentFromPackage) {
725
+ if (isTrustedDataWedgeSender(context, sentFromUid, sentFromPackage)) {
726
+ return true;
727
+ }
728
+ return isSenderIdentityUnavailable(sentFromUid, sentFromPackage);
729
+ }
730
+
731
+ private boolean isSenderIdentityUnavailable(int sentFromUid, String sentFromPackage) {
732
+ if (Build.VERSION.SDK_INT < Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
733
+ return true;
734
+ }
735
+ return (sentFromUid == Process.INVALID_UID || sentFromUid == -1) && sentFromPackage == null;
736
+ }
737
+
738
+ private boolean isTrustedDataWedgeSender(Context context, int sentFromUid, String sentFromPackage) {
739
+ if (ZebraDataWedge.DATAWEDGE_PACKAGE.equals(sentFromPackage)) {
740
+ return true;
741
+ }
742
+ if (sentFromUid == Process.INVALID_UID || sentFromUid == -1) {
743
+ return false;
744
+ }
745
+ String[] packages = context.getPackageManager().getPackagesForUid(sentFromUid);
746
+ if (packages == null) {
747
+ return false;
748
+ }
749
+ for (String packageName : packages) {
750
+ if (ZebraDataWedge.DATAWEDGE_PACKAGE.equals(packageName)) {
751
+ return true;
752
+ }
753
+ }
754
+ return false;
755
+ }
756
+
757
+ /** Select one delivery mode consistently for every outgoing DataWedge API intent. */
758
+ private void dispatchDataWedgeIntent(Intent intent) {
759
+ // Zebra documents an ordinary-broadcast delivery delay starting on Android 14.
760
+ // Delivery completion is not a DataWedge result: callers still await RESULT_ACTION.
761
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
762
+ getContext().sendOrderedBroadcast(intent, null);
763
+ } else {
764
+ getContext().sendBroadcast(intent);
765
+ }
766
+ }
767
+
646
768
  private void sendCommand(PluginCall call, Intent intent, String prefix, ResponseParser parser) {
647
769
  String commandId = ZebraDataWedge.newCommandIdentifier(prefix);
770
+ diagnostics.record(commandId, "SENT");
648
771
  intent.putExtra(ZebraDataWedge.EXTRA_SEND_RESULT, ZebraDataWedge.VALUE_LAST_RESULT);
649
772
  intent.putExtra(ZebraDataWedge.EXTRA_COMMAND_IDENTIFIER, commandId);
650
773
  Runnable timeout = () -> {
651
774
  PendingRequest removed = pendingRequests.remove(commandId);
652
775
  if (removed != null) {
653
- removed.call.reject("Timed out waiting for DataWedge response.");
776
+ diagnostics.record(commandId, "TIMEOUT");
777
+ removed.call.reject("Timed out waiting for DataWedge response.", "DATAWEDGE_TIMEOUT");
654
778
  }
655
779
  };
656
- pendingRequests.put(commandId, new PendingRequest(call, parser, timeout));
780
+ pendingRequests.put(commandId, new PendingRequest(call, parser, timeout, queryResultExtras(intent)));
657
781
  handler.postDelayed(timeout, REQUEST_TIMEOUT_MS);
658
- sendBroadcast(intent, call);
782
+ try {
783
+ dispatchDataWedgeIntent(intent);
784
+ } catch (Exception exception) {
785
+ pendingRequests.remove(commandId);
786
+ handler.removeCallbacks(timeout);
787
+ diagnostics.record(commandId, "TRANSPORT_ERROR");
788
+ call.reject("Failed to communicate with Zebra DataWedge.", "DATAWEDGE_TRANSPORT", exception);
789
+ }
790
+ }
791
+
792
+ private String[] queryResultExtras(Intent intent) {
793
+ if (intent.hasExtra(ZebraDataWedge.CMD_GET_ACTIVE_PROFILE)) return ACTIVE_PROFILE_RESULTS;
794
+ if (intent.hasExtra(ZebraDataWedge.CMD_GET_CONFIG)) return CONFIG_RESULTS;
795
+ if (intent.hasExtra(ZebraDataWedge.CMD_GET_DATAWEDGE_STATUS)) return DATAWEDGE_STATUS_RESULTS;
796
+ if (intent.hasExtra(ZebraDataWedge.CMD_GET_PROFILES_LIST)) return PROFILES_LIST_RESULTS;
797
+ if (intent.hasExtra(ZebraDataWedge.CMD_GET_SCANNER_STATUS)) return SCANNER_STATUS_RESULTS;
798
+ if (intent.hasExtra(ZebraDataWedge.CMD_GET_VERSION_INFO)) return VERSION_INFO_RESULTS;
799
+ if (intent.hasExtra(ZebraDataWedge.CMD_GET_DISABLED_APP_LIST)) return DISABLED_APPS_RESULTS;
800
+ if (intent.hasExtra(ZebraDataWedge.CMD_GET_IGNORE_DISABLED_PROFILES)) return IGNORE_DISABLED_RESULTS;
801
+ if (intent.hasExtra(ZebraDataWedge.CMD_ENUMERATE_TRIGGERS)) return TRIGGER_RESULTS;
802
+ if (intent.hasExtra(ZebraDataWedge.CMD_ENUMERATE_SCANNERS)) return SCANNER_ENUMERATION_RESULTS;
803
+ return new String[0];
659
804
  }
660
805
 
661
806
  private void dispatchNotification(Intent intent, PluginCall call) {
662
807
  try {
663
- getContext().sendBroadcast(intent);
808
+ dispatchDataWedgeIntent(intent);
664
809
  } catch (Exception exception) {
665
810
  call.reject("DataWedge notification transport failed.", "DATAWEDGE_TRANSPORT", exception);
666
811
  return;
@@ -670,19 +815,23 @@ public class ZebraDataWedgePlugin extends Plugin {
670
815
 
671
816
  private void sendBroadcast(Intent intent, PluginCall call) {
672
817
  try {
673
- getContext().sendBroadcast(intent);
818
+ dispatchDataWedgeIntent(intent);
674
819
  } catch (Exception exception) {
675
820
  call.reject("Failed to communicate with Zebra DataWedge.", exception);
676
821
  }
677
822
  }
678
823
 
679
- private void resolvePendingRequest(PendingRequest request, Intent intent) {
824
+ private void resolvePendingRequest(PendingRequest request, Intent intent, String commandId) {
680
825
  try {
681
826
  rejectIfFailure(intent);
682
- request.call.resolve(request.parser.parse(intent));
827
+ JSObject result = request.parser.parse(intent);
828
+ diagnostics.record(commandId, "SUCCESS");
829
+ request.call.resolve(result);
683
830
  } catch (ZebraDataWedgeException exception) {
831
+ diagnostics.record(commandId, "FAILURE");
684
832
  request.call.reject(exception.getMessage(), exception.getCode());
685
833
  } catch (Exception exception) {
834
+ diagnostics.record(commandId, "INVALID_RESPONSE");
686
835
  request.call.reject(exception.getMessage(), exception);
687
836
  }
688
837
  }
@@ -736,7 +885,7 @@ public class ZebraDataWedgePlugin extends Plugin {
736
885
  }
737
886
 
738
887
  private JSObject parseProfilesList(Intent intent) {
739
- String[] profiles = firstStringArray(intent, ZebraDataWedge.RESULT_GET_PROFILES_LIST);
888
+ String[] profiles = firstStringArray(intent, PROFILES_LIST_RESULTS);
740
889
  JSObject ret = new JSObject();
741
890
  ret.put("profiles", ZebraDataWedge.stringArrayToJSArray(profiles));
742
891
  return ret;
@@ -744,19 +893,19 @@ public class ZebraDataWedgePlugin extends Plugin {
744
893
 
745
894
  private JSObject parseActiveProfile(Intent intent) {
746
895
  JSObject ret = new JSObject();
747
- ret.put("profileName", firstString(intent, ZebraDataWedge.RESULT_GET_ACTIVE_PROFILE, "PROFILE_NAME"));
896
+ ret.put("profileName", firstString(intent, ACTIVE_PROFILE_RESULTS));
748
897
  return ret;
749
898
  }
750
899
 
751
900
  private JSObject parseDataWedgeStatus(Intent intent) {
752
- String rawStatus = firstString(intent, ZebraDataWedge.RESULT_GET_DATAWEDGE_STATUS, "DATAWEDGE_STATUS");
901
+ String rawStatus = firstString(intent, DATAWEDGE_STATUS_RESULTS);
753
902
  JSObject ret = new JSObject();
754
903
  ret.put("isEnabled", rawStatus != null && ("enabled".equalsIgnoreCase(rawStatus) || Boolean.parseBoolean(rawStatus)));
755
904
  return ret;
756
905
  }
757
906
 
758
907
  private JSObject parseIgnoreDisabledProfiles(Intent intent) {
759
- String rawValue = firstString(intent, ZebraDataWedge.RESULT_GET_IGNORE_DISABLED_PROFILES, "IGNORE_DISABLED_PROFILES");
908
+ String rawValue = firstString(intent, IGNORE_DISABLED_RESULTS);
760
909
  JSObject ret = new JSObject();
761
910
  ret.put("enabled", rawValue != null && ("true".equalsIgnoreCase(rawValue) || "enabled".equalsIgnoreCase(rawValue)));
762
911
  return ret;
@@ -764,12 +913,12 @@ public class ZebraDataWedgePlugin extends Plugin {
764
913
 
765
914
  private JSObject parseScannerStatus(Intent intent) {
766
915
  JSObject ret = new JSObject();
767
- ret.put("status", firstString(intent, ZebraDataWedge.RESULT_GET_SCANNER_STATUS, "SCANNER_STATUS"));
916
+ ret.put("status", firstString(intent, SCANNER_STATUS_RESULTS));
768
917
  return ret;
769
918
  }
770
919
 
771
920
  private JSObject parseTriggers(Intent intent) {
772
- String[] triggers = firstStringArray(intent, ZebraDataWedge.RESULT_ENUMERATE_TRIGGERS, "ENUMERATE_TRIGGERS");
921
+ String[] triggers = firstStringArray(intent, TRIGGER_RESULTS);
773
922
  JSObject ret = new JSObject();
774
923
  ret.put("triggers", ZebraDataWedge.stringArrayToJSArray(triggers));
775
924
  return ret;
@@ -777,12 +926,12 @@ public class ZebraDataWedgePlugin extends Plugin {
777
926
 
778
927
  private JSObject parseDisabledAppList(Intent intent) {
779
928
  JSObject ret = new JSObject();
780
- ret.put("appList", parseAppListResult(extractBundleList(intent, ZebraDataWedge.RESULT_GET_DISABLED_APP_LIST)));
929
+ ret.put("appList", parseAppListResult(extractBundleList(intent, DISABLED_APPS_RESULTS)));
781
930
  return ret;
782
931
  }
783
932
 
784
933
  private JSObject parseVersionInfo(Intent intent) {
785
- Bundle versionInfo = firstBundle(intent, ZebraDataWedge.RESULT_GET_VERSION_INFO, "GET_VERSION_INFO_RESULT");
934
+ Bundle versionInfo = firstBundle(intent, VERSION_INFO_RESULTS);
786
935
  JSObject ret = new JSObject();
787
936
  if (versionInfo == null) {
788
937
  return ret;
@@ -799,7 +948,7 @@ public class ZebraDataWedgePlugin extends Plugin {
799
948
  }
800
949
 
801
950
  private JSObject parseConfig(Intent intent) {
802
- Bundle config = firstBundle(intent, ZebraDataWedge.RESULT_GET_CONFIG, ZebraDataWedge.RESULT_GET_CONFIG_LEGACY);
951
+ Bundle config = firstBundle(intent, CONFIG_RESULTS);
803
952
  JSObject ret = new JSObject();
804
953
  if (config == null) {
805
954
  return ret;
@@ -1051,12 +1200,42 @@ public class ZebraDataWedgePlugin extends Plugin {
1051
1200
  final PluginCall call;
1052
1201
  final ResponseParser parser;
1053
1202
  final Runnable timeoutRunnable;
1203
+ final String[] resultExtras;
1054
1204
 
1055
- PendingRequest(PluginCall call, ResponseParser parser, Runnable timeoutRunnable) {
1205
+ PendingRequest(PluginCall call, ResponseParser parser, Runnable timeoutRunnable, String[] resultExtras) {
1056
1206
  this.call = call;
1057
1207
  this.parser = parser;
1208
+ this.resultExtras = resultExtras;
1058
1209
  this.timeoutRunnable = timeoutRunnable;
1059
1210
  }
1211
+
1212
+ boolean hasQueryPayload(Intent intent) {
1213
+ Bundle extras = intent.getExtras();
1214
+ if (extras == null) return false;
1215
+ for (String key : resultExtras) {
1216
+ Object value = extras.get(key);
1217
+ if (hasExpectedPayloadType(key, value)) return true;
1218
+ }
1219
+ return false;
1220
+ }
1221
+
1222
+ /** Validate the outer wire type; empty containers remain valid query results. */
1223
+ private boolean hasExpectedPayloadType(String key, Object value) {
1224
+ if (Arrays.equals(resultExtras, VERSION_INFO_RESULTS) || Arrays.equals(resultExtras, CONFIG_RESULTS)) {
1225
+ return value instanceof Bundle;
1226
+ }
1227
+ if (
1228
+ Arrays.equals(resultExtras, PROFILES_LIST_RESULTS) ||
1229
+ Arrays.equals(resultExtras, TRIGGER_RESULTS) ||
1230
+ ZebraDataWedge.RESULT_ENUMERATED_SCANNER_LIST.equals(key)
1231
+ ) {
1232
+ return value instanceof String[];
1233
+ }
1234
+ if (Arrays.equals(resultExtras, DISABLED_APPS_RESULTS) || Arrays.equals(resultExtras, SCANNER_ENUMERATION_RESULTS)) {
1235
+ return value instanceof ArrayList<?> || value instanceof android.os.Parcelable[];
1236
+ }
1237
+ return value instanceof String;
1238
+ }
1060
1239
  }
1061
1240
 
1062
1241
  private static class ScanRequest {
package/dist/docs.json CHANGED
@@ -5,6 +5,36 @@
5
5
  "docs": "",
6
6
  "tags": [],
7
7
  "methods": [
8
+ {
9
+ "name": "configureDiagnostics",
10
+ "signature": "(options: DiagnosticsOptions) => Promise<void>",
11
+ "parameters": [
12
+ {
13
+ "name": "options",
14
+ "docs": "",
15
+ "type": "DiagnosticsOptions"
16
+ }
17
+ ],
18
+ "returns": "Promise<void>",
19
+ "tags": [],
20
+ "docs": "Configure opt-in native command metadata tracing. Never enables DataWedge or scanner input.",
21
+ "complexTypes": [
22
+ "DiagnosticsOptions"
23
+ ],
24
+ "slug": "configurediagnostics"
25
+ },
26
+ {
27
+ "name": "getDiagnostics",
28
+ "signature": "() => Promise<DataWedgeDiagnosticsSnapshot>",
29
+ "parameters": [],
30
+ "returns": "Promise<DataWedgeDiagnosticsSnapshot>",
31
+ "tags": [],
32
+ "docs": "Return a read-only native environment and trace snapshot. Does not send any DataWedge commands.\nBarcode values, intent bodies and arbitrary exception text are excluded. The application decides\nwhich device information to include when sharing this snapshot. Android only.",
33
+ "complexTypes": [
34
+ "DataWedgeDiagnosticsSnapshot"
35
+ ],
36
+ "slug": "getdiagnostics"
37
+ },
8
38
  {
9
39
  "name": "cloneProfile",
10
40
  "signature": "(options: CloneProfileOptions) => Promise<void>",
@@ -221,7 +251,7 @@
221
251
  "parameters": [],
222
252
  "returns": "Promise<{ scanners: ZebraDeviceScanner[]; }>",
223
253
  "tags": [],
224
- "docs": "",
254
+ "docs": "Android only. DataWedge may omit `COMMAND_IDENTIFIER` on query replies. The plugin accepts\nidentifier-free replies only when the payload matches exactly one pending call that expects the\nsame result payload shape. Avoid overlapping pending calls that share that shape. When sender\nidentity is unavailable (Android API 24 to 33, or API 34+ when the platform withholds it),\nmatching identifier-free replies are accepted for compatibility. If a call times out, a delayed\nidentifier-free reply can still match a later sequential call that expects the same shape and\nresolve it with stale data. This default may change in the next Capacitor major version; see\nhttps://github.com/Cap-go/capacitor-zebra-datawedge/issues/25/.",
225
255
  "complexTypes": [
226
256
  "ZebraDeviceScanner"
227
257
  ],
@@ -233,7 +263,7 @@
233
263
  "parameters": [],
234
264
  "returns": "Promise<{ profileName: string; }>",
235
265
  "tags": [],
236
- "docs": "",
266
+ "docs": "Android only. DataWedge may omit `COMMAND_IDENTIFIER` on query replies. The plugin accepts\nidentifier-free replies only when the payload matches exactly one pending call that expects the\nsame result payload shape. Avoid overlapping pending calls that share that shape. When sender\nidentity is unavailable (Android API 24 to 33, or API 34+ when the platform withholds it),\nmatching identifier-free replies are accepted for compatibility. If a call times out, a delayed\nidentifier-free reply can still match a later sequential call that expects the same shape and\nresolve it with stale data. This default may change in the next Capacitor major version; see\nhttps://github.com/Cap-go/capacitor-zebra-datawedge/issues/25/.",
237
267
  "complexTypes": [],
238
268
  "slug": "getactiveprofile"
239
269
  },
@@ -249,7 +279,7 @@
249
279
  ],
250
280
  "returns": "Promise<{ appList: DataWedgeAppConfig[]; }>",
251
281
  "tags": [],
252
- "docs": "",
282
+ "docs": "Android only. DataWedge may omit `COMMAND_IDENTIFIER` on query replies. The plugin accepts\nidentifier-free replies only when the payload matches exactly one pending call that expects the\nsame result payload shape. Avoid overlapping pending calls that share that shape. For example,\n`getAssociatedApps()` and `getConfig()` both send `CMD_GET_CONFIG` and expect `CONFIG_RESULTS`, so one\npending call to each overlaps. When sender identity is unavailable (Android API 24 to 33, or API\n34+ when the platform withholds it), matching identifier-free replies are accepted for\ncompatibility. If a call times out, a delayed identifier-free reply can still match a later\nsequential call that expects the same shape and resolve it with stale data. This default may\nchange in the next Capacitor major version; see\nhttps://github.com/Cap-go/capacitor-zebra-datawedge/issues/25/.",
253
283
  "complexTypes": [
254
284
  "DataWedgeAppConfig"
255
285
  ],
@@ -267,7 +297,7 @@
267
297
  ],
268
298
  "returns": "Promise<ZebraProfileConfiguration>",
269
299
  "tags": [],
270
- "docs": "",
300
+ "docs": "Android only. DataWedge may omit `COMMAND_IDENTIFIER` on query replies. The plugin accepts\nidentifier-free replies only when the payload matches exactly one pending call that expects the\nsame result payload shape. Avoid overlapping pending calls that share that shape. For example,\n`getAssociatedApps()` and `getConfig()` both send `CMD_GET_CONFIG` and expect `CONFIG_RESULTS`, so one\npending call to each overlaps. When sender identity is unavailable (Android API 24 to 33, or API\n34+ when the platform withholds it), matching identifier-free replies are accepted for\ncompatibility. If a call times out, a delayed identifier-free reply can still match a later\nsequential call that expects the same shape and resolve it with stale data. This default may\nchange in the next Capacitor major version; see\nhttps://github.com/Cap-go/capacitor-zebra-datawedge/issues/25/.",
271
301
  "complexTypes": [
272
302
  "ZebraProfileConfiguration",
273
303
  "GetConfigOptions"
@@ -280,7 +310,7 @@
280
310
  "parameters": [],
281
311
  "returns": "Promise<DataWedgeStatusResult>",
282
312
  "tags": [],
283
- "docs": "",
313
+ "docs": "Android only. DataWedge may omit `COMMAND_IDENTIFIER` on query replies. The plugin accepts\nidentifier-free replies only when the payload matches exactly one pending call that expects the\nsame result payload shape. Avoid overlapping pending calls that share that shape. When sender\nidentity is unavailable (Android API 24 to 33, or API 34+ when the platform withholds it),\nmatching identifier-free replies are accepted for compatibility. If a call times out, a delayed\nidentifier-free reply can still match a later sequential call that expects the same shape and\nresolve it with stale data. This default may change in the next Capacitor major version; see\nhttps://github.com/Cap-go/capacitor-zebra-datawedge/issues/25/.",
284
314
  "complexTypes": [
285
315
  "DataWedgeStatusResult"
286
316
  ],
@@ -292,7 +322,7 @@
292
322
  "parameters": [],
293
323
  "returns": "Promise<{ appList: DataWedgeAppConfig[]; }>",
294
324
  "tags": [],
295
- "docs": "",
325
+ "docs": "Android only. DataWedge may omit `COMMAND_IDENTIFIER` on query replies. The plugin accepts\nidentifier-free replies only when the payload matches exactly one pending call that expects the\nsame result payload shape. Avoid overlapping pending calls that share that shape. When sender\nidentity is unavailable (Android API 24 to 33, or API 34+ when the platform withholds it),\nmatching identifier-free replies are accepted for compatibility. If a call times out, a delayed\nidentifier-free reply can still match a later sequential call that expects the same shape and\nresolve it with stale data. This default may change in the next Capacitor major version; see\nhttps://github.com/Cap-go/capacitor-zebra-datawedge/issues/25/.",
296
326
  "complexTypes": [
297
327
  "DataWedgeAppConfig"
298
328
  ],
@@ -304,7 +334,7 @@
304
334
  "parameters": [],
305
335
  "returns": "Promise<IgnoreDisabledProfilesResult>",
306
336
  "tags": [],
307
- "docs": "",
337
+ "docs": "Android only. DataWedge may omit `COMMAND_IDENTIFIER` on query replies. The plugin accepts\nidentifier-free replies only when the payload matches exactly one pending call that expects the\nsame result payload shape. Avoid overlapping pending calls that share that shape. When sender\nidentity is unavailable (Android API 24 to 33, or API 34+ when the platform withholds it),\nmatching identifier-free replies are accepted for compatibility. If a call times out, a delayed\nidentifier-free reply can still match a later sequential call that expects the same shape and\nresolve it with stale data. This default may change in the next Capacitor major version; see\nhttps://github.com/Cap-go/capacitor-zebra-datawedge/issues/25/.",
308
338
  "complexTypes": [
309
339
  "IgnoreDisabledProfilesResult"
310
340
  ],
@@ -316,7 +346,7 @@
316
346
  "parameters": [],
317
347
  "returns": "Promise<{ profiles: string[]; }>",
318
348
  "tags": [],
319
- "docs": "",
349
+ "docs": "Android only. DataWedge may omit `COMMAND_IDENTIFIER` on query replies. The plugin accepts\nidentifier-free replies only when the payload matches exactly one pending call that expects the\nsame result payload shape. Avoid overlapping pending calls that share that shape. When sender\nidentity is unavailable (Android API 24 to 33, or API 34+ when the platform withholds it),\nmatching identifier-free replies are accepted for compatibility. If a call times out, a delayed\nidentifier-free reply can still match a later sequential call that expects the same shape and\nresolve it with stale data. This default may change in the next Capacitor major version; see\nhttps://github.com/Cap-go/capacitor-zebra-datawedge/issues/25/.",
320
350
  "complexTypes": [],
321
351
  "slug": "getprofileslist"
322
352
  },
@@ -326,7 +356,7 @@
326
356
  "parameters": [],
327
357
  "returns": "Promise<{ status: string; }>",
328
358
  "tags": [],
329
- "docs": "",
359
+ "docs": "Android only. DataWedge may omit `COMMAND_IDENTIFIER` on query replies. The plugin accepts\nidentifier-free replies only when the payload matches exactly one pending call that expects the\nsame result payload shape. Avoid overlapping pending calls that share that shape. When sender\nidentity is unavailable (Android API 24 to 33, or API 34+ when the platform withholds it),\nmatching identifier-free replies are accepted for compatibility. If a call times out, a delayed\nidentifier-free reply can still match a later sequential call that expects the same shape and\nresolve it with stale data. This default may change in the next Capacitor major version; see\nhttps://github.com/Cap-go/capacitor-zebra-datawedge/issues/25/.",
330
360
  "complexTypes": [
331
361
  "ScannerStatus"
332
362
  ],
@@ -338,7 +368,7 @@
338
368
  "parameters": [],
339
369
  "returns": "Promise<ZebraDeviceVersionInfo>",
340
370
  "tags": [],
341
- "docs": "",
371
+ "docs": "Android only. DataWedge may omit `COMMAND_IDENTIFIER` on query replies. The plugin accepts\nidentifier-free replies only when the payload matches exactly one pending call that expects the\nsame result payload shape. Avoid overlapping pending calls that share that shape. When sender\nidentity is unavailable (Android API 24 to 33, or API 34+ when the platform withholds it),\nmatching identifier-free replies are accepted for compatibility. If a call times out, a delayed\nidentifier-free reply can still match a later sequential call that expects the same shape and\nresolve it with stale data. This default may change in the next Capacitor major version; see\nhttps://github.com/Cap-go/capacitor-zebra-datawedge/issues/25/.",
342
372
  "complexTypes": [
343
373
  "ZebraDeviceVersionInfo"
344
374
  ],
@@ -390,7 +420,7 @@
390
420
  "parameters": [],
391
421
  "returns": "Promise<{ triggers: string[]; }>",
392
422
  "tags": [],
393
- "docs": "",
423
+ "docs": "Android only. DataWedge may omit `COMMAND_IDENTIFIER` on query replies. The plugin accepts\nidentifier-free replies only when the payload matches exactly one pending call that expects the\nsame result payload shape. Avoid overlapping pending calls that share that shape. When sender\nidentity is unavailable (Android API 24 to 33, or API 34+ when the platform withholds it),\nmatching identifier-free replies are accepted for compatibility. If a call times out, a delayed\nidentifier-free reply can still match a later sequential call that expects the same shape and\nresolve it with stale data. This default may change in the next Capacitor major version; see\nhttps://github.com/Cap-go/capacitor-zebra-datawedge/issues/25/.",
394
424
  "complexTypes": [],
395
425
  "slug": "enumeratetriggers"
396
426
  },
@@ -602,6 +632,108 @@
602
632
  "properties": []
603
633
  },
604
634
  "interfaces": [
635
+ {
636
+ "name": "DiagnosticsOptions",
637
+ "slug": "diagnosticsoptions",
638
+ "docs": "",
639
+ "tags": [],
640
+ "methods": [],
641
+ "properties": [
642
+ {
643
+ "name": "enabled",
644
+ "tags": [],
645
+ "docs": "Enable metadata tracing. Disabled by default; disabling does not erase previous entries.",
646
+ "complexTypes": [],
647
+ "type": "boolean"
648
+ },
649
+ {
650
+ "name": "maxEntries",
651
+ "tags": [],
652
+ "docs": "Number of recent entries retained, from 1 to 1000. Initially 100; omitted values preserve the current capacity.",
653
+ "complexTypes": [],
654
+ "type": "number | undefined"
655
+ },
656
+ {
657
+ "name": "reset",
658
+ "tags": [],
659
+ "docs": "Clear retained entries and reset elapsed time and dropped count. Default: false.",
660
+ "complexTypes": [],
661
+ "type": "boolean | undefined"
662
+ }
663
+ ]
664
+ },
665
+ {
666
+ "name": "DataWedgeDiagnosticsSnapshot",
667
+ "slug": "datawedgediagnosticssnapshot",
668
+ "docs": "",
669
+ "tags": [],
670
+ "methods": [],
671
+ "properties": [
672
+ {
673
+ "name": "diagnosticsVersion",
674
+ "tags": [],
675
+ "docs": "",
676
+ "complexTypes": [],
677
+ "type": "number"
678
+ },
679
+ {
680
+ "name": "enabled",
681
+ "tags": [],
682
+ "docs": "",
683
+ "complexTypes": [],
684
+ "type": "boolean"
685
+ },
686
+ {
687
+ "name": "maxEntries",
688
+ "tags": [],
689
+ "docs": "",
690
+ "complexTypes": [],
691
+ "type": "number"
692
+ },
693
+ {
694
+ "name": "droppedEntries",
695
+ "tags": [],
696
+ "docs": "",
697
+ "complexTypes": [],
698
+ "type": "number"
699
+ },
700
+ {
701
+ "name": "manufacturer",
702
+ "tags": [],
703
+ "docs": "",
704
+ "complexTypes": [],
705
+ "type": "string"
706
+ },
707
+ {
708
+ "name": "model",
709
+ "tags": [],
710
+ "docs": "",
711
+ "complexTypes": [],
712
+ "type": "string"
713
+ },
714
+ {
715
+ "name": "androidVersion",
716
+ "tags": [],
717
+ "docs": "",
718
+ "complexTypes": [],
719
+ "type": "string"
720
+ },
721
+ {
722
+ "name": "dataWedgePackage",
723
+ "tags": [],
724
+ "docs": "notFound means Android could not find the package; it is not a service-permission check.",
725
+ "complexTypes": [],
726
+ "type": "{ status: 'installed' | 'notFound' | 'unavailable'; version?: string | undefined; }"
727
+ },
728
+ {
729
+ "name": "commands",
730
+ "tags": [],
731
+ "docs": "",
732
+ "complexTypes": [],
733
+ "type": "{ commandIdentifier: string; outcome: 'SENT' | 'SUCCESS' | 'FAILURE' | 'TIMEOUT' | 'TRANSPORT_ERROR' | 'CANCELLED' | 'INVALID_RESPONSE'; elapsedMs: number; }[]"
734
+ }
735
+ ]
736
+ },
605
737
  {
606
738
  "name": "CloneProfileOptions",
607
739
  "slug": "cloneprofileoptions",