Skip to content
Snippets Groups Projects
Unverified Commit 69f23ead authored by akwizgran's avatar akwizgran
Browse files

Ensure that Service instances aren't reused.

parent 57be439f
No related branches found
No related tags found
No related merge requests found
...@@ -41,6 +41,7 @@ import java.util.concurrent.Callable; ...@@ -41,6 +41,7 @@ import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executor; import java.util.concurrent.Executor;
import java.util.concurrent.Future; import java.util.concurrent.Future;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.logging.Logger; import java.util.logging.Logger;
import javax.inject.Inject; import javax.inject.Inject;
...@@ -80,10 +81,10 @@ class AndroidNotificationManagerImpl implements AndroidNotificationManager, ...@@ -80,10 +81,10 @@ class AndroidNotificationManagerImpl implements AndroidNotificationManager,
private final Context appContext; private final Context appContext;
// The following must only be accessed on the main UI thread // The following must only be accessed on the main UI thread
private final Map<GroupId, Integer> contactCounts = private final Map<GroupId, Integer> contactCounts = new HashMap<>();
new HashMap<GroupId, Integer>(); private final Map<GroupId, Integer> forumCounts = new HashMap<>();
private final Map<GroupId, Integer> forumCounts = private final AtomicBoolean used = new AtomicBoolean(false);
new HashMap<GroupId, Integer>();
private int contactTotal = 0, forumTotal = 0; private int contactTotal = 0, forumTotal = 0;
private int nextRequestId = 0; private int nextRequestId = 0;
private GroupId visibleGroup = null; private GroupId visibleGroup = null;
...@@ -105,6 +106,7 @@ class AndroidNotificationManagerImpl implements AndroidNotificationManager, ...@@ -105,6 +106,7 @@ class AndroidNotificationManagerImpl implements AndroidNotificationManager,
@Override @Override
public void startService() throws ServiceException { public void startService() throws ServiceException {
if (used.getAndSet(true)) throw new IllegalStateException();
try { try {
settings = settingsManager.getSettings(SETTINGS_NAMESPACE); settings = settingsManager.getSettings(SETTINGS_NAMESPACE);
} catch (DbException e) { } catch (DbException e) {
...@@ -115,6 +117,7 @@ class AndroidNotificationManagerImpl implements AndroidNotificationManager, ...@@ -115,6 +117,7 @@ class AndroidNotificationManagerImpl implements AndroidNotificationManager,
@Override @Override
public void stopService() throws ServiceException { public void stopService() throws ServiceException {
Future<Void> f = androidExecutor.submit(new Callable<Void>() { Future<Void> f = androidExecutor.submit(new Callable<Void>() {
@Override
public Void call() { public Void call() {
clearPrivateMessageNotification(); clearPrivateMessageNotification();
clearForumPostNotification(); clearForumPostNotification();
...@@ -124,9 +127,7 @@ class AndroidNotificationManagerImpl implements AndroidNotificationManager, ...@@ -124,9 +127,7 @@ class AndroidNotificationManagerImpl implements AndroidNotificationManager,
}); });
try { try {
f.get(); f.get();
} catch (InterruptedException e) { } catch (InterruptedException | ExecutionException e) {
throw new ServiceException(e);
} catch (ExecutionException e) {
throw new ServiceException(e); throw new ServiceException(e);
} }
} }
...@@ -149,6 +150,7 @@ class AndroidNotificationManagerImpl implements AndroidNotificationManager, ...@@ -149,6 +150,7 @@ class AndroidNotificationManagerImpl implements AndroidNotificationManager,
nm.cancel(INTRODUCTION_SUCCESS_NOTIFICATION_ID); nm.cancel(INTRODUCTION_SUCCESS_NOTIFICATION_ID);
} }
@Override
public void eventOccurred(Event e) { public void eventOccurred(Event e) {
if (e instanceof SettingsUpdatedEvent) { if (e instanceof SettingsUpdatedEvent) {
SettingsUpdatedEvent s = (SettingsUpdatedEvent) e; SettingsUpdatedEvent s = (SettingsUpdatedEvent) e;
...@@ -176,6 +178,7 @@ class AndroidNotificationManagerImpl implements AndroidNotificationManager, ...@@ -176,6 +178,7 @@ class AndroidNotificationManagerImpl implements AndroidNotificationManager,
private void loadSettings() { private void loadSettings() {
dbExecutor.execute(new Runnable() { dbExecutor.execute(new Runnable() {
@Override
public void run() { public void run() {
try { try {
settings = settingsManager.getSettings(SETTINGS_NAMESPACE); settings = settingsManager.getSettings(SETTINGS_NAMESPACE);
...@@ -187,8 +190,10 @@ class AndroidNotificationManagerImpl implements AndroidNotificationManager, ...@@ -187,8 +190,10 @@ class AndroidNotificationManagerImpl implements AndroidNotificationManager,
}); });
} }
@Override
public void showPrivateMessageNotification(final GroupId g) { public void showPrivateMessageNotification(final GroupId g) {
androidExecutor.execute(new Runnable() { androidExecutor.execute(new Runnable() {
@Override
public void run() { public void run() {
Integer count = contactCounts.get(g); Integer count = contactCounts.get(g);
if (count == null) contactCounts.put(g, 1); if (count == null) contactCounts.put(g, 1);
...@@ -200,8 +205,10 @@ class AndroidNotificationManagerImpl implements AndroidNotificationManager, ...@@ -200,8 +205,10 @@ class AndroidNotificationManagerImpl implements AndroidNotificationManager,
}); });
} }
@Override
public void clearPrivateMessageNotification(final GroupId g) { public void clearPrivateMessageNotification(final GroupId g) {
androidExecutor.execute(new Runnable() { androidExecutor.execute(new Runnable() {
@Override
public void run() { public void run() {
Integer count = contactCounts.remove(g); Integer count = contactCounts.remove(g);
if (count == null) return; // Already cleared if (count == null) return; // Already cleared
...@@ -271,9 +278,12 @@ class AndroidNotificationManagerImpl implements AndroidNotificationManager, ...@@ -271,9 +278,12 @@ class AndroidNotificationManagerImpl implements AndroidNotificationManager,
return defaults; return defaults;
} }
@Override
public void showForumPostNotification(final GroupId g) { public void showForumPostNotification(final GroupId g) {
androidExecutor.execute(new Runnable() { androidExecutor.execute(new Runnable() {
public void run() { @Override
public void
run() {
Integer count = forumCounts.get(g); Integer count = forumCounts.get(g);
if (count == null) forumCounts.put(g, 1); if (count == null) forumCounts.put(g, 1);
else forumCounts.put(g, count + 1); else forumCounts.put(g, count + 1);
...@@ -284,8 +294,10 @@ class AndroidNotificationManagerImpl implements AndroidNotificationManager, ...@@ -284,8 +294,10 @@ class AndroidNotificationManagerImpl implements AndroidNotificationManager,
}); });
} }
@Override
public void clearForumPostNotification(final GroupId g) { public void clearForumPostNotification(final GroupId g) {
androidExecutor.execute(new Runnable() { androidExecutor.execute(new Runnable() {
@Override
public void run() { public void run() {
Integer count = forumCounts.remove(g); Integer count = forumCounts.remove(g);
if (count == null) return; // Already cleared if (count == null) return; // Already cleared
...@@ -343,16 +355,20 @@ class AndroidNotificationManagerImpl implements AndroidNotificationManager, ...@@ -343,16 +355,20 @@ class AndroidNotificationManagerImpl implements AndroidNotificationManager,
} }
} }
@Override
public void blockNotification(final GroupId g) { public void blockNotification(final GroupId g) {
androidExecutor.execute(new Runnable() { androidExecutor.execute(new Runnable() {
@Override
public void run() { public void run() {
visibleGroup = g; visibleGroup = g;
} }
}); });
} }
@Override
public void unblockNotification(final GroupId g) { public void unblockNotification(final GroupId g) {
androidExecutor.execute(new Runnable() { androidExecutor.execute(new Runnable() {
@Override
public void run() { public void run() {
if (g.equals(visibleGroup)) visibleGroup = null; if (g.equals(visibleGroup)) visibleGroup = null;
} }
...@@ -361,6 +377,7 @@ class AndroidNotificationManagerImpl implements AndroidNotificationManager, ...@@ -361,6 +377,7 @@ class AndroidNotificationManagerImpl implements AndroidNotificationManager,
private void showIntroductionNotifications(final ContactId c) { private void showIntroductionNotifications(final ContactId c) {
androidExecutor.execute(new Runnable() { androidExecutor.execute(new Runnable() {
@Override
public void run() { public void run() {
try { try {
GroupId group = messagingManager.getConversationId(c); GroupId group = messagingManager.getConversationId(c);
...@@ -375,6 +392,7 @@ class AndroidNotificationManagerImpl implements AndroidNotificationManager, ...@@ -375,6 +392,7 @@ class AndroidNotificationManagerImpl implements AndroidNotificationManager,
private void showIntroductionSucceededNotification(final Contact c) { private void showIntroductionSucceededNotification(final Contact c) {
androidExecutor.execute(new Runnable() { androidExecutor.execute(new Runnable() {
@Override
public void run() { public void run() {
NotificationCompat.Builder b = NotificationCompat.Builder b =
new NotificationCompat.Builder(appContext); new NotificationCompat.Builder(appContext);
......
...@@ -39,6 +39,7 @@ import java.util.concurrent.ConcurrentHashMap; ...@@ -39,6 +39,7 @@ import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.CountDownLatch; import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Executor; import java.util.concurrent.Executor;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.logging.Logger; import java.util.logging.Logger;
import javax.inject.Inject; import javax.inject.Inject;
...@@ -61,6 +62,7 @@ class PluginManagerImpl implements PluginManager, Service { ...@@ -61,6 +62,7 @@ class PluginManagerImpl implements PluginManager, Service {
private final Map<TransportId, Plugin> plugins; private final Map<TransportId, Plugin> plugins;
private final List<SimplexPlugin> simplexPlugins; private final List<SimplexPlugin> simplexPlugins;
private final List<DuplexPlugin> duplexPlugins; private final List<DuplexPlugin> duplexPlugins;
private final AtomicBoolean used = new AtomicBoolean(false);
@Inject @Inject
PluginManagerImpl(@IoExecutor Executor ioExecutor, EventBus eventBus, PluginManagerImpl(@IoExecutor Executor ioExecutor, EventBus eventBus,
...@@ -82,6 +84,7 @@ class PluginManagerImpl implements PluginManager, Service { ...@@ -82,6 +84,7 @@ class PluginManagerImpl implements PluginManager, Service {
@Override @Override
public void startService() throws ServiceException { public void startService() throws ServiceException {
if (used.getAndSet(true)) throw new IllegalStateException();
Collection<SimplexPluginFactory> simplexFactories = Collection<SimplexPluginFactory> simplexFactories =
pluginConfig.getSimplexFactories(); pluginConfig.getSimplexFactories();
Collection<DuplexPluginFactory> duplexFactories = Collection<DuplexPluginFactory> duplexFactories =
......
...@@ -26,6 +26,7 @@ import java.util.Map; ...@@ -26,6 +26,7 @@ import java.util.Map;
import java.util.Queue; import java.util.Queue;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executor; import java.util.concurrent.Executor;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.logging.Logger; import java.util.logging.Logger;
import javax.inject.Inject; import javax.inject.Inject;
...@@ -44,6 +45,7 @@ class ValidationManagerImpl implements ValidationManager, Service, ...@@ -44,6 +45,7 @@ class ValidationManagerImpl implements ValidationManager, Service,
private final Executor cryptoExecutor; private final Executor cryptoExecutor;
private final Map<ClientId, MessageValidator> validators; private final Map<ClientId, MessageValidator> validators;
private final Map<ClientId, IncomingMessageHook> hooks; private final Map<ClientId, IncomingMessageHook> hooks;
private final AtomicBoolean used = new AtomicBoolean(false);
@Inject @Inject
ValidationManagerImpl(DatabaseComponent db, ValidationManagerImpl(DatabaseComponent db,
...@@ -58,6 +60,7 @@ class ValidationManagerImpl implements ValidationManager, Service, ...@@ -58,6 +60,7 @@ class ValidationManagerImpl implements ValidationManager, Service,
@Override @Override
public void startService() { public void startService() {
if (used.getAndSet(true)) throw new IllegalStateException();
for (ClientId c : validators.keySet()) getMessagesToValidate(c); for (ClientId c : validators.keySet()) getMessagesToValidate(c);
} }
...@@ -78,6 +81,7 @@ class ValidationManagerImpl implements ValidationManager, Service, ...@@ -78,6 +81,7 @@ class ValidationManagerImpl implements ValidationManager, Service,
private void getMessagesToValidate(final ClientId c) { private void getMessagesToValidate(final ClientId c) {
dbExecutor.execute(new Runnable() { dbExecutor.execute(new Runnable() {
@Override
public void run() { public void run() {
try { try {
Queue<MessageId> unvalidated = new LinkedList<MessageId>(); Queue<MessageId> unvalidated = new LinkedList<MessageId>();
...@@ -100,6 +104,7 @@ class ValidationManagerImpl implements ValidationManager, Service, ...@@ -100,6 +104,7 @@ class ValidationManagerImpl implements ValidationManager, Service,
private void validateNextMessage(final Queue<MessageId> unvalidated) { private void validateNextMessage(final Queue<MessageId> unvalidated) {
if (unvalidated.isEmpty()) return; if (unvalidated.isEmpty()) return;
dbExecutor.execute(new Runnable() { dbExecutor.execute(new Runnable() {
@Override
public void run() { public void run() {
try { try {
Message m = null; Message m = null;
...@@ -141,6 +146,7 @@ class ValidationManagerImpl implements ValidationManager, Service, ...@@ -141,6 +146,7 @@ class ValidationManagerImpl implements ValidationManager, Service,
private void validateMessage(final Message m, final Group g) { private void validateMessage(final Message m, final Group g) {
cryptoExecutor.execute(new Runnable() { cryptoExecutor.execute(new Runnable() {
@Override
public void run() { public void run() {
MessageValidator v = validators.get(g.getClientId()); MessageValidator v = validators.get(g.getClientId());
if (v == null) { if (v == null) {
...@@ -156,6 +162,7 @@ class ValidationManagerImpl implements ValidationManager, Service, ...@@ -156,6 +162,7 @@ class ValidationManagerImpl implements ValidationManager, Service,
private void storeValidationResult(final Message m, final ClientId c, private void storeValidationResult(final Message m, final ClientId c,
final Metadata meta) { final Metadata meta) {
dbExecutor.execute(new Runnable() { dbExecutor.execute(new Runnable() {
@Override
public void run() { public void run() {
try { try {
Transaction txn = db.startTransaction(false); Transaction txn = db.startTransaction(false);
...@@ -193,6 +200,7 @@ class ValidationManagerImpl implements ValidationManager, Service, ...@@ -193,6 +200,7 @@ class ValidationManagerImpl implements ValidationManager, Service,
private void loadGroupAndValidate(final Message m) { private void loadGroupAndValidate(final Message m) {
dbExecutor.execute(new Runnable() { dbExecutor.execute(new Runnable() {
@Override
public void run() { public void run() {
try { try {
Group g; Group g;
......
...@@ -28,6 +28,7 @@ import java.util.Map.Entry; ...@@ -28,6 +28,7 @@ import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executor; import java.util.concurrent.Executor;
import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.logging.Logger; import java.util.logging.Logger;
import javax.inject.Inject; import javax.inject.Inject;
...@@ -47,6 +48,7 @@ class KeyManagerImpl implements KeyManager, Service, EventListener { ...@@ -47,6 +48,7 @@ class KeyManagerImpl implements KeyManager, Service, EventListener {
private final Clock clock; private final Clock clock;
private final Map<ContactId, Boolean> activeContacts; private final Map<ContactId, Boolean> activeContacts;
private final ConcurrentHashMap<TransportId, TransportKeyManager> managers; private final ConcurrentHashMap<TransportId, TransportKeyManager> managers;
private final AtomicBoolean used = new AtomicBoolean(false);
@Inject @Inject
KeyManagerImpl(DatabaseComponent db, CryptoComponent crypto, KeyManagerImpl(DatabaseComponent db, CryptoComponent crypto,
...@@ -66,6 +68,7 @@ class KeyManagerImpl implements KeyManager, Service, EventListener { ...@@ -66,6 +68,7 @@ class KeyManagerImpl implements KeyManager, Service, EventListener {
@Override @Override
public void startService() throws ServiceException { public void startService() throws ServiceException {
if (used.getAndSet(true)) throw new IllegalStateException();
Map<TransportId, Integer> transports = Map<TransportId, Integer> transports =
new HashMap<TransportId, Integer>(); new HashMap<TransportId, Integer>();
for (SimplexPluginFactory f : pluginConfig.getSimplexFactories()) for (SimplexPluginFactory f : pluginConfig.getSimplexFactories())
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment