From c28148b843b9d5cda66d95afa0274640f61a3ffe Mon Sep 17 00:00:00 2001 From: adbenitez Date: Mon, 22 Dec 2025 16:32:27 +0100 Subject: [PATCH] avoid NPE accessing location manager, event center and notification center --- .../securesms/ApplicationContext.java | 36 ++++++++++++++++--- .../securesms/connect/DcHelper.java | 4 +-- .../geolocation/DcLocationManager.java | 6 ++-- .../securesms/mms/AttachmentManager.java | 2 +- 4 files changed, 38 insertions(+), 10 deletions(-) diff --git a/src/main/java/org/thoughtcrime/securesms/ApplicationContext.java b/src/main/java/org/thoughtcrime/securesms/ApplicationContext.java index 2fd3a5aee..6476842a3 100644 --- a/src/main/java/org/thoughtcrime/securesms/ApplicationContext.java +++ b/src/main/java/org/thoughtcrime/securesms/ApplicationContext.java @@ -62,9 +62,9 @@ public class ApplicationContext extends MultiDexApplication { private Rpc rpc; private DcContext dcContext; - public DcLocationManager dcLocationManager; - public DcEventCenter eventCenter; - public NotificationCenter notificationCenter; + private DcLocationManager dcLocationManager; + private DcEventCenter eventCenter; + private NotificationCenter notificationCenter; private JobManager jobManager; private int debugOnAvailableCount; @@ -127,6 +127,33 @@ public class ApplicationContext extends MultiDexApplication { } } + /** + * Get DcLocationManager instance, waiting for initialization if necessary. + * This method is thread-safe and will block until initialization is complete. + */ + public DcLocationManager getLocationManager() { + ensureInitialized(); + return dcLocationManager; + } + + /** + * Get DcEventCenter instance, waiting for initialization if necessary. + * This method is thread-safe and will block until initialization is complete. + */ + public DcEventCenter getEventCenter() { + ensureInitialized(); + return eventCenter; + } + + /** + * Get NotificationCenter instance, waiting for initialization if necessary. + * This method is thread-safe and will block until initialization is complete. + */ + public NotificationCenter getNotificationCenter() { + ensureInitialized(); + return notificationCenter; + } + @Override public void onCreate() { super.onCreate(); @@ -187,14 +214,13 @@ public class ApplicationContext extends MultiDexApplication { dcContext = dcAccounts.getSelectedAccount(); notificationCenter = new NotificationCenter(this); eventCenter = new DcEventCenter(this); + dcLocationManager = new DcLocationManager(this, dcContext); // Mark as initialized before starting threads that depend on it isInitialized = true; initLock.notifyAll(); Log.i(TAG, "DcAccounts initialization complete"); - dcLocationManager = new DcLocationManager(this); // depends on dcContext - new Thread(() -> { Log.i(TAG, "Starting event loop"); DcEventEmitter emitter = dcAccounts.getEventEmitter(); diff --git a/src/main/java/org/thoughtcrime/securesms/connect/DcHelper.java b/src/main/java/org/thoughtcrime/securesms/connect/DcHelper.java index 72b3edc44..6eadb77f8 100644 --- a/src/main/java/org/thoughtcrime/securesms/connect/DcHelper.java +++ b/src/main/java/org/thoughtcrime/securesms/connect/DcHelper.java @@ -77,11 +77,11 @@ public class DcHelper { } public static DcEventCenter getEventCenter(@NonNull Context context) { - return ApplicationContext.getInstance(context).eventCenter; + return ApplicationContext.getInstance(context).getEventCenter(); } public static NotificationCenter getNotificationCenter(@NonNull Context context) { - return ApplicationContext.getInstance(context).notificationCenter; + return ApplicationContext.getInstance(context).getNotificationCenter(); } public static boolean isConfigured(Context context) { diff --git a/src/main/java/org/thoughtcrime/securesms/geolocation/DcLocationManager.java b/src/main/java/org/thoughtcrime/securesms/geolocation/DcLocationManager.java index 1876caa2c..c54e81455 100644 --- a/src/main/java/org/thoughtcrime/securesms/geolocation/DcLocationManager.java +++ b/src/main/java/org/thoughtcrime/securesms/geolocation/DcLocationManager.java @@ -16,6 +16,8 @@ import java.util.Observer; import static android.content.Context.BIND_AUTO_CREATE; +import com.b44t.messenger.DcContext; + public class DcLocationManager implements Observer { private static final String TAG = DcLocationManager.class.getSimpleName(); @@ -40,10 +42,10 @@ public class DcLocationManager implements Observer { } }; - public DcLocationManager(Context context) { + public DcLocationManager(Context context, DcContext dcContext) { this.context = context.getApplicationContext(); DcLocation.getInstance().addObserver(this); - if (DcHelper.getContext(context).isSendingLocationsToChat(0)) { + if (dcContext.isSendingLocationsToChat(0)) { startLocationEngine(); } } diff --git a/src/main/java/org/thoughtcrime/securesms/mms/AttachmentManager.java b/src/main/java/org/thoughtcrime/securesms/mms/AttachmentManager.java index 53589981d..c2902b63e 100644 --- a/src/main/java/org/thoughtcrime/securesms/mms/AttachmentManager.java +++ b/src/main/java/org/thoughtcrime/securesms/mms/AttachmentManager.java @@ -473,7 +473,7 @@ public class AttachmentManager { public static void selectLocation(Activity activity, int chatId) { ApplicationContext applicationContext = ApplicationContext.getInstance(activity); - DcLocationManager dcLocationManager = applicationContext.dcLocationManager; + DcLocationManager dcLocationManager = applicationContext.getLocationManager(); if (DcHelper.getContext(applicationContext).isSendingLocationsToChat(chatId)) { dcLocationManager.stopSharingLocation(chatId);