pythonnative 0.25.0__py3-none-any.whl → 0.26.0__py3-none-any.whl

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.
Files changed (44) hide show
  1. pythonnative/__init__.py +1 -1
  2. pythonnative/cli/pn.py +172 -12
  3. pythonnative/diagnostics.py +27 -0
  4. pythonnative/native_modules/app_state.py +2 -1
  5. pythonnative/native_modules/battery.py +3 -2
  6. pythonnative/native_modules/biometrics.py +2 -1
  7. pythonnative/native_modules/camera.py +16 -7
  8. pythonnative/native_modules/clipboard.py +3 -2
  9. pythonnative/native_modules/file_system.py +3 -2
  10. pythonnative/native_modules/haptics.py +7 -6
  11. pythonnative/native_modules/linking.py +62 -6
  12. pythonnative/native_modules/location.py +11 -8
  13. pythonnative/native_modules/net_info.py +2 -1
  14. pythonnative/native_modules/notifications.py +97 -6
  15. pythonnative/native_modules/permissions.py +3 -2
  16. pythonnative/native_modules/share.py +2 -1
  17. pythonnative/native_views/android.py +142 -122
  18. pythonnative/native_views/desktop.py +50 -49
  19. pythonnative/native_views/ios.py +228 -160
  20. pythonnative/project/android.py +15 -3
  21. pythonnative/project/builder.py +172 -70
  22. pythonnative/project/config.py +28 -6
  23. pythonnative/project/devices.py +291 -0
  24. pythonnative/project/doctor.py +5 -4
  25. pythonnative/project/ios.py +51 -77
  26. pythonnative/project/permissions.py +19 -1
  27. pythonnative/project/runtime_assets.py +78 -166
  28. pythonnative/templates/android_template/app/build.gradle +5 -0
  29. pythonnative/templates/android_template/app/src/main/AndroidManifest.xml +1 -0
  30. pythonnative/templates/android_template/app/src/main/java/com/pythonnative/android_template/MainActivity.kt +88 -12
  31. pythonnative/templates/ios_template/ios_template/AppDelegate.swift +41 -17
  32. pythonnative/templates/ios_template/ios_template/BridgingHeader.h +14 -0
  33. pythonnative/templates/ios_template/ios_template/Info.plist +0 -2
  34. pythonnative/templates/ios_template/ios_template/PythonRuntime.swift +397 -0
  35. pythonnative/templates/ios_template/ios_template/SceneDelegate.swift +31 -20
  36. pythonnative/templates/ios_template/ios_template/ViewController.swift +77 -198
  37. pythonnative/templates/ios_template/ios_template.xcodeproj/project.pbxproj +72 -47
  38. {pythonnative-0.25.0.dist-info → pythonnative-0.26.0.dist-info}/METADATA +1 -1
  39. {pythonnative-0.25.0.dist-info → pythonnative-0.26.0.dist-info}/RECORD +43 -41
  40. pythonnative/templates/ios_template/ios_template/Base.lproj/Main.storyboard +0 -24
  41. {pythonnative-0.25.0.dist-info → pythonnative-0.26.0.dist-info}/WHEEL +0 -0
  42. {pythonnative-0.25.0.dist-info → pythonnative-0.26.0.dist-info}/entry_points.txt +0 -0
  43. {pythonnative-0.25.0.dist-info → pythonnative-0.26.0.dist-info}/licenses/LICENSE +0 -0
  44. {pythonnative-0.25.0.dist-info → pythonnative-0.26.0.dist-info}/top_level.txt +0 -0
@@ -40,6 +40,7 @@ from typing import Any, Callable, Dict, Optional, Tuple
40
40
 
41
41
  from java import dynamic_proxy, jclass
42
42
 
43
+ from .. import diagnostics
43
44
  from ..events import dispatch_event, event_names
44
45
  from ..gestures import make_arbiter
45
46
  from ..utils import get_android_context
@@ -206,7 +207,7 @@ def _apply_side_border(view: Any, props: Dict[str, Any]) -> bool:
206
207
  try:
207
208
  view.invalidate()
208
209
  except Exception:
209
- pass
210
+ diagnostics.swallowed("android._apply_side_border")
210
211
  return True
211
212
  except Exception:
212
213
  return False
@@ -237,12 +238,12 @@ def _apply_border(view: Any, props: Dict[str, Any]) -> None:
237
238
  try:
238
239
  drawable.setColor(parse_color_int(props["background_color"]))
239
240
  except Exception:
240
- pass
241
+ diagnostics.swallowed("android._apply_border")
241
242
  if "border_radius" in props and props["border_radius"] is not None:
242
243
  try:
243
244
  drawable.setCornerRadius(float(_dp(float(props["border_radius"]))))
244
245
  except Exception:
245
- pass
246
+ diagnostics.swallowed("android._apply_border")
246
247
  if ("border_width" in props and props["border_width"] is not None) or (
247
248
  "border_color" in props and props["border_color"] is not None
248
249
  ):
@@ -254,18 +255,18 @@ def _apply_border(view: Any, props: Dict[str, Any]) -> None:
254
255
  parse_color_int(color or "#000000"),
255
256
  )
256
257
  except Exception:
257
- pass
258
+ diagnostics.swallowed("android._apply_border")
258
259
  view.setBackground(drawable)
259
260
  try:
260
261
  drawable.invalidateSelf()
261
262
  except Exception:
262
- pass
263
+ diagnostics.swallowed("android._apply_border")
263
264
  try:
264
265
  view.invalidate()
265
266
  except Exception:
266
- pass
267
+ diagnostics.swallowed("android._apply_border")
267
268
  except Exception:
268
- pass
269
+ diagnostics.swallowed("android._apply_border")
269
270
 
270
271
 
271
272
  def _apply_shadow(view: Any, props: Dict[str, Any]) -> None:
@@ -291,7 +292,7 @@ def _apply_shadow(view: Any, props: Dict[str, Any]) -> None:
291
292
  try:
292
293
  view.setElevation(float(_dp(float(elevation))))
293
294
  except Exception:
294
- pass
295
+ diagnostics.swallowed("android._apply_shadow")
295
296
  color = props.get("shadow_color")
296
297
  if color is None:
297
298
  return
@@ -308,7 +309,7 @@ def _apply_shadow(view: Any, props: Dict[str, Any]) -> None:
308
309
  view.setOutlineAmbientShadowColor(signed)
309
310
  view.setOutlineSpotShadowColor(signed)
310
311
  except Exception:
311
- pass
312
+ diagnostics.swallowed("android._apply_shadow")
312
313
 
313
314
 
314
315
  def _apply_transform(view: Any, props: Dict[str, Any]) -> None:
@@ -324,7 +325,7 @@ def _apply_transform(view: Any, props: Dict[str, Any]) -> None:
324
325
  view.setTranslationX(0.0)
325
326
  view.setTranslationY(0.0)
326
327
  except Exception:
327
- pass
328
+ diagnostics.swallowed("android._apply_transform")
328
329
  return
