@goliapkg/sentori-react-native 1.0.0-rc.1 → 1.0.0-rc.2

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.
@@ -0,0 +1,145 @@
1
+ package com.sentori
2
+
3
+ import android.app.Activity
4
+ import android.app.Application
5
+ import android.os.Bundle
6
+ import java.lang.ref.WeakReference
7
+
8
+ /**
9
+ * v1.0.0-rc.2 — process-wide foreground-Activity tracker.
10
+ *
11
+ * Both [SentoriScreenshotCapture] and [SentoriReplayCapture] need a
12
+ * pointer to the currently-foregrounded Activity to drive their
13
+ * native captures. The previous implementation registered each
14
+ * helper's own `ActivityLifecycleCallbacks` inside
15
+ * [SentoriCrashHandler.register], which runs from the Expo module's
16
+ * `OnCreate` lifecycle — **after** the MainActivity has already been
17
+ * resumed in the typical Insight / Expo dev-launcher topology.
18
+ * `ActivityLifecycleCallbacks` does not back-fill the current state,
19
+ * it only forwards future events, so `lastActivity` would stay null
20
+ * for the entire session if the user never backgrounded the app.
21
+ *
22
+ * Fix mirrors the iOS keyWindow 4-layer fallback:
23
+ *
24
+ * 1. Lifecycle callbacks track resumed/started activities going
25
+ * forward (the same approach as before, kept).
26
+ * 2. **On first install** we also probe `ActivityThread` reflection
27
+ * to back-fill whatever Activity is currently foreground, so the
28
+ * already-resumed window is seen by the SDK from boot.
29
+ * 3. If reflection fails (e.g. on a future Android release that
30
+ * removes `ActivityThread` access), the lifecycle callbacks
31
+ * still catch the next foreground transition.
32
+ *
33
+ * `lastPath` carries the diagnostic provenance for `probeWireframe` /
34
+ * `probeScreenshot`, so the JS side (and Insight) can tell whether
35
+ * the SDK was working off a live lifecycle event or fell back to
36
+ * reflection.
37
+ */
38
+ object SentoriForegroundActivity {
39
+
40
+ @Volatile private var lastActivity: WeakReference<Activity>? = null
41
+ @Volatile var lastPath: String = "none(not-yet-resolved)"
42
+ private set
43
+
44
+ /** Idempotent. Call from [SentoriCrashHandler.register]; subsequent
45
+ * calls are no-ops because the same callbacks object would be
46
+ * registered twice otherwise. */
47
+ @Volatile private var registered = false
48
+
49
+ @Synchronized
50
+ fun install(application: Application) {
51
+ if (registered) {
52
+ // Even on second install attempt, try the reflection
53
+ // back-fill again — process state may have advanced.
54
+ backfillFromActivityThread()
55
+ return
56
+ }
57
+ registered = true
58
+ application.registerActivityLifecycleCallbacks(object :
59
+ Application.ActivityLifecycleCallbacks {
60
+ override fun onActivityCreated(a: Activity, b: Bundle?) {
61
+ set(a, "lifecycle.created")
62
+ }
63
+ override fun onActivityStarted(a: Activity) {
64
+ set(a, "lifecycle.started")
65
+ }
66
+ override fun onActivityResumed(a: Activity) {
67
+ set(a, "lifecycle.resumed")
68
+ }
69
+ override fun onActivityPaused(a: Activity) {}
70
+ override fun onActivityStopped(a: Activity) {}
71
+ override fun onActivitySaveInstanceState(a: Activity, b: Bundle) {}
72
+ override fun onActivityDestroyed(a: Activity) {}
73
+ })
74
+ // Back-fill in case the Activity was already resumed before
75
+ // we got installed (the dev-launcher → MainActivity transition
76
+ // happens before the Expo module's OnCreate fires).
77
+ backfillFromActivityThread()
78
+ }
79
+
80
+ /** Public for tests + the helpers' own explicit `setActivity`
81
+ * paths (kept for backwards-compat). */
82
+ fun set(activity: Activity, source: String) {
83
+ lastActivity = WeakReference(activity)
84
+ lastPath = source
85
+ }
86
+
87
+ fun current(): Activity? {
88
+ val live = lastActivity?.get()
89
+ if (live != null) return live
90
+ // Last-ditch: try reflection again in case install() ran before
91
+ // any Activity existed. Cheap if it fails.
92
+ backfillFromActivityThread()
93
+ return lastActivity?.get()
94
+ }
95
+
96
+ /**
97
+ * Best-effort foreground-Activity lookup using non-SDK reflection.
98
+ * Walks `ActivityThread.sCurrentActivityThread.mActivities` (an
99
+ * `ArrayMap<IBinder, ActivityClientRecord>`) and finds the record
100
+ * whose `paused` field is false. This is what Stetho / LeakCanary
101
+ * / Firebase Performance do, with the same caveat that future
102
+ * Android versions may break it — failures are silent and the
103
+ * lifecycle-callbacks path still wins.
104
+ *
105
+ * Tagged via `lastPath = "reflection.activityThread"` so the JS
106
+ * probe can see when reflection had to step in.
107
+ */
108
+ @Suppress("PrivateApi", "UNCHECKED_CAST")
109
+ private fun backfillFromActivityThread() {
110
+ try {
111
+ val activityThreadClass = Class.forName("android.app.ActivityThread")
112
+ val currentActivityThread = activityThreadClass
113
+ .getDeclaredMethod("currentActivityThread")
114
+ .also { it.isAccessible = true }
115
+ .invoke(null) ?: return
116
+ val activitiesField = activityThreadClass
117
+ .getDeclaredField("mActivities")
118
+ .also { it.isAccessible = true }
119
+ val activities = activitiesField.get(currentActivityThread) ?: return
120
+
121
+ // ArrayMap<IBinder, ActivityClientRecord> — iterate via reflection
122
+ // so we don't have to depend on the (also private) ArrayMap shape.
123
+ val valuesIter = (activities as? Map<*, *>)?.values?.iterator() ?: return
124
+ while (valuesIter.hasNext()) {
125
+ val record = valuesIter.next() ?: continue
126
+ val recordClass = record.javaClass
127
+ val pausedField = try {
128
+ recordClass.getDeclaredField("paused").also { it.isAccessible = true }
129
+ } catch (_: NoSuchFieldException) { null }
130
+ val activityField = try {
131
+ recordClass.getDeclaredField("activity").also { it.isAccessible = true }
132
+ } catch (_: NoSuchFieldException) { null } ?: continue
133
+ val paused = pausedField?.getBoolean(record) ?: false
134
+ val candidate = activityField.get(record) as? Activity ?: continue
135
+ if (!paused && !candidate.isFinishing && !candidate.isDestroyed) {
136
+ set(candidate, "reflection.activityThread")
137
+ return
138
+ }
139
+ }
140
+ } catch (_: Throwable) {
141
+ // Reflection unavailable; the lifecycle-callbacks path
142
+ // will still catch the next foreground transition.
143
+ }
144
+ }
145
+ }
@@ -39,6 +39,14 @@ class SentoriModule : Module() {
39
39
  SentoriReplayCapture.probe()
40
40
  }
