|
25 | 25 | import android.content.Intent; |
26 | 26 | import android.content.IntentFilter; |
27 | 27 | import android.os.Bundle; |
| 28 | +import android.os.Handler; |
| 29 | +import android.os.HandlerThread; |
| 30 | +import android.os.Process; |
28 | 31 | import io.sentry.Breadcrumb; |
29 | 32 | import io.sentry.Hint; |
30 | 33 | import io.sentry.IScopes; |
@@ -63,6 +66,7 @@ public final class SystemEventsBreadcrumbsIntegration |
63 | 66 | private volatile boolean isClosed = false; |
64 | 67 | private volatile boolean isStopped = false; |
65 | 68 | private volatile IntentFilter filter = null; |
| 69 | + private volatile HandlerThread handlerThread = null; |
66 | 70 | private final @NotNull AtomicBoolean isReceiverRegistered = new AtomicBoolean(false); |
67 | 71 | private final @NotNull AutoClosableReentrantLock receiverLock = new AutoClosableReentrantLock(); |
68 | 72 | // Track previous battery state to avoid duplicate breadcrumbs when values haven't changed |
@@ -138,10 +142,19 @@ private void registerReceiver( |
138 | 142 | filter.addAction(item); |
139 | 143 | } |
140 | 144 | } |
| 145 | + if (handlerThread == null) { |
| 146 | + handlerThread = |
| 147 | + new HandlerThread( |
| 148 | + "SystemEventsReceiver", Process.THREAD_PRIORITY_BACKGROUND); |
| 149 | + handlerThread.start(); |
| 150 | + } |
141 | 151 | try { |
142 | 152 | // registerReceiver can throw SecurityException but it's not documented in the |
143 | 153 | // official docs |
144 | | - ContextUtils.registerReceiver(context, options, receiver, filter); |
| 154 | + |
| 155 | + // onReceive will be called on this handler thread |
| 156 | + final @NotNull Handler handler = new Handler(handlerThread.getLooper()); |
| 157 | + ContextUtils.registerReceiver(context, options, receiver, filter, handler); |
145 | 158 | if (!isReceiverRegistered.getAndSet(true)) { |
146 | 159 | options |
147 | 160 | .getLogger() |
@@ -195,6 +208,10 @@ public void close() throws IOException { |
195 | 208 | try (final @NotNull ISentryLifecycleToken ignored = receiverLock.acquire()) { |
196 | 209 | isClosed = true; |
197 | 210 | filter = null; |
| 211 | + if (handlerThread != null) { |
| 212 | + handlerThread.quit(); |
| 213 | + } |
| 214 | + handlerThread = null; |
198 | 215 | } |
199 | 216 |
|
200 | 217 | AppState.getInstance().removeAppStateListener(this); |
@@ -293,25 +310,15 @@ public void onReceive(final Context context, final @NotNull Intent intent) { |
293 | 310 |
|
294 | 311 | final BatteryState state = batteryState; |
295 | 312 | final long now = System.currentTimeMillis(); |
296 | | - try { |
297 | | - options |
298 | | - .getExecutorService() |
299 | | - .submit( |
300 | | - () -> { |
301 | | - final Breadcrumb breadcrumb = createBreadcrumb(now, intent, action, state); |
302 | | - final Hint hint = new Hint(); |
303 | | - hint.set(ANDROID_INTENT, intent); |
304 | | - scopes.addBreadcrumb(breadcrumb, hint); |
305 | | - }); |
306 | | - } catch (Throwable t) { |
307 | | - // ignored |
308 | | - } |
| 313 | + final Breadcrumb breadcrumb = createBreadcrumb(now, intent, action, state); |
| 314 | + final Hint hint = new Hint(); |
| 315 | + hint.set(ANDROID_INTENT, intent); |
| 316 | + scopes.addBreadcrumb(breadcrumb, hint); |
309 | 317 | } |
310 | 318 |
|
311 | 319 | // in theory this should be ThreadLocal, but we won't have more than 1 thread accessing it, |
312 | 320 | // so we save some memory here and CPU cycles. 64 is because all intent actions we subscribe for |
313 | 321 | // are less than 64 chars. We also don't care about encoding as those are always UTF. |
314 | | - // TODO: _MULTI_THREADED_EXECUTOR_ |
315 | 322 | private final char[] buf = new char[64]; |
316 | 323 |
|
317 | 324 | @TestOnly |
@@ -365,8 +372,8 @@ String getStringAfterDotFast(final @Nullable String str) { |
365 | 372 | } |
366 | 373 | } else { |
367 | 374 | final Bundle extras = intent.getExtras(); |
368 | | - final Map<String, String> newExtras = new HashMap<>(); |
369 | 375 | if (extras != null && !extras.isEmpty()) { |
| 376 | + final Map<String, String> newExtras = new HashMap<>(extras.size()); |
370 | 377 | for (String item : extras.keySet()) { |
371 | 378 | try { |
372 | 379 | @SuppressWarnings("deprecation") |
|
0 commit comments