329
330
  entries = spec if isinstance(spec, list) else [spec]
330
331
  for entry in entries:
@@ -353,7 +354,7 @@ def _apply_transform(view: Any, props: Dict[str, Any]) -> None:
353
354
  if "translate_y" in entry:
354
355
  view.setTranslationY(float(_dp(float(entry["translate_y"]))))
355
356
  except Exception:
356
- pass
357
+ diagnostics.swallowed("android._apply_transform")
357
358
 
358
359
 
359
360
  def _apply_accessibility(view: Any, props: Dict[str, Any]) -> None:
@@ -365,13 +366,13 @@ def _apply_accessibility(view: Any, props: Dict[str, Any]) -> None:
365
366
  View.IMPORTANT_FOR_ACCESSIBILITY_YES if props["accessible"] else View.IMPORTANT_FOR_ACCESSIBILITY_NO
366
367
  )
367
368
  except Exception:
368
- pass
369
+ diagnostics.swallowed("android._apply_accessibility")
369
370
  if "accessibility_label" in props:
370
371
  try:
371
372
  label = props["accessibility_label"]
372
373
  view.setContentDescription(str(label) if label is not None else None)
373
374
  except Exception:
374
- pass
375
+ diagnostics.swallowed("android._apply_accessibility")
375
376
  if "accessibility_live_region" in props:
376
377
  try:
377
378
  mode = {"none": 0, "polite": 1, "assertive": 2}.get(
@@ -379,14 +380,14 @@ def _apply_accessibility(view: Any, props: Dict[str, Any]) -> None:
379
380
  )
380
381
  view.setAccessibilityLiveRegion(mode)
381
382
  except Exception:
382
- pass
383
+ diagnostics.swallowed("android._apply_accessibility")
383
384
 
384
385
  state = props.get("accessibility_state")
385
386
  if isinstance(state, dict) and "selected" in state:
386
387
  try:
387
388
  view.setSelected(bool(state["selected"]))
388
389
  except Exception:
389
- pass
390
+ diagnostics.swallowed("android._apply_accessibility")
390
391
  test_id = props.get("test_id")
391
392
  if test_id is None and not isinstance(state, dict):
392
393
  return
@@ -413,7 +414,7 @@ def _apply_accessibility(view: Any, props: Dict[str, Any]) -> None:
413
414
  delegate.setStateBusy(state.get("busy"))
414
415
  delegate.setStateExpanded(state.get("expanded"))
415
416
  except Exception:
416
- pass
417
+ diagnostics.swallowed("android._apply_accessibility")
417
418
 
418
419
 
419
420
  def _apply_common_visual(view: Any, props: Dict[str, Any]) -> None:
@@ -433,12 +434,12 @@ def _apply_common_visual(view: Any, props: Dict[str, Any]) -> None:
433
434
  view.setClipChildren(clip)
434
435
  view.setClipToPadding(clip)
435
436
  except Exception:
436
- pass
437
+ diagnostics.swallowed("android._apply_common_visual")
437
438
  if "opacity" in props and props["opacity"] is not None:
438
439
  try:
439
440
  view.setAlpha(float(props["opacity"]))
440
441
  except Exception:
441
- pass
442
+ diagnostics.swallowed("android._apply_common_visual")
442
443
  _apply_shadow(view, props)
443
444
  _apply_transform(view, props)
444
445
  _apply_accessibility(view, props)
@@ -501,7 +502,7 @@ def _schedule_arbiter_poll(view: Any, state: Dict[str, Any]) -> None:
501
502
 
502
503
  handler.postDelayed(_PollRunnable(), delay_ms)
503
504
  except Exception:
504
- pass
505
+ diagnostics.swallowed("android._schedule_arbiter_poll")
505
506
 
506
507
 
507
508
  def _bind_touch_stream(view: Any, state: Dict[str, Any]) -> None:
@@ -515,7 +516,7 @@ def _bind_touch_stream(view: Any, state: Dict[str, Any]) -> None:
515
516
 
516
517
  view.setOnTouchListener(_GestureTouchProxy())
517
518
  except Exception:
518
- pass
519
+ diagnostics.swallowed("android._bind_touch_stream")
519
520
 
520
521
 
521
522
  def _feed_motion_event(view: Any, state: Dict[str, Any], event: Any) -> bool:
@@ -546,7 +547,7 @@ def _feed_motion_event(view: Any, state: Dict[str, Any], event: Any) -> bool:
546
547
  if parent is not None:
547
548
  parent.requestDisallowInterceptTouchEvent(True)
548
549
  except Exception:
549
- pass
550
+ diagnostics.swallowed("android._feed_motion_event")
550
551
  elif action in (1, 6): # UP / POINTER_UP
551
552
  idx = int(event.getActionIndex())
552
553
  pid = int(event.getPointerId(idx))
@@ -603,7 +604,7 @@ def _read_animated_value(view: Any, prop_name: str) -> Any:
603
604
  if prop_name == "rotate":
604
605
  return float(view.getRotation())
605
606
  except Exception:
606
- pass
607
+ diagnostics.swallowed("android._read_animated_value")
607
608
  return None
608
609
 
609
610
 
@@ -639,7 +640,7 @@ def _make_end_listener(anim_id: int) -> Any:
639
640
 
640
641
  native_animation_completed(anim_id, not self._cancelled)
641
642
  except Exception:
642
- pass
643
+ diagnostics.swallowed("android._make_end_listener._EndProxy.onAnimationEnd")
643
644
 
644
645
  return _EndProxy()
645
646
 
@@ -731,7 +732,7 @@ class AndroidViewHandler(ViewHandler):
731
732
  if parent is not None:
732
733
  parent.removeView(native_view)
733
734
  except Exception:
734
- pass
735
+ diagnostics.swallowed("android.AndroidViewHandler.destroy")
735
736
  _forget(native_view)
736
737
 
737
738
  def _build(self, props: Dict[str, Any]) -> Any:
@@ -760,17 +761,17 @@ class AndroidViewHandler(ViewHandler):
760
761
  lp.width = px_w
761
762
  lp.height = px_h
762
763
  except Exception:
763
- pass
764
+ diagnostics.swallowed("android.AndroidViewHandler.set_frame")
764
765
  try:
765
766
  lp.leftMargin = px_x
766
767
  lp.topMargin = px_y
767
768
  lp.rightMargin = 0
768
769
  lp.bottomMargin = 0
769
770
  except Exception:
770
- pass
771
+ diagnostics.swallowed("android.AndroidViewHandler.set_frame")
771
772
  native_view.setLayoutParams(lp)
772
773
  except Exception:
773
- pass
774
+ diagnostics.swallowed("android.AndroidViewHandler.set_frame")
774
775
 