41
41
 
42
+ // v1.0.0-rc.2 — diagnostic readout for screenshot. Surfaces
43
+ // foreground-Activity provenance, decor-view state, and the
44
+ // last failure reason so the JS side can ship raw state back
45
+ // when screenshot returns null.
46
+ Function("probeScreenshot") {
47
+ SentoriScreenshotCapture.probe()
48
+ }
49
+
42
50
  // v0.9.4 #1 — Mobile Vitals exposure.
43
51
  Function("markJsBridgeReady") {
44
52
  SentoriMobileVitals.markJsBridgeReady()
@@ -9,7 +9,6 @@ import android.widget.ImageView
9
9
  import android.widget.TextView
10
10
  import org.json.JSONArray
11
11
  import org.json.JSONObject
12
- import java.lang.ref.WeakReference
13
12
 
14
13
  /**
15
14
  * v0.9.6 #2 — wireframe session replay (Android side).
@@ -27,8 +26,6 @@ object SentoriReplayCapture {
27
26
 
28
27
  private const val MAX_NODES = 800
29
28
 
30
- @Volatile private var lastActivity: WeakReference<Activity>? = null
31
-
32
29
  // v0.9.12 — diagnostic readout so the JS side can ask "why is the
33
30
  // ring empty?" without parsing logcat. Mirrors the iOS side.
34
31
  @Volatile private var lastDiagPath: String = "none(not-yet-called)"
@@ -36,39 +33,35 @@ object SentoriReplayCapture {
36
33
 
37
34
  @JvmStatic
38
35
  fun probe(): Map<String, Any> {
39
- val activity = lastActivity?.get()
36
+ val activity = SentoriForegroundActivity.current()
40
37
  return mapOf(
41
38
  "lastPath" to lastDiagPath,
42
39
  "lastNodes" to lastDiagNodes,
43
- "sceneCount" to if (activity != null) 1 else 0,
44
- "windowCount" to (activity?.window?.let { 1 } ?: 0),
40
+ "trackedSource" to SentoriForegroundActivity.lastPath,
41
+ "trackedActivity" to (activity?.javaClass?.name ?: "null"),
42
+ "decorViewFound" to (activity?.window?.decorView != null),
45
43
  )
46
44
  }
47
45
 
46
+ /** Backwards compat — pre-rc.2 callers that hand-fed an Activity
47
+ * through `setActivity` still work; we forward to the shared
48
+ * tracker so screenshot + replay both see it. */
48
49
  @JvmStatic
49
50
  fun setActivity(activity: Activity?) {
50
- lastActivity = activity?.let { WeakReference(it) }
51
+ if (activity != null) SentoriForegroundActivity.set(activity, "manual.setActivity")
51
52
  }
52
53
 
53
- /** Attach an ActivityLifecycleCallbacks so future
54
- * `captureWireframe()` calls know which Activity to walk. */
54
+ /** Idempotent. Wires the replay helper into the shared tracker;
55
+ * kept as a public entrypoint for backwards compat with existing
56
+ * call sites. */
55
57
  @JvmStatic
56
58
  fun register(application: android.app.Application) {
57
- application.registerActivityLifecycleCallbacks(object :
58
- android.app.Application.ActivityLifecycleCallbacks {
59
- override fun onActivityCreated(a: Activity, b: android.os.Bundle?) { setActivity(a) }
60
- override fun onActivityStarted(a: Activity) { setActivity(a) }
61
- override fun onActivityResumed(a: Activity) { setActivity(a) }
62
- override fun onActivityPaused(a: Activity) {}
63
- override fun onActivityStopped(a: Activity) {}
64
- override fun onActivitySaveInstanceState(a: Activity, b: android.os.Bundle) {}
65
- override fun onActivityDestroyed(a: Activity) {}
66
- })
59
+ SentoriForegroundActivity.install(application)
67
60
  }
68
61
 
69
62
  @JvmStatic
70
63
  fun captureWireframe(maskedIds: List<String>): String? {
71
- val activity = lastActivity?.get()
64
+ val activity = SentoriForegroundActivity.current()
72
65
  if (activity == null) {
73
66
  lastDiagPath = "activity.null"
74
67
  return null
@@ -89,7 +82,7 @@ object SentoriReplayCapture {
89
82
  val rootLoc = IntArray(2).also { root.getLocationInWindow(it) }
90
83
  walk(root, false, maskedSet, rootLoc, rect, nodes)
91
84
 
92
- lastDiagPath = "activity.resumed"
85
+ lastDiagPath = "ok(${SentoriForegroundActivity.lastPath})"
93
86
  lastDiagNodes = nodes.length()
94
87
 
95
88
  val payload = JSONObject().apply {
@@ -1,13 +1,11 @@
1
1
  package com.sentori
2
2
 
3
- import android.app.Activity
4
3
  import android.app.Application
5
4
  import android.graphics.Bitmap
6
5
  import android.graphics.Canvas
7
6
  import android.graphics.Color
8
7
  import android.graphics.Paint
9
8
  import android.os.Build
10
- import android.os.Bundle
11
9
  import android.os.Handler
12
10
  import android.os.HandlerThread
13
11
  import android.util.Base64
@@ -16,7 +14,6 @@ import android.view.View
16
14
  import android.view.ViewGroup
17
15
  import android.view.Window
18
16
  import java.io.ByteArrayOutputStream
19
- import java.lang.ref.WeakReference
20
17
  import java.util.concurrent.CountDownLatch
21
18
  import java.util.concurrent.TimeUnit
22
19
  import org.json.JSONArray
@@ -60,36 +57,44 @@ object SentoriScreenshotCapture {
60
57
  private const val MAX_NODES = 1500
61
58
  private const val PIXEL_COPY_TIMEOUT_MS = 200L
62
59
 
63
- /// Latest activity we've seen via `ActivityLifecycleCallbacks`
64
- /// used to find the window to screenshot when neither the JS
65
- /// side (which knows of `Activity.this` via React Native) nor
66
- /// the crash handler hands one to us.
67
- @Volatile private var lastActivity: WeakReference<Activity>? = null
60
+ // v1.0.0-rc.2 diagnostic readout so the JS side can ask
61
+ // "why did screenshot return null" without parsing logcat. Mirrors
62
+ // SentoriReplayCapture.probe() and the iOS Swift probe.
63
+ @Volatile private var lastDiagPath: String = "none(not-yet-called)"
64
+ @Volatile private var lastDiagW: Int = 0
65
+ @Volatile private var lastDiagH: Int = 0
68
66
 
69
67
  /**
70
- * Attach an `ActivityLifecycleCallbacks` so subsequent
71
- * `captureScreen()` calls know which Activity (and therefore
72
- * Window) to target. Idempotent; call from
73
- * `SentoriCrashHandler.register(context)`.
68
+ * Snapshot of the most recent capture attempt — what code path
69
+ * resolved an Activity, what the decor view's dimensions were,
70
+ * and what call source the foreground tracker last saw the
71
+ * Activity from. Used by `probeNativeScreenshot()` on the JS
72
+ * side so Insight can ship raw diagnostic state back without
73
+ * needing logcat access.
74
+ */
75
+ @JvmStatic
76
+ fun probe(): Map<String, Any> {
77
+ val tracked = SentoriForegroundActivity.current()
78
+ return mapOf(
79
+ "lastPath" to lastDiagPath,
80
+ "lastWidth" to lastDiagW,
81
+ "lastHeight" to lastDiagH,
82
+ "trackedSource" to SentoriForegroundActivity.lastPath,
83
+ "trackedActivity" to (tracked?.javaClass?.name ?: "null"),
84
+ "decorViewFound" to (tracked?.window?.decorView != null),
85
+ )
86
+ }
87
+
88
+ /**
89
+ * Idempotent. Wires the screenshot helper into the shared
90
+ * foreground-activity tracker; kept as a public entrypoint for
91
+ * backwards compat with existing call sites (the crash handler
92
+ * still calls this), but the actual lifecycle subscription lives
93
+ * in [SentoriForegroundActivity].
74
94
  */
75
95
  @JvmStatic
76
96
  fun register(application: Application) {
77
- application.registerActivityLifecycleCallbacks(object :
78
- Application.ActivityLifecycleCallbacks {
79
- override fun onActivityCreated(a: Activity, b: Bundle?) {
80
- lastActivity = WeakReference(a)
81
- }
82
- override fun onActivityStarted(a: Activity) {
83
- lastActivity = WeakReference(a)
84
- }
85
- override fun onActivityResumed(a: Activity) {
86
- lastActivity = WeakReference(a)
87
- }
88
- override fun onActivityPaused(a: Activity) {}
89
- override fun onActivityStopped(a: Activity) {}
90
- override fun onActivitySaveInstanceState(a: Activity, b: Bundle) {}
91
- override fun onActivityDestroyed(a: Activity) {}
92
- })
97
+ SentoriForegroundActivity.install(application)
93
98
  }
94
99
 
95
100
  /**
@@ -102,8 +107,16 @@ object SentoriScreenshotCapture {
102
107
  */
103
108
  @JvmStatic
104
109
  fun captureKeyWindow(): Map<String, Any>? {
105
- val activity = lastActivity?.get() ?: return null
106
- val window = activity.window ?: return null
110
+ val activity = SentoriForegroundActivity.current()
111
+ if (activity == null) {
112
+ lastDiagPath = "activity.null"
113
+ return null
114
+ }
115
+ val window = activity.window
116
+ if (window == null) {
117
+ lastDiagPath = "window.null"
118
+ return null
119
+ }
107
120
  val out = mutableMapOf<String, Any>()
108
121
  captureScreen(window, emptySet())?.let { (base64, mediaType) ->
109
122
  out["screenshot"] = mapOf("base64" to base64, "mediaType" to mediaType)
@@ -120,8 +133,16 @@ object SentoriScreenshotCapture {
120
133
  /// masked subview's frame on the captured bitmap.
121
134
  @JvmStatic
122
135
  fun captureScreenshotWithMask(maskedIds: List<String>): Map<String, String>? {
123
- val activity = lastActivity?.get() ?: return null
124
- val window = activity.window ?: return null
136
+ val activity = SentoriForegroundActivity.current()
137
+ if (activity == null) {
138
+ lastDiagPath = "activity.null"
139
+ return null
140
+ }
141
+ val window = activity.window
142
+ if (window == null) {
143
+ lastDiagPath = "window.null"
144
+ return null
145
+ }
125
146
  val (base64, mediaType) = captureScreen(window, maskedIds.toHashSet()) ?: return null
126
147
  return mapOf("base64" to base64, "mediaType" to mediaType)
127
148
  }
@@ -135,12 +156,22 @@ object SentoriScreenshotCapture {
135
156
  // requires the activity not to be torn down. Skip for
136
157
  // now; v0.6.1 SDK can add the fallback if real-world
137
158
  // data shows we have users below API 24.
159
+ lastDiagPath = "api.unsupported"
160
+ return null
161
+ }
162
+ val decor = window.decorView
163
+ if (decor == null) {
164
+ lastDiagPath = "decorView.null"
138
165
  return null
139
166
  }
140
- val decor = window.decorView ?: return null
141
167
  val w = decor.width
142
168
  val h = decor.height
143
- if (w <= 0 || h <= 0) return null
169
+ lastDiagW = w
170
+ lastDiagH = h
171
+ if (w <= 0 || h <= 0) {
172
+ lastDiagPath = "decorView.zero-size"
173
+ return null
174
+ }
144
175
 
145
176
  // Long-edge scale.
146
177
  val longEdge = maxOf(w, h).toFloat()
@@ -175,12 +206,17 @@ object SentoriScreenshotCapture {
175
206
  )
176
207
  }
177
208
  latch.await(PIXEL_COPY_TIMEOUT_MS, TimeUnit.MILLISECONDS)
178
- } catch (_: Throwable) {
209
+ } catch (t: Throwable) {
210
+ lastDiagPath = "pixelCopy.threw:${t.javaClass.simpleName}"
179
211
  return null
180
212
  } finally {
181
213
  handlerThread.quitSafely()
182
214
  }
183
- if (!success) return null
215
+ if (!success) {
216
+ lastDiagPath = "pixelCopy.notSuccess"
217
+ return null
218
+ }
219
+ lastDiagPath = "ok"
184
220
 
185
221
  // v0.7.3 — paint black rectangles over masked subviews on the
186
222
  // already-captured bitmap. We get window-relative coordinates
@@ -38,6 +38,13 @@ public class SentoriModule: Module {
38
38
  return SentoriReplayCapture.probe()
39
39
  }
40
40
 
41
+ // v1.0.0-rc.2 — diagnostic readout for screenshot. Same shape
42
+ // as Android side; lets Insight ship raw state back when the
43
+ // captureScreenshot path returns null.
44
+ Function("probeScreenshot") { () -> [String: Any] in
45
+ return SentoriScreenshotCapture.probe()
46
+ }
47
+
41
48
  // v0.9.4 #1 — Mobile Vitals exposure.
42
49
  Function("markJsBridgeReady") {
43
50
  SentoriMobileVitals.markJsBridgeReady()
@@ -82,10 +82,15 @@ import UIKit
82
82
  }
83
83
 
84
84
  private static func captureWithMaskSync(maskedIds: [String]) -> [String: String]? {
85
- guard let window = keyWindow() else { return nil }
85
+ guard let window = keyWindowDiag().window else {
86
+ lastDiagPath = "window.null"
87
+ return nil
88
+ }
86
89
  guard let jpeg = renderJpegBase64(window: window, maskedIds: Set(maskedIds)) else {
90
+ lastDiagPath = "render.failed"
87
91
  return nil
88
92
  }
93
+ lastDiagPath = "ok"
89
94
  return [
90
95
  "base64": jpeg,
91
96
  "mediaType": "image/jpeg",
@@ -94,8 +99,28 @@ import UIKit
94
99
 
95
100
  // MARK: - Internals
96
101
 
102
+ // v1.0.0-rc.2 — diagnostic readout mirror of the replay-capture
103
+ // probe. The JS side calls `probeScreenshot()` to ship raw state
104
+ // back when screenshot returns null.
105
+ private static var lastDiagPath: String = "none(not-yet-called)"
106
+
107
+ @objc public static func probe() -> [String: Any] {
108
+ let (win, path) = keyWindowDiag()
109
+ return [
110
+ "lastPath": lastDiagPath,
111
+ "resolvedPath": path,
112
+ "windowFound": win != nil,
113
+ "rootViewControllerFound": win?.rootViewController != nil,
114
+ "boundsW": win.map { Double($0.bounds.width) } ?? 0.0,
115
+ "boundsH": win.map { Double($0.bounds.height) } ?? 0.0,
116
+ ]
117
+ }
118
+
97
119
  private static func captureSync() -> [String: Any]? {
98
- guard let window = keyWindow() else { return nil }
120
+ guard let window = keyWindowDiag().window else {
121
+ lastDiagPath = "window.null"
122
+ return nil
123
+ }
99
124
  var out: [String: Any] = [:]
100
125
  if let jpeg = renderJpegBase64(window: window) {
101
126
  out["screenshot"] = [
@@ -104,7 +129,48 @@ import UIKit
104
129
  ]
105
130
  }
106
131
  out["viewTree"] = walkTree(root: window)
107
- return out.isEmpty ? nil : out
132
+ if out.isEmpty {
133
+ lastDiagPath = "empty"
134
+ return nil
135
+ }
136
+ lastDiagPath = "ok"
137
+ return out
138
+ }
139
+
140
+ /// keyWindow with the same 4-tier resolution as the replay capture,
141
+ /// plus the diagnostic path tag for the probe. The original
142
+ /// single-pass `keyWindow()` is kept for source-compat callers but
143
+ /// new paths funnel through this so screenshot + replay agree on
144
+ /// which window they are pointing at.
145
+ private static func keyWindowDiag() -> (window: UIWindow?, path: String) {
146
+ if #available(iOS 13.0, *) {
147
+ let scenes = Array(UIApplication.shared.connectedScenes)
148
+ for scene in scenes where scene.activationState == .foregroundActive {
149
+ if let ws = scene as? UIWindowScene,
150
+ let key = ws.windows.first(where: { $0.isKeyWindow }) {
151
+ return (key, "scene.fg.key")
152
+ }
153
+ }
154
+ for scene in scenes where scene.activationState == .foregroundActive {
155
+ if let ws = scene as? UIWindowScene, let win = ws.windows.first {
156
+ return (win, "scene.fg.first")
157
+ }
158
+ }
159
+ for scene in scenes where scene.activationState == .foregroundInactive {
160
+ if let ws = scene as? UIWindowScene, let win = ws.windows.first {
161
+ return (win, "scene.fgi.first")
162
+ }
163
+ }
164
+ for scene in scenes {
165
+ if let ws = scene as? UIWindowScene, let win = ws.windows.first {
166
+ return (win, "scene.any.first")
167
+ }
168
+ }
169
+ }
170
+ if let leg = UIApplication.shared.windows.first {
171
+ return (leg, "legacy.first")
172
+ }
173
+ return (nil, "none")
108
174
  }
109
175
 
110
176
  private static func keyWindow() -> UIWindow? {
package/lib/index.d.ts CHANGED
@@ -61,7 +61,7 @@ export { getColdStartMs, markTimeToFullDisplay, type TimeToFullDisplayHandle, }
61
61
  export { MomentHandle, type MomentProperties, startMoment } from '@goliapkg/sentori-core';
62
62
  export { bindState, recordState, type StateSnapshot, unbindState, } from './state-snapshots';
63
63
  export { RageTapCapture } from './rage-tap';
64
- export { probeNativeWireframe, startAnrWatchdog, stopAnrWatchdog, triggerNativeCrash, } from './native';
64
+ export { probeNativeScreenshot, probeNativeWireframe, startAnrWatchdog, stopAnrWatchdog, triggerNativeCrash, } from './native';
65
65
  export { drainReplay, startReplay, stopReplay } from './replay';
66
66
  export { endSession, markSessionCrashed, startSession, } from './session-tracker';
67
67
  export { type NavigationRefLike, useTraceNavigation } from './navigation';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,EAAkB,KAAK,oBAAoB,EAAE,KAAK,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAOxG,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,QAAQ,CAAC;AAC3D,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EACL,cAAc,EACd,qBAAqB,EAEtB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACxE,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AACrD,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AACvD,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAO5C,eAAO,MAAM,OAAO;;;;;;;;;;aAgGsR,CAAC;eAAmB,CAAC;YAAgB,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;CAlE/U,CAAC;AAEF,eAAe,OAAO,CAAC;AAEvB,OAAO,EAAE,IAAI,EAAE,IAAI,IAAI,WAAW,EAAE,MAAM,QAAQ,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAC9C,OAAO,EACL,YAAY,EACZ,gBAAgB,EAChB,WAAW,EACX,OAAO,EACP,gBAAgB,EAChB,OAAO,GACR,MAAM,WAAW,CAAC;AACnB,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,EAAE,cAAc,EAAE,KAAK,oBAAoB,EAAE,KAAK,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AACxG,OAAO,EACL,oBAAoB,EACpB,gBAAgB,EAChB,eAAe,EACf,cAAc,GACf,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,QAAQ,CAAC;AAC3D,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AACvD,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EACL,cAAc,EACd,qBAAqB,EACrB,KAAK,uBAAuB,GAC7B,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,YAAY,EAAE,KAAK,gBAAgB,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAC1F,OAAO,EACL,SAAS,EACT,WAAW,EACX,KAAK,aAAa,EAClB,WAAW,GACZ,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,EACL,oBAAoB,EACpB,gBAAgB,EAChB,eAAe,EACf,kBAAkB,GACnB,MAAM,UAAU,CAAC;AAClB,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAChE,OAAO,EACL,UAAU,EACV,kBAAkB,EAClB,YAAY,GACb,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,KAAK,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAE1E,YAAY,EACV,KAAK,EACL,YAAY,EACZ,KAAK,EACL,UAAU,EACV,cAAc,EACd,MAAM,EACN,QAAQ,EACR,GAAG,EACH,IAAI,EACJ,IAAI,EACJ,SAAS,EACT,QAAQ,GACT,MAAM,SAAS,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,EAAkB,KAAK,oBAAoB,EAAE,KAAK,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAOxG,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,QAAQ,CAAC;AAC3D,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EACL,cAAc,EACd,qBAAqB,EAEtB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACxE,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AACrD,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AACvD,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAO5C,eAAO,MAAM,OAAO;;;;;;;;;;aAiG6P,CAAC;eAAmB,CAAC;YAAgB,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;CAnEtT,CAAC;AAEF,eAAe,OAAO,CAAC;AAEvB,OAAO,EAAE,IAAI,EAAE,IAAI,IAAI,WAAW,EAAE,MAAM,QAAQ,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAC9C,OAAO,EACL,YAAY,EACZ,gBAAgB,EAChB,WAAW,EACX,OAAO,EACP,gBAAgB,EAChB,OAAO,GACR,MAAM,WAAW,CAAC;AACnB,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,EAAE,cAAc,EAAE,KAAK,oBAAoB,EAAE,KAAK,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AACxG,OAAO,EACL,oBAAoB,EACpB,gBAAgB,EAChB,eAAe,EACf,cAAc,GACf,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,QAAQ,CAAC;AAC3D,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AACvD,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EACL,cAAc,EACd,qBAAqB,EACrB,KAAK,uBAAuB,GAC7B,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,YAAY,EAAE,KAAK,gBAAgB,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAC1F,OAAO,EACL,SAAS,EACT,WAAW,EACX,KAAK,aAAa,EAClB,WAAW,GACZ,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,EACL,qBAAqB,EACrB,oBAAoB,EACpB,gBAAgB,EAChB,eAAe,EACf,kBAAkB,GACnB,MAAM,UAAU,CAAC;AAClB,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAChE,OAAO,EACL,UAAU,EACV,kBAAkB,EAClB,YAAY,GACb,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,KAAK,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAE1E,YAAY,EACV,KAAK,EACL,YAAY,EACZ,KAAK,EACL,UAAU,EACV,cAAc,EACd,MAAM,EACN,QAAQ,EACR,GAAG,EACH,IAAI,EACJ,IAAI,EACJ,SAAS,EACT,QAAQ,GACT,MAAM,SAAS,CAAC"}
package/lib/index.js CHANGED
@@ -57,7 +57,7 @@ export { getColdStartMs, markTimeToFullDisplay, } from './mobile-vitals';
57
57
  export { MomentHandle, startMoment } from '@goliapkg/sentori-core';
58
58
  export { bindState, recordState, unbindState, } from './state-snapshots';
59
59
  export { RageTapCapture } from './rage-tap';
60
- export { probeNativeWireframe, startAnrWatchdog, stopAnrWatchdog, triggerNativeCrash, } from './native';
60
+ export { probeNativeScreenshot, probeNativeWireframe, startAnrWatchdog, stopAnrWatchdog, triggerNativeCrash, } from './native';
61
61
  export { drainReplay, startReplay, stopReplay } from './replay';
62
62
  export { endSession, markSessionCrashed, startSession, } from './session-tracker';
63
63
  export { useTraceNavigation } from './navigation';
package/lib/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/lib/native.d.ts CHANGED
@@ -107,4 +107,33 @@ export declare function probeNativeWireframe(): {
107
107
  sceneCount: number;
108
108
  windowCount: number;
109
109
  };
110
+ /**
111
+ * v1.0.0-rc.2 — JS entry to the `probeScreenshot` native diagnostic.
112
+ * Same shape contract as [probeNativeWireframe]: returns a flat
113
+ * key/value bag the consumer can ship back as-is when screenshot
114
+ * capture returns null.
115
+ *
116
+ * path meaning
117
+ * ───────────────────────── ───────────────────────────────────────
118
+ * none(not-yet-called) captureScreenshot has never run
119
+ * ok capture succeeded
120
+ * activity.null Android: foreground tracker had no Activity
121
+ * window.null Android/iOS: Activity/scene has no window
122
+ * decorView.null Android: window had no decor view
123
+ * decorView.zero-size Android: decorView size <= 0 (mid-layout)
124
+ * api.unsupported Android: API < 24 (no PixelCopy)
125
+ * pixelCopy.notSuccess Android: PixelCopy completed but reported failure
126
+ * pixelCopy.threw:<class> Android: PixelCopy threw mid-request
127
+ * render.failed iOS: UIGraphicsImageRenderer returned nil
128
+ * empty iOS: walked tree but no view+screenshot output
129
+ *
130
+ * On Android the result also carries `trackedSource` (lifecycle.created /
131
+ * lifecycle.resumed / reflection.activityThread / manual.setActivity)
132
+ * so callers can tell whether the SDK back-filled via reflection.
133
+ */
134
+ export declare function probeNativeScreenshot(): {
135
+ available: boolean;
136
+ lastPath: string;
137
+ raw: Record<string, unknown>;
138
+ };
110
139
  //# sourceMappingURL=native.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"native.d.ts","sourceRoot":"","sources":["../src/native.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AA8HH,wBAAgB,eAAe,CAAC,MAAM,EAAE;IACtC,WAAW,EAAE,MAAM,CAAA;IACnB,OAAO,EAAE,MAAM,CAAA;IACf,KAAK,EAAE,MAAM,CAAA;CACd,GAAG,IAAI,CAMP;AAED,wBAAsB,kBAAkB,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC,CAQ5D;AAED;;;;;;;;;GASG;AACH,wBAAgB,kBAAkB,IAAI,IAAI,CAMzC;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,CAAC,EAAE;IACzC,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB,GAAG,IAAI,CAMP;AAED,wBAAgB,eAAe,IAAI,IAAI,CAMtC;AAED,+DAA+D;AAC/D,wBAAgB,uBAAuB,IAAI,IAAI,CAM9C;AAED,yEAAyE;AACzE,wBAAgB,oBAAoB,IAAI,IAAI,GAAG,MAAM,CAOpD;AAED,oEAAoE;AACpE,wBAAgB,sBAAsB,IAAI,IAAI,GAAG;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAMhF;AAED,iEAAiE;AACjE,wBAAgB,wBAAwB,IAAI,IAAI,CAM/C;AAED;;yBAEyB;AACzB,wBAAgB,wBAAwB,IAAI,IAAI,GAAG;IACjD,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,MAAM,CAAA;IACd,KAAK,EAAE,MAAM,EAAE,CAAA;CAChB,CAMA;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,+BAA+B,CACnD,SAAS,EAAE,MAAM,EAAE,GAClB,OAAO,CAAC,IAAI,GAAG;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,CAAC,CAoCvD;AAED;;sEAEsE;AACtE,wBAAgB,uBAAuB,IAAI;IACzC,KAAK,EAAE,OAAO,CAAA;IACd,mBAAmB,EAAE,OAAO,CAAA;IAC5B,iBAAiB,EAAE,OAAO,CAAA;CAC3B,CAOA;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,oBAAoB,IAAI;IACtC,SAAS,EAAE,OAAO,CAAA;IAClB,SAAS,EAAE,MAAM,CAAA;IACjB,QAAQ,EAAE,MAAM,CAAA;IAChB,UAAU,EAAE,MAAM,CAAA;IAClB,WAAW,EAAE,MAAM,CAAA;CACpB,CAiCA"}
1
+ {"version":3,"file":"native.d.ts","sourceRoot":"","sources":["../src/native.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAyIH,wBAAgB,eAAe,CAAC,MAAM,EAAE;IACtC,WAAW,EAAE,MAAM,CAAA;IACnB,OAAO,EAAE,MAAM,CAAA;IACf,KAAK,EAAE,MAAM,CAAA;CACd,GAAG,IAAI,CAMP;AAED,wBAAsB,kBAAkB,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC,CAQ5D;AAED;;;;;;;;;GASG;AACH,wBAAgB,kBAAkB,IAAI,IAAI,CAMzC;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,CAAC,EAAE;IACzC,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB,GAAG,IAAI,CAMP;AAED,wBAAgB,eAAe,IAAI,IAAI,CAMtC;AAED,+DAA+D;AAC/D,wBAAgB,uBAAuB,IAAI,IAAI,CAM9C;AAED,yEAAyE;AACzE,wBAAgB,oBAAoB,IAAI,IAAI,GAAG,MAAM,CAOpD;AAED,oEAAoE;AACpE,wBAAgB,sBAAsB,IAAI,IAAI,GAAG;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAMhF;AAED,iEAAiE;AACjE,wBAAgB,wBAAwB,IAAI,IAAI,CAM/C;AAED;;yBAEyB;AACzB,wBAAgB,wBAAwB,IAAI,IAAI,GAAG;IACjD,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,MAAM,CAAA;IACd,KAAK,EAAE,MAAM,EAAE,CAAA;CAChB,CAMA;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,+BAA+B,CACnD,SAAS,EAAE,MAAM,EAAE,GAClB,OAAO,CAAC,IAAI,GAAG;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,CAAC,CAoCvD;AAED;;sEAEsE;AACtE,wBAAgB,uBAAuB,IAAI;IACzC,KAAK,EAAE,OAAO,CAAA;IACd,mBAAmB,EAAE,OAAO,CAAA;IAC5B,iBAAiB,EAAE,OAAO,CAAA;CAC3B,CAOA;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,oBAAoB,IAAI;IACtC,SAAS,EAAE,OAAO,CAAA;IAClB,SAAS,EAAE,MAAM,CAAA;IACjB,QAAQ,EAAE,MAAM,CAAA;IAChB,UAAU,EAAE,MAAM,CAAA;IAClB,WAAW,EAAE,MAAM,CAAA;CACpB,CAiCA;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,qBAAqB,IAAI;IACvC,SAAS,EAAE,OAAO,CAAA;IAClB,QAAQ,EAAE,MAAM,CAAA;IAChB,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAC7B,CAkBA"}
package/lib/native.js CHANGED
@@ -251,4 +251,47 @@ export function probeNativeWireframe() {
251
251
  };
252
252
  }
253
253
  }
254
+ /**
255
+ * v1.0.0-rc.2 — JS entry to the `probeScreenshot` native diagnostic.
256
+ * Same shape contract as [probeNativeWireframe]: returns a flat
257
+ * key/value bag the consumer can ship back as-is when screenshot
258
+ * capture returns null.
259
+ *
260
+ * path meaning
261
+ * ───────────────────────── ───────────────────────────────────────
262
+ * none(not-yet-called) captureScreenshot has never run
263
+ * ok capture succeeded
264
+ * activity.null Android: foreground tracker had no Activity
265
+ * window.null Android/iOS: Activity/scene has no window
266
+ * decorView.null Android: window had no decor view
267
+ * decorView.zero-size Android: decorView size <= 0 (mid-layout)
268
+ * api.unsupported Android: API < 24 (no PixelCopy)
269
+ * pixelCopy.notSuccess Android: PixelCopy completed but reported failure
270
+ * pixelCopy.threw:<class> Android: PixelCopy threw mid-request
271
+ * render.failed iOS: UIGraphicsImageRenderer returned nil
272
+ * empty iOS: walked tree but no view+screenshot output
273
+ *
274
+ * On Android the result also carries `trackedSource` (lifecycle.created /
275
+ * lifecycle.resumed / reflection.activityThread / manual.setActivity)
276
+ * so callers can tell whether the SDK back-filled via reflection.
277
+ */
278
+ export function probeNativeScreenshot() {
279
+ const n = native();
280
+ if (!n || typeof n.probeScreenshot !== 'function') {
281
+ return { available: false, lastPath: 'native.unavailable', raw: {} };
282
+ }
283
+ try {
284
+ const r = n.probeScreenshot();
285
+ const raw = r && typeof r === 'object' && !Array.isArray(r) ? r : {};
286
+ const lastPath = typeof raw.lastPath === 'string' ? raw.lastPath : 'unknown';
287
+ return { available: true, lastPath, raw };
288
+ }
289
+ catch (e) {
290
+ if (typeof __DEV__ !== 'undefined' && __DEV__) {
291
+ // eslint-disable-next-line no-console
292
+ console.warn('[sentori] probeScreenshot threw', e);
293
+ }
294
+ return { available: false, lastPath: 'native.threw', raw: {} };
295
+ }
296
+ }
254
297
  //# sourceMappingURL=native.js.map
package/lib/native.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"native.js","sourceRoot":"","sources":["../src/native.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"native.js","sourceRoot":"","sources":["../src/native.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@goliapkg/sentori-react-native",
3
- "version": "1.0.0-rc.1",
3
+ "version": "1.0.0-rc.2",
4
4
  "description": "Sentori SDK for React Native \u2014 JS-layer error capture, native crash handlers (iOS / Android), batched transport, fetch + react-navigation tracing.",
5
5
  "license": "MIT",
6
6
  "homepage": "https://sentori.golia.jp",
package/src/index.ts CHANGED
@@ -102,6 +102,7 @@ export {
102
102
  } from './state-snapshots';
103
103
  export { RageTapCapture } from './rage-tap';
104
104
  export {
105
+ probeNativeScreenshot,
105
106
  probeNativeWireframe,
106
107
  startAnrWatchdog,
107
108
  stopAnrWatchdog,
package/src/native.ts CHANGED
@@ -78,9 +78,20 @@ type SentoriNativeModule = {
78
78
  probeWireframe?: () => {
79
79
  lastPath: string
80
80
  lastNodes: number
81
- sceneCount: number
82
- windowCount: number
81
+ sceneCount?: number
82
+ windowCount?: number
83
+ trackedSource?: string
84
+ trackedActivity?: string
85
+ decorViewFound?: boolean
83
86
  }
87
+ /**
88
+ * v1.0.0-rc.2 — diagnostic mirror of probeWireframe for the
89
+ * screenshot path. Returned shape is best-effort cross-platform —
90
+ * Android carries `trackedActivity` / `decorViewFound` / dims,
91
+ * iOS carries `windowFound` / `rootViewControllerFound` / `bounds*`.
92
+ * Callers should treat unknown keys as missing.
93
+ */
94
+ probeScreenshot?: () => Record<string, unknown>
84
95
  /**
85
96
  * Phase 22 sub-D / sub-E: cross-platform main-thread watchdog.
86
97
  * Android: 5 s / 1 s defaults (matches the OS ANR threshold).
@@ -379,3 +390,51 @@ export function probeNativeWireframe(): {
379
390
  }
380
391
  }
381
392
  }
393
+
394
+ /**
395
+ * v1.0.0-rc.2 — JS entry to the `probeScreenshot` native diagnostic.
396
+ * Same shape contract as [probeNativeWireframe]: returns a flat
397
+ * key/value bag the consumer can ship back as-is when screenshot
398
+ * capture returns null.
399
+ *
400
+ * path meaning
401
+ * ───────────────────────── ───────────────────────────────────────
402
+ * none(not-yet-called) captureScreenshot has never run
403
+ * ok capture succeeded
404
+ * activity.null Android: foreground tracker had no Activity
405
+ * window.null Android/iOS: Activity/scene has no window
406
+ * decorView.null Android: window had no decor view
407
+ * decorView.zero-size Android: decorView size <= 0 (mid-layout)
408
+ * api.unsupported Android: API < 24 (no PixelCopy)
409
+ * pixelCopy.notSuccess Android: PixelCopy completed but reported failure
410
+ * pixelCopy.threw:<class> Android: PixelCopy threw mid-request
411
+ * render.failed iOS: UIGraphicsImageRenderer returned nil
412
+ * empty iOS: walked tree but no view+screenshot output
413
+ *
414
+ * On Android the result also carries `trackedSource` (lifecycle.created /
415
+ * lifecycle.resumed / reflection.activityThread / manual.setActivity)
416
+ * so callers can tell whether the SDK back-filled via reflection.
417
+ */
418
+ export function probeNativeScreenshot(): {
419
+ available: boolean
420
+ lastPath: string
421
+ raw: Record<string, unknown>
422
+ } {
423
+ const n = native()
424
+ if (!n || typeof n.probeScreenshot !== 'function') {
425
+ return { available: false, lastPath: 'native.unavailable', raw: {} }
426
+ }
427
+ try {
428
+ const r = n.probeScreenshot()
429
+ const raw =
430
+ r && typeof r === 'object' && !Array.isArray(r) ? (r as Record<string, unknown>) : {}
431
+ const lastPath = typeof raw.lastPath === 'string' ? raw.lastPath : 'unknown'
432
+ return { available: true, lastPath, raw }
433
+ } catch (e) {
434
+ if (typeof __DEV__ !== 'undefined' && __DEV__) {
435
+ // eslint-disable-next-line no-console
436
+ console.warn('[sentori] probeScreenshot threw', e)
437
+ }
438
+ return { available: false, lastPath: 'native.threw', raw: {} }
439
+ }
440
+ }