775
776
  def measure_intrinsic(
776
777
  self,
@@ -823,7 +824,7 @@ class AndroidViewHandler(ViewHandler):
823
824
  elif prop_name == "background_color":
824
825
  native_view.setBackgroundColor(parse_color_int(value))
825
826
  except Exception:
826
- pass
827
+ diagnostics.swallowed("android.AndroidViewHandler.set_animated_property")
827
828
 
828
829
  def start_animation(
829
830
  self,
@@ -851,7 +852,7 @@ class AndroidViewHandler(ViewHandler):
851
852
  try:
852
853
  entry["animator"].cancel()
853
854
  except Exception:
854
- pass
855
+ diagnostics.swallowed("android.AndroidViewHandler.cancel_animation")
855
856
  return _read_animated_value(entry.get("view"), str(entry.get("prop", "")))
856
857
 
857
858
 
@@ -879,7 +880,7 @@ class FlexContainerHandler(AndroidViewHandler):
879
880
  try:
880
881
  parent.removeView(child)
881
882
  except Exception:
882
- pass
883
+ diagnostics.swallowed("android.FlexContainerHandler.remove_child")
883
884
 
884
885
 
885
886
  def _insert_view(parent: Any, child: Any, index: int) -> None:
@@ -905,7 +906,7 @@ def _insert_view(parent: Any, child: Any, index: int) -> None:
905
906
  try:
906
907
  parent.addView(child)
907
908
  except Exception:
908
- pass
909
+ diagnostics.swallowed("android._insert_view")
909
910
 
910
911
 
911
912
  # ======================================================================
@@ -993,7 +994,7 @@ def _build_spannable(spans: Any) -> Any:
993
994
  StrikethroughSpan = jclass("android.text.style.StrikethroughSpan")
994
995
  _set(StrikethroughSpan())
995
996
  except Exception:
996
- pass
997
+ diagnostics.swallowed("android._build_spannable")
997
998
  return builder
998
999
 
999
1000
 
@@ -1035,7 +1036,7 @@ class TextHandler(AndroidViewHandler):
1035
1036
  else:
1036
1037
  tv.setTypeface(tv.getTypeface(), style)
1037
1038
  except Exception:
1038
- pass
1039
+ diagnostics.swallowed("android.TextHandler._apply")
1039
1040
  if "max_lines" in props and props["max_lines"] is not None:
1040
1041
  tv.setMaxLines(int(props["max_lines"]))
1041
1042
  if "text_align" in props:
@@ -1050,14 +1051,14 @@ class TextHandler(AndroidViewHandler):
1050
1051
  size = float(merged.get("font_size") or 16.0)
1051
1052
  tv.setLetterSpacing(float(props["letter_spacing"]) / max(size, 1.0))
1052
1053
  except Exception:
1053
- pass
1054
+ diagnostics.swallowed("android.TextHandler._apply")
1054
1055
  if "line_height" in props and props["line_height"] is not None:
1055
1056
  try:
1056
1057
  merged = _state_of(tv).get("props") or props
1057
1058
  size = float(merged.get("font_size") or 16.0)
1058
1059
  tv.setLineSpacing(0.0, float(props["line_height"]) / max(size, 1.0))
1059
1060
  except Exception:
1060
- pass
1061
+ diagnostics.swallowed("android.TextHandler._apply")
1061
1062
  if "text_decoration" in props:
1062
1063
  try:
1063
1064
  Paint = jclass("android.graphics.Paint")
@@ -1068,7 +1069,7 @@ class TextHandler(AndroidViewHandler):
1068
1069
  flags |= Paint.STRIKE_THRU_TEXT_FLAG
1069
1070
  tv.setPaintFlags(flags)
1070
1071
  except Exception:
1071
- pass
1072
+ diagnostics.swallowed("android.TextHandler._apply")
1072
1073
  _apply_common_visual(tv, props)
1073
1074
 
1074
1075
 
@@ -1147,7 +1148,7 @@ class ScrollViewHandler(AndroidViewHandler):
1147
1148
  try:
1148
1149
  outer.setEnabled(False)
1149
1150
  except Exception:
1150
- pass
1151
+ diagnostics.swallowed("android.ScrollViewHandler.create")
1151
1152
  self._bind_scroll_listener(outer, sv)
1152
1153
  self._apply(outer, props, initial=True)
1153
1154
  if props.get("gestures"):
@@ -1165,7 +1166,7 @@ class ScrollViewHandler(AndroidViewHandler):
1165
1166
  sv.setVerticalScrollBarEnabled(show)
1166
1167
  sv.setHorizontalScrollBarEnabled(show)
1167
1168
  except Exception:
1168
- pass
1169
+ diagnostics.swallowed("android.ScrollViewHandler._apply")
1169
1170
  if "bounces" in props:
1170
1171
  # ``bounces`` is only present when ``False``; map it to the
1171
1172
  # closest analogue, the over-scroll (glow) mode.
@@ -1174,7 +1175,7 @@ class ScrollViewHandler(AndroidViewHandler):
1174
1175
  mode = View.OVER_SCROLL_NEVER if props["bounces"] is False else View.OVER_SCROLL_IF_CONTENT_SCROLLS
1175
1176
  sv.setOverScrollMode(mode)
1176
1177
  except Exception:
1177
- pass
1178
+ diagnostics.swallowed("android.ScrollViewHandler._apply")
1178
1179
  if "refresh_control" in props and state.get("refresh") is not None:
1179
1180
  self._apply_refresh(outer, props)
1180
1181
  # ``paging_enabled`` and ``keyboard_dismiss_mode`` have no clean
@@ -1190,7 +1191,7 @@ class ScrollViewHandler(AndroidViewHandler):
1190
1191
  try:
1191
1192
  sv.removeView(child)
1192
1193
  except Exception:
1193
- pass
1194
+ diagnostics.swallowed("android.ScrollViewHandler.remove_child")
1194
1195
 
1195
1196
  def command(self, native_view: Any, name: str, args: Dict[str, Any]) -> Any:
1196
1197
  state = _state_of(native_view)
@@ -1206,7 +1207,7 @@ class ScrollViewHandler(AndroidViewHandler):
1206
1207
  else:
1207
1208
  sv.scrollTo(x_px, y_px)
1208
1209
  except Exception:
1209
- pass
1210
+ diagnostics.swallowed("android.ScrollViewHandler.command")
1210
1211
  return None
1211
1212
  if name == "scroll_to_end":
1212
1213
  try:
@@ -1220,7 +1221,7 @@ class ScrollViewHandler(AndroidViewHandler):
1220
1221
  target_y = max(0, int(child.getHeight()) - int(sv.getHeight()))
1221
1222
  sv.smoothScrollTo(0, target_y)
1222
1223
  except Exception:
1223
- pass
1224
+ diagnostics.swallowed("android.ScrollViewHandler.command")
1224
1225
  return None
1225
1226
  if name == "get_scroll_offset":
1226
1227
  try:
@@ -1250,11 +1251,13 @@ class ScrollViewHandler(AndroidViewHandler):
1250
1251
  density = _density() or 1.0
1251
1252
  _fire(outer, "on_scroll", {"x": scroll_x / density, "y": scroll_y / density})
1252
1253
  except Exception:
1253
- pass
1254
+ diagnostics.swallowed(
1255
+ "android.ScrollViewHandler._bind_scroll_listener._ScrollChangeProxy.onScrollChange"
1256
+ )
1254
1257
 
1255
1258
  sv.setOnScrollChangeListener(_ScrollChangeProxy())
1256
1259
  except Exception:
1257
- pass
1260
+ diagnostics.swallowed("android.ScrollViewHandler._bind_scroll_listener")
1258
1261
 
1259
1262
  def _wrap_in_refresh(self, sv: Any) -> Any:
1260
1263
  try:
@@ -1278,7 +1281,7 @@ class ScrollViewHandler(AndroidViewHandler):
1278
1281
 
1279
1282
  srl.setOnRefreshListener(_RefreshProxy())
1280
1283
  except Exception:
1281
- pass
1284
+ diagnostics.swallowed("android.ScrollViewHandler._bind_refresh_listener")
1282
1285
 
1283
1286
  def _apply_refresh(self, outer: Any, props: Dict[str, Any]) -> None:
1284
1287
  srl = _state_of(outer).get("refresh")
@@ -1289,21 +1292,21 @@ class ScrollViewHandler(AndroidViewHandler):
1289
1292
  try:
1290
1293
  srl.setEnabled(False)
1291
1294
  except Exception:
1292
- pass
1295
+ diagnostics.swallowed("android.ScrollViewHandler._apply_refresh")
1293
1296
  return
1294
1297
  try:
1295
1298
  srl.setEnabled(True)
1296
1299
  except Exception:
1297
- pass
1300
+ diagnostics.swallowed("android.ScrollViewHandler._apply_refresh")
1298
1301
  if spec.get("tint_color"):
1299
1302
  try:
1300
1303
  srl.setColorSchemeColors([parse_color_int(spec["tint_color"])])
1301
1304
  except Exception:
1302
- pass
1305
+ diagnostics.swallowed("android.ScrollViewHandler._apply_refresh")
1303
1306
  try:
1304
1307
  srl.setRefreshing(bool(spec.get("refreshing")))
1305
1308
  except Exception:
1306
- pass
1309
+ diagnostics.swallowed("android.ScrollViewHandler._apply_refresh")
1307
1310
 
1308
1311
 
1309
1312
  class TextInputHandler(AndroidViewHandler):
@@ -1316,7 +1319,7 @@ class TextInputHandler(AndroidViewHandler):
1316
1319
  if not props.get("multiline"):
1317
1320
  et.setSingleLine(True)
1318
1321
  except Exception:
1319
- pass
1322
+ diagnostics.swallowed("android.TextInputHandler._build")
1320
1323
  self._bind_listeners(et, props)
1321
1324
  return et
1322
1325
 
@@ -1342,7 +1345,7 @@ class TextInputHandler(AndroidViewHandler):
1342
1345
 
1343
1346
  et.addTextChangedListener(ChangeProxy())
1344
1347
  except Exception:
1345
- pass
1348
+ diagnostics.swallowed("android.TextInputHandler._bind_listeners")
1346
1349
  try:
1347
1350
 
1348
1351
  class _FocusProxy(dynamic_proxy(jclass("android.view.View").OnFocusChangeListener)):
@@ -1351,7 +1354,7 @@ class TextInputHandler(AndroidViewHandler):
1351
1354
 
1352
1355
  et.setOnFocusChangeListener(_FocusProxy())
1353
1356
  except Exception:
1354
- pass
1357
+ diagnostics.swallowed("android.TextInputHandler._bind_listeners")
1355
1358
 
1356
1359
  def _apply(self, et: Any, props: Dict[str, Any], initial: bool) -> None:
1357
1360
  state = _state_of(et)
@@ -1368,7 +1371,7 @@ class TextInputHandler(AndroidViewHandler):
1368
1371
  selection_start = et.getSelectionStart()
1369
1372
  selection_end = et.getSelectionEnd()
1370
1373
  except Exception:
1371
- pass
1374
+ diagnostics.swallowed("android.TextInputHandler._apply")
1372
1375
  state["suppress"] = True
1373
1376
  try:
1374
1377
  et.setText(incoming)
@@ -1381,7 +1384,7 @@ class TextInputHandler(AndroidViewHandler):
1381
1384
  else:
1382
1385
  et.setSelection(start, end)
1383
1386
  except Exception:
1384
- pass
1387
+ diagnostics.swallowed("android.TextInputHandler._apply")
1385
1388
  finally:
1386
1389
  state["suppress"] = False
1387
1390
  if "placeholder" in props:
@@ -1390,7 +1393,7 @@ class TextInputHandler(AndroidViewHandler):
1390
1393
  try:
1391
1394
  et.setHintTextColor(parse_color_int(props["placeholder_color"]))
1392
1395
  except Exception:
1393
- pass
1396
+ diagnostics.swallowed("android.TextInputHandler._apply")
1394
1397
  if "font_size" in props and props["font_size"] is not None:
1395
1398
  et.setTextSize(float(props["font_size"]))
1396
1399
  if "color" in props and props["color"] is not None:
@@ -1428,18 +1431,18 @@ class TextInputHandler(AndroidViewHandler):
1428
1431
  et.setSingleLine(True)
1429
1432
  et.setInputType(base)
1430
1433
  except Exception:
1431
- pass
1434
+ diagnostics.swallowed("android.TextInputHandler._apply")
1432
1435
  if "max_length" in props and props["max_length"] is not None:
1433
1436
  try:
1434
1437
  InputFilter = jclass("android.text.InputFilter$LengthFilter")
1435
1438
  et.setFilters([InputFilter(int(props["max_length"]))])
1436
1439
  except Exception:
1437
- pass
1440
+ diagnostics.swallowed("android.TextInputHandler._apply")
1438
1441
  if "auto_focus" in props and props["auto_focus"]:
1439
1442
  try:
1440
1443
  et.requestFocus()
1441
1444
  except Exception:
1442
- pass
1445
+ diagnostics.swallowed("android.TextInputHandler._apply")
1443
1446
  if "editable" in props:
1444
1447
  # ``editable`` is only present when ``False`` (read-only); a
1445
1448
  # removal (``None``) restores editing. We keep the field
@@ -1452,12 +1455,12 @@ class TextInputHandler(AndroidViewHandler):
1452
1455
  et.setCursorVisible(editable)
1453
1456
  et.setLongClickable(editable)
1454
1457
  except Exception:
1455
- pass
1458
+ diagnostics.swallowed("android.TextInputHandler._apply")
1456
1459
  if "selection_color" in props and props["selection_color"] is not None:
1457
1460
  try:
1458
1461
  et.setHighlightColor(parse_color_int(props["selection_color"]))
1459
1462
  except Exception:
1460
- pass
1463
+ diagnostics.swallowed("android.TextInputHandler._apply")
1461
1464
  if "text_content_type" in props and props["text_content_type"] is not None:
1462
1465
  self._apply_autofill(et, str(props["text_content_type"]))
1463
1466
  if "clear_button" in props:
@@ -1485,7 +1488,7 @@ class TextInputHandler(AndroidViewHandler):
1485
1488
  action = rkt_mapping.get(props["return_key_type"], EditorInfo.IME_ACTION_DONE)
1486
1489
  et.setImeOptions(action)
1487
1490
  except Exception:
1488
- pass
1491
+ diagnostics.swallowed("android.TextInputHandler._apply")
1489
1492
  if initial or "multiline" in props:
1490
1493
  self._apply_editor_action(et)
1491
1494
  _apply_common_visual(et, props)
@@ -1514,7 +1517,9 @@ class TextInputHandler(AndroidViewHandler):
1514
1517
  try:
1515
1518
  _fire(view, "on_submit", str(view.getText()))
1516
1519
  except Exception:
1517
- pass
1520
+ diagnostics.swallowed(
1521
+ "android.TextInputHandler._apply_editor_action.SubmitProxy.onEditorAction"
1522
+ )
1518
1523
  if not multiline:
1519
1524
  try:
1520
1525
  view.clearFocus()
@@ -1522,12 +1527,14 @@ class TextInputHandler(AndroidViewHandler):
1522
1527
  imm = ctx.getSystemService(Context.INPUT_METHOD_SERVICE)
1523
1528
  imm.hideSoftInputFromWindow(view.getWindowToken(), 0)
1524
1529
  except Exception:
1525
- pass
1530
+ diagnostics.swallowed(
1531
+ "android.TextInputHandler._apply_editor_action.SubmitProxy.onEditorAction"
1532
+ )
1526
1533
  return True
1527
1534
 
1528
1535
  et.setOnEditorActionListener(SubmitProxy())
1529
1536
  except Exception:
1530
- pass
1537
+ diagnostics.swallowed("android.TextInputHandler._apply_editor_action")
1531
1538
 
1532
1539
  @staticmethod
1533
1540
  def _autofill_hint(content_type: str) -> Optional[str]:
@@ -1559,7 +1566,7 @@ class TextInputHandler(AndroidViewHandler):
1559
1566
  if hint:
1560
1567
  et.setAutofillHints([hint])
1561
1568
  except Exception:
1562
- pass
1569
+ diagnostics.swallowed("android.TextInputHandler._apply_autofill")
1563
1570
 
1564
1571
  def _apply_clear_button(self, et: Any, enabled: bool) -> None:
1565
1572
  # Best-effort drawableEnd "X": shows a system clear icon and wires
@@ -1588,12 +1595,12 @@ class TextInputHandler(AndroidViewHandler):
1588
1595
  view.setText("")
1589
1596
  return True
1590
1597
  except Exception:
1591
- pass
1598
+ diagnostics.swallowed("android.TextInputHandler._apply_clear_button._ClearTouchProxy.onTouch")
1592
1599
  return False
1593
1600
 
1594
1601
  et.setOnTouchListener(_ClearTouchProxy())
1595
1602
  except Exception:
1596
- pass
1603
+ diagnostics.swallowed("android.TextInputHandler._apply_clear_button")
1597
1604
 
1598
1605
 
1599
1606
  class ImageHandler(AndroidViewHandler):
@@ -1606,12 +1613,12 @@ class ImageHandler(AndroidViewHandler):
1606
1613
  ColorStateList = jclass("android.content.res.ColorStateList")
1607
1614
  iv.setImageTintList(ColorStateList.valueOf(parse_color_int(props["tint_color"])))
1608
1615
  except Exception:
1609
- pass
1616
+ diagnostics.swallowed("android.ImageHandler._apply")
1610
1617
  if "placeholder_color" in props and props["placeholder_color"] is not None:
1611
1618
  try:
1612
1619
  iv.setBackgroundColor(parse_color_int(props["placeholder_color"]))
1613
1620
  except Exception:
1614
- pass
1621
+ diagnostics.swallowed("android.ImageHandler._apply")
1615
1622
  if "source" in props and props["source"]:
1616
1623
  self._load_source(iv, str(props["source"]))
1617
1624
  if "scale_type" in props and props["scale_type"]:
@@ -1648,7 +1655,7 @@ class ImageHandler(AndroidViewHandler):
1648
1655
  iv.setImageBitmap(bitmap)
1649
1656
  _fire(iv, "on_load")
1650
1657
  except Exception:
1651
- pass
1658
+ diagnostics.swallowed("android.ImageHandler._load_source._on_ready")
1652
1659
 
1653
1660
  def _on_error(message: str) -> None:
1654
1661
  if _state_of(iv).get("pending_uri") == source:
@@ -1674,7 +1681,7 @@ class ImageHandler(AndroidViewHandler):
1674
1681
  else:
1675
1682
  _fire(iv, "on_error", f"drawable {res_name!r} not found")
1676
1683
  except Exception:
1677
- pass
1684
+ diagnostics.swallowed("android.ImageHandler._load_source")
1678
1685
 
1679
1686
  def _load_data_uri(self, iv: Any, source: str) -> None:
1680
1687
  """Decode an inline ``data:`` URI (base64 payload) into the view."""
@@ -1719,7 +1726,7 @@ class ImageHandler(AndroidViewHandler):
1719
1726
  target_w = int(iv.getWidth())
1720
1727
  target_h = int(iv.getHeight())
1721
1728
  except Exception:
1722
- pass
1729
+ diagnostics.swallowed("android.ImageHandler._decode_downsampled")
1723
1730
  if target_w <= 0:
1724
1731
  try:
1725
1732
  metrics = _ctx().getResources().getDisplayMetrics()
@@ -1780,7 +1787,7 @@ class ProgressBarHandler(AndroidViewHandler):
1780
1787
  ColorStateList = jclass("android.content.res.ColorStateList")
1781
1788
  pb.setProgressTintList(ColorStateList.valueOf(parse_color_int(props["color"])))
1782
1789
  except Exception:
1783
- pass
1790
+ diagnostics.swallowed("android.ProgressBarHandler._apply")
1784
1791
  if "track_color" in props and props["track_color"] is not None:
1785
1792
  try:
1786
1793
  ColorStateList = jclass("android.content.res.ColorStateList")
@@ -1788,12 +1795,12 @@ class ProgressBarHandler(AndroidViewHandler):
1788
1795
  pb.setProgressBackgroundTintList(track)
1789
1796
  pb.setSecondaryProgressTintList(track)
1790
1797
  except Exception:
1791
- pass
1798
+ diagnostics.swallowed("android.ProgressBarHandler._apply")
1792
1799
  if "indeterminate" in props:
1793
1800
  try:
1794
1801
  pb.setIndeterminate(bool(props["indeterminate"]))
1795
1802
  except Exception:
1796
- pass
1803
+ diagnostics.swallowed("android.ProgressBarHandler._apply")
1797
1804
 
1798
1805
 
1799
1806
  class ActivityIndicatorHandler(AndroidViewHandler):
@@ -1809,7 +1816,7 @@ class ActivityIndicatorHandler(AndroidViewHandler):
1809
1816
  ColorStateList = jclass("android.content.res.ColorStateList")
1810
1817
  pb.setIndeterminateTintList(ColorStateList.valueOf(parse_color_int(props["color"])))
1811
1818
  except Exception:
1812
- pass
1819
+ diagnostics.swallowed("android.ActivityIndicatorHandler._apply")
1813
1820
  if "size" in props and props["size"] is not None:
1814
1821
  # The framework ProgressBar has no runtime size switch, so
1815
1822
  # approximate "large" by scaling the indeterminate drawable.
@@ -1818,7 +1825,7 @@ class ActivityIndicatorHandler(AndroidViewHandler):
1818
1825
  pb.setScaleX(scale)
1819
1826
  pb.setScaleY(scale)
1820
1827
  except Exception:
1821
- pass
1828
+ diagnostics.swallowed("android.ActivityIndicatorHandler._apply")
1822
1829
 
1823
1830
 
1824
1831
  def _make_web_client(wv: Any) -> Any:
@@ -1854,13 +1861,13 @@ def _make_web_client(wv: Any) -> Any:
1854
1861
  )
1855
1862
  view.evaluateJavascript(shim, None)
1856
1863
  except Exception:
1857
- pass
1864
+ diagnostics.swallowed("android._make_web_client._WebClientProxy.onPageFinished")
1858
1865
  inject_js = (_state_of(wv).get("props") or {}).get("inject_javascript")
1859
1866
  if inject_js:
1860
1867
  try:
1861
1868
  view.evaluateJavascript(str(inject_js), None)
1862
1869
  except Exception:
1863
- pass
1870
+ diagnostics.swallowed("android._make_web_client._WebClientProxy.onPageFinished")
1864
1871
 
1865
1872
  def shouldOverrideUrlLoading(self, view: Any, request: Any) -> bool:
1866
1873
  try:
@@ -1873,7 +1880,7 @@ def _make_web_client(wv: Any) -> Any:
1873
1880
 
1874
1881
  _fire(wv, "on_message", unquote(url[len(scheme) :]))
1875
1882
  except Exception:
1876
- pass
1883
+ diagnostics.swallowed("android._make_web_client._WebClientProxy.shouldOverrideUrlLoading")
1877
1884
  return True
1878
1885
  return False
1879
1886
 
@@ -1893,7 +1900,7 @@ class WebViewHandler(AndroidViewHandler):
1893
1900
  try:
1894
1901
  wv.getSettings().setJavaScriptEnabled(True)
1895
1902
  except Exception:
1896
- pass
1903
+ diagnostics.swallowed("android.WebViewHandler._apply")
1897
1904
 
1898
1905
  if initial:
1899
1906
  client = _make_web_client(wv)
@@ -1901,19 +1908,19 @@ class WebViewHandler(AndroidViewHandler):
1901
1908
  try:
1902
1909
  wv.setWebViewClient(client)
1903
1910
  except Exception:
1904
- pass
1911
+ diagnostics.swallowed("android.WebViewHandler._apply")
1905
1912
 
1906
1913
  # ``html`` takes precedence over ``url`` when both are present.
1907
1914
  if "html" in props and props["html"]:
1908
1915
  try:
1909
1916
  wv.loadDataWithBaseURL(None, str(props["html"]), "text/html", "utf-8", None)
1910
1917
  except Exception:
1911
- pass
1918
+ diagnostics.swallowed("android.WebViewHandler._apply")
1912
1919
  elif "url" in props and props["url"]:
1913
1920
  try:
1914
1921
  wv.loadUrl(str(props["url"]))
1915
1922
  except Exception:
1916
- pass
1923
+ diagnostics.swallowed("android.WebViewHandler._apply")
1917
1924
 
1918
1925
  if "scroll_enabled" in props:
1919
1926
  self._apply_scroll_enabled(wv, props["scroll_enabled"])
@@ -1930,7 +1937,7 @@ class WebViewHandler(AndroidViewHandler):
1930
1937
  else:
1931
1938
  wv.setOnTouchListener(None)
1932
1939
  except Exception:
1933
- pass
1940
+ diagnostics.swallowed("android.WebViewHandler._apply_scroll_enabled")
1934
1941
 
1935
1942
 
1936
1943
  class SpacerHandler(AndroidViewHandler):
@@ -1995,7 +2002,7 @@ class ModalHandler(AndroidViewHandler):
1995
2002
  try:
1996
2003
  dialog.setCanceledOnTouchOutside(props["dismiss_on_backdrop"] is not False)
1997
2004
  except Exception:
1998
- pass
2005
+ diagnostics.swallowed("android.ModalHandler._apply")
1999
2006
 
2000
2007
  def insert_child(self, parent: Any, child: Any, index: int) -> None:
2001
2008
  state = _state_of(parent)
@@ -2012,7 +2019,7 @@ class ModalHandler(AndroidViewHandler):
2012
2019
  try:
2013
2020
  content.removeView(child)
2014
2021
  except Exception:
2015
- pass
2022
+ diagnostics.swallowed("android.ModalHandler.remove_child")
2016
2023
  else:
2017
2024
  buf = state.get("pending")
2018
2025
  if buf and child in buf:
@@ -2057,18 +2064,18 @@ class ModalHandler(AndroidViewHandler):
2057
2064
  WMLP = jclass("android.view.WindowManager$LayoutParams")
2058
2065
  window.setLayout(WMLP.MATCH_PARENT, WMLP.MATCH_PARENT)
2059
2066
  except Exception:
2060
- pass
2067
+ diagnostics.swallowed("android.ModalHandler._present")
2061
2068
  try:
2062
2069
  dialog.setCanceledOnTouchOutside(props.get("dismiss_on_backdrop") is not False)
2063
2070
  except Exception:
2064
- pass
2071
+ diagnostics.swallowed("android.ModalHandler._present")
2065
2072
  state["dialog"] = dialog
2066
2073
  state["content_view"] = content
2067
2074
  for child in state.pop("pending", []):
2068
2075
  try:
2069
2076
  content.addView(child)
2070
2077
  except Exception:
2071
- pass
2078
+ diagnostics.swallowed("android.ModalHandler._present")
2072
2079
 
2073
2080
  OnShowListener = jclass("android.content.DialogInterface$OnShowListener")
2074
2081
 
@@ -2087,7 +2094,7 @@ class ModalHandler(AndroidViewHandler):
2087
2094
  dialog.setOnDismissListener(_DismissProxy())
2088
2095
  dialog.show()
2089
2096
  except Exception:
2090
- pass
2097
+ diagnostics.swallowed("android.ModalHandler._present")
2091
2098
 
2092
2099
  def _dismiss(self, placeholder: Any, state: Dict[str, Any]) -> None:
2093
2100
  dialog = state.pop("dialog", None)
@@ -2096,7 +2103,7 @@ class ModalHandler(AndroidViewHandler):
2096
2103
  try:
2097
2104
  dialog.dismiss()
2098
2105
  except Exception:
2099
- pass
2106
+ diagnostics.swallowed("android.ModalHandler._dismiss")
2100
2107
 
2101
2108
 
2102
2109
  # ======================================================================
@@ -2148,7 +2155,7 @@ class PortalHandler(AndroidViewHandler):
2148
2155
  lp = LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)
2149
2156
  container.addView(overlay, lp)
2150
2157
  except Exception:
2151
- pass
2158
+ diagnostics.swallowed("android.PortalHandler._ensure_attached")
2152
2159
 
2153
2160
  def insert_child(self, parent: Any, child: Any, index: int) -> None:
2154
2161
  self._ensure_attached(parent)
@@ -2158,7 +2165,7 @@ class PortalHandler(AndroidViewHandler):
2158
2165
  try:
2159
2166
  parent.removeView(child)
2160
2167
  except Exception:
2161
- pass
2168
+ diagnostics.swallowed("android.PortalHandler.remove_child")
2162
2169
 
2163
2170
  def set_frame(self, native_view: Any, x: float, y: float, width: float, height: float) -> None:
2164
2171
  # The overlay fills its container via MATCH_PARENT layout params;
@@ -2171,7 +2178,7 @@ class PortalHandler(AndroidViewHandler):
2171
2178
  if parent is not None:
2172
2179
  parent.removeView(overlay)
2173
2180
  except Exception:
2174
- pass
2181
+ diagnostics.swallowed("android.PortalHandler._teardown")
2175
2182
 
2176
2183
 
2177
2184
  class SliderHandler(AndroidViewHandler):
@@ -2225,7 +2232,7 @@ class TabBarHandler(AndroidViewHandler):
2225
2232
  try:
2226
2233
  bnv.setLabelVisibilityMode(self._LABEL_VISIBILITY_LABELED)
2227
2234
  except Exception:
2228
- pass
2235
+ diagnostics.swallowed("android.TabBarHandler._build")
2229
2236
  return bnv
2230
2237
  except Exception:
2231
2238
  LinearLayout = jclass("android.widget.LinearLayout")
@@ -2275,7 +2282,7 @@ class TabBarHandler(AndroidViewHandler):
2275
2282
 
2276
2283
  bnv.setOnItemSelectedListener(_TabSelectProxy())
2277
2284
  except Exception:
2278
- pass
2285
+ diagnostics.swallowed("android.TabBarHandler._bind_material_listener")
2279
2286
 
2280
2287
  def _set_menu(self, bnv: Any, items: list) -> None:
2281
2288
  try:
@@ -2289,9 +2296,9 @@ class TabBarHandler(AndroidViewHandler):
2289
2296
  try:
2290
2297
  menu_item.setIcon(res_id)
2291
2298
  except Exception:
2292
- pass
2299
+ diagnostics.swallowed("android.TabBarHandler._set_menu")
2293
2300
  except Exception:
2294
- pass
2301
+ diagnostics.swallowed("android.TabBarHandler._set_menu")
2295
2302
 
2296
2303
  def _resolve_icon(self, icon: Any) -> int:
2297
2304
  """Resolve a tab icon spec to an `android.R.drawable.*` res id.
@@ -2325,7 +2332,7 @@ class TabBarHandler(AndroidViewHandler):
2325
2332
  try:
2326
2333
  bnv.setSelectedItemId(i)
2327
2334
  except Exception:
2328
- pass
2335
+ diagnostics.swallowed("android.TabBarHandler._set_active")
2329
2336
  break
2330
2337
 
2331
2338
  def _apply_fallback(self, ll: Any, props: Dict[str, Any]) -> None:
@@ -2425,7 +2432,9 @@ class PressableHandler(FlexContainerHandler):
2425
2432
  try:
2426
2433
  view.animate().alpha(opacity).setDuration(50).start()
2427
2434
  except Exception:
2428
- pass
2435
+ diagnostics.swallowed(
2436
+ "android.PressableHandler._bind_press_stream._PressTouchProxy.onTouch"
2437
+ )
2429
2438
  if _has_event(view, "on_long_press"):
2430
2439
  seq = press["seq"]
2431
2440
 
@@ -2456,7 +2465,9 @@ class PressableHandler(FlexContainerHandler):
2456
2465
  try:
2457
2466
  view.animate().alpha(1.0).setDuration(100).start()
2458
2467
  except Exception:
2459
- pass
2468
+ diagnostics.swallowed(
2469
+ "android.PressableHandler._bind_press_stream._PressTouchProxy.onTouch"
2470
+ )
2460
2471
  if action == 1 and not press["moved"] and not press["long_fired"]:
2461
2472
  _fire(view, "on_press")
2462
2473
  return True
@@ -2464,7 +2475,7 @@ class PressableHandler(FlexContainerHandler):
2464
2475
 
2465
2476
  fl.setOnTouchListener(_PressTouchProxy())
2466
2477
  except Exception:
2467
- pass
2478
+ diagnostics.swallowed("android.PressableHandler._bind_press_stream")
2468
2479
 
2469
2480
 
2470
2481
  # ======================================================================
@@ -2491,20 +2502,29 @@ class StatusBarHandler(AndroidViewHandler):
2491
2502
  return
2492
2503
  if "background_color" in props and props["background_color"] is not None:
2493
2504
  window.setStatusBarColor(parse_color_int(props["background_color"]))
2505
+ View = jclass("android.view.View")
2506
+ decor = window.getDecorView()
2494
2507
  if "bar_style" in props and props["bar_style"] is not None:
2495
2508
  # API 23+: setSystemUiVisibility with SYSTEM_UI_FLAG_LIGHT_STATUS_BAR
2496
2509
  # for dark-content (light backgrounds), 0 for light-content.
2497
- View = jclass("android.view.View")
2498
2510
  bar_style = props["bar_style"]
2499
- decor = window.getDecorView()
2500
2511
  flags = decor.getSystemUiVisibility()
2501
2512
  if bar_style in ("dark", "default"):
2502
2513
  flags |= View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR
2503
2514
  else:
2504
2515
  flags &= ~View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR
2505
2516
  decor.setSystemUiVisibility(flags)
2506
- except Exception:
2507
- pass
2517
+ if "hidden" in props and props["hidden"] is not None:
2518
+ flags = decor.getSystemUiVisibility()
2519
+ if props["hidden"]:
2520
+ flags |= View.SYSTEM_UI_FLAG_FULLSCREEN
2521
+ else:
2522
+ flags &= ~View.SYSTEM_UI_FLAG_FULLSCREEN
2523
+ decor.setSystemUiVisibility(flags)
2524
+ except Exception as exc:
2525
+ from .. import diagnostics
2526
+
2527
+ diagnostics.warn_once(f"StatusBar: could not apply props on Android: {exc!r}")
2508
2528
 
2509
2529
 
2510
2530
  class KeyboardAvoidingViewHandler(FlexContainerHandler):
@@ -2552,7 +2572,7 @@ def _present_alert(
2552
2572
  try:
2553
2573
  on_result(index)
2554
2574
  except Exception:
2555
- pass
2575
+ diagnostics.swallowed("android._present_alert._deliver")
2556
2576
 
2557
2577
  def _present_on_main() -> None:
2558
2578
  try:
@@ -2738,7 +2758,7 @@ class CheckboxHandler(AndroidViewHandler):
2738
2758
  ColorStateList = jclass("android.content.res.ColorStateList")
2739
2759
  cb.setButtonTintList(ColorStateList.valueOf(parse_color_int(props["color"])))
2740
2760
  except Exception:
2741
- pass
2761
+ diagnostics.swallowed("android.CheckboxHandler._apply")
2742
2762
  _apply_accessibility(cb, props)
2743
2763
 
2744
2764
 
@@ -2798,7 +2818,7 @@ class SegmentedControlHandler(AndroidViewHandler):
2798
2818
  try:
2799
2819
  ll.removeAllViews()
2800
2820
  except Exception:
2801
- pass
2821
+ diagnostics.swallowed("android.SegmentedControlHandler._rebuild")
2802
2822
  state["buttons"] = []
2803
2823
  LL_LP = jclass("android.widget.LinearLayout$LayoutParams")
2804
2824
  restyle = self._restyle
@@ -2808,7 +2828,7 @@ class SegmentedControlHandler(AndroidViewHandler):
2808
2828
  try:
2809
2829
  btn.setAllCaps(False)
2810
2830
  except Exception:
2811
- pass
2831
+ diagnostics.swallowed("android.SegmentedControlHandler._rebuild")
2812
2832
  # Equal-width segments: zero base width + weight 1, full height.
2813
2833
  btn.setLayoutParams(LL_LP(0, LL_LP.MATCH_PARENT, 1.0))
2814
2834
  enabled = (state.get("props") or {}).get("enabled") is not False
@@ -2856,7 +2876,7 @@ class SegmentedControlHandler(AndroidViewHandler):
2856
2876
  btn.setBackground(drawable)
2857
2877
  btn.setEnabled(enabled)
2858
2878
  except Exception:
2859
- pass
2879
+ diagnostics.swallowed("android.SegmentedControlHandler._style_segment")
2860
2880
 
2861
2881
  def measure_intrinsic(
2862
2882
  self,
@@ -2911,7 +2931,7 @@ class DatePickerHandler(AndroidViewHandler):
2911
2931
  try:
2912
2932
  btn.setAllCaps(False)
2913
2933
  except Exception:
2914
- pass
2934
+ diagnostics.swallowed("android.DatePickerHandler._build")
2915
2935
  open_dialog = self._open_dialog
2916
2936
 
2917
2937
  class _DateTriggerProxy(dynamic_proxy(jclass("android.view.View").OnClickListener)):
@@ -3021,7 +3041,7 @@ class DatePickerHandler(AndroidViewHandler):
3021
3041
  if maximum:
3022
3042
  picker.setMaxDate(self._parse_to_calendar(maximum, mode).getTimeInMillis())
3023
3043
  except Exception:
3024
- pass
3044
+ diagnostics.swallowed("android.DatePickerHandler._apply_min_max")
3025
3045
 
3026
3046
  def _parse_to_calendar(self, value: Any, mode: str) -> Any:
3027
3047
  Calendar = jclass("java.util.Calendar")
@@ -3033,7 +3053,7 @@ class DatePickerHandler(AndroidViewHandler):
3033
3053
  fmt = SimpleDateFormat(self._PATTERNS.get(mode, self._PATTERNS["date"]), Locale.US)
3034
3054
  cal.setTime(fmt.parse(str(value)))
3035
3055
  except Exception:
3036
- pass
3056
+ diagnostics.swallowed("android.DatePickerHandler._parse_to_calendar")
3037
3057
  return cal
3038
3058
 
3039
3059
  def _format_calendar(self, cal: Any, mode: str) -> str:
@@ -3053,7 +3073,7 @@ class DatePickerHandler(AndroidViewHandler):
3053
3073
  try:
3054
3074
  btn.setText(iso)
3055
3075
  except Exception:
3056
- pass
3076
+ diagnostics.swallowed("android.DatePickerHandler._commit")
3057
3077
  _fire(btn, "on_change", iso)
3058
3078
 
3059
3079
 
@@ -3153,7 +3173,7 @@ class VirtualListHandler(AndroidViewHandler):
3153
3173
  try:
3154
3174
  info["pool"].release(_java_id(container))
3155
3175
  except Exception:
3156
- pass
3176
+ diagnostics.swallowed("android.VirtualListHandler._build._Delegate.onRowRecycled")
3157
3177
 
3158
3178
  def onScrolled(self, offset_dp: float, extent_dp: float, range_dp: float) -> None:
3159
3179
  view = info.get("view")
@@ -3202,12 +3222,12 @@ class VirtualListHandler(AndroidViewHandler):
3202
3222
  try:
3203
3223
  view.setVerticalScrollBarEnabled(show)
3204
3224
  except Exception:
3205
- pass
3225
+ diagnostics.swallowed("android.VirtualListHandler._apply")
3206
3226
  if data_changed and not initial:
3207
3227
  try:
3208
3228
  view.notifyDataChanged()
3209
3229
  except Exception:
3210
- pass
3230
+ diagnostics.swallowed("android.VirtualListHandler._apply")
3211
3231
 
3212
3232
  def _teardown(self, native_view: Any) -> None:
3213
3233
  info = _pn_vlist_info.pop(_java_id(native_view), None)
@@ -3238,7 +3258,7 @@ class VirtualListHandler(AndroidViewHandler):
3238
3258
  args.get("animated", True) is not False,
3239
3259
  )
3240
3260
  except Exception:
3241
- pass
3261
+ diagnostics.swallowed("android.VirtualListHandler.command")
3242
3262
  return None
3243
3263
  if name == "scroll_to_index":
3244
3264
  try:
@@ -3247,7 +3267,7 @@ class VirtualListHandler(AndroidViewHandler):
3247
3267
  args.get("animated", True) is not False,
3248
3268
  )
3249
3269
  except Exception:
3250
- pass
3270
+ diagnostics.swallowed("android.VirtualListHandler.command")
3251
3271
  return None
3252
3272
  if name == "scroll_to_end":
3253
3273
  info = _pn_vlist_info.get(_java_id(native_view))
@@ -3255,7 +3275,7 @@ class VirtualListHandler(AndroidViewHandler):
3255
3275
  try:
3256
3276
  native_view.scrollToIndex(max(0, count - 1), args.get("animated", True) is not False)
3257
3277
  except Exception:
3258
- pass
3278
+ diagnostics.swallowed("android.VirtualListHandler.command")
3259
3279
  return None
3260
3280
  if name == "get_scroll_offset":
3261
3281
  try: