Merge pull request #3558 from k9mail/controller_extension
Add ControllerExtension to allow accessing MessagingController internals
This commit is contained in:
commit
f3ef980587
8 changed files with 72 additions and 43 deletions
|
@ -9,6 +9,7 @@ import android.os.Handler
|
|||
import android.os.Looper
|
||||
import android.os.StrictMode
|
||||
import com.fsck.k9.autocrypt.autocryptModule
|
||||
import com.fsck.k9.controller.controllerModule
|
||||
import com.fsck.k9.crypto.openPgpModule
|
||||
import com.fsck.k9.mail.internet.BinaryTempFileBody
|
||||
import com.fsck.k9.mail.ssl.LocalKeyStore
|
||||
|
@ -39,7 +40,8 @@ object Core : KoinComponent {
|
|||
mailStoreModule,
|
||||
extractorModule,
|
||||
htmlModule,
|
||||
coreNotificationModule
|
||||
coreNotificationModule,
|
||||
controllerModule
|
||||
)
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package com.fsck.k9
|
||||
|
||||
import android.content.Context
|
||||
import com.fsck.k9.controller.MessagingController
|
||||
import com.fsck.k9.helper.Contacts
|
||||
import com.fsck.k9.mail.power.PowerManager
|
||||
import com.fsck.k9.mailstore.StorageManager
|
||||
import com.fsck.k9.power.TracingPowerManager
|
||||
|
@ -9,8 +9,8 @@ import org.koin.dsl.module.applicationContext
|
|||
|
||||
val mainModule = applicationContext {
|
||||
bean { Preferences.getPreferences(get()) }
|
||||
bean { MessagingController.getInstance(get()) }
|
||||
bean { get<Context>().resources }
|
||||
bean { StorageManager.getInstance(get()) }
|
||||
bean { TracingPowerManager.getPowerManager(get()) as PowerManager }
|
||||
bean { Contacts.getInstance(get()) }
|
||||
}
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
package com.fsck.k9.controller
|
||||
|
||||
import com.fsck.k9.backend.BackendManager
|
||||
|
||||
interface ControllerExtension {
|
||||
fun init(controller: MessagingController, backendManager: BackendManager, controllerInternals: ControllerInternals)
|
||||
|
||||
|
||||
interface ControllerInternals {
|
||||
fun put(description: String, listener: MessagingListener?, runnable: Runnable)
|
||||
fun putBackground(description: String, listener: MessagingListener?, runnable: Runnable)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
package com.fsck.k9.controller
|
||||
|
||||
import org.koin.dsl.module.applicationContext
|
||||
|
||||
val controllerModule = applicationContext {
|
||||
bean { MessagingController(get(), get(), get(), get(), get(), get(), get("controllerExtensions")) }
|
||||
bean { DefaultAccountStatsCollector(get()) as AccountStatsCollector }
|
||||
}
|
|
@ -37,6 +37,7 @@ import com.fsck.k9.Account.DeletePolicy;
|
|||
import com.fsck.k9.Account.Expunge;
|
||||
import com.fsck.k9.AccountStats;
|
||||
import com.fsck.k9.CoreResourceProvider;
|
||||
import com.fsck.k9.controller.ControllerExtension.ControllerInternals;
|
||||
import com.fsck.k9.core.BuildConfig;
|
||||
import com.fsck.k9.DI;
|
||||
import com.fsck.k9.K9;
|
||||
|
@ -83,6 +84,7 @@ import com.fsck.k9.search.LocalSearch;
|
|||
import com.fsck.k9.search.SearchAccount;
|
||||
import com.fsck.k9.search.SearchSpecification;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import timber.log.Timber;
|
||||
|
||||
import static com.fsck.k9.K9.MAX_SEND_ATTEMPTS;
|
||||
|
@ -109,13 +111,10 @@ public class MessagingController {
|
|||
public static final Set<Flag> SYNC_FLAGS = EnumSet.of(Flag.SEEN, Flag.FLAGGED, Flag.ANSWERED, Flag.FORWARDED);
|
||||
|
||||
|
||||
private static MessagingController inst = null;
|
||||
|
||||
|
||||
private final Context context;
|
||||
private final Contacts contacts;
|
||||
private final NotificationController notificationController;
|
||||
private final BackendManager backendManager = DI.get(BackendManager.class);
|
||||
private final BackendManager backendManager;
|
||||
|
||||
private final Thread controllerThread;
|
||||
|
||||
|
@ -133,28 +132,20 @@ public class MessagingController {
|
|||
private volatile boolean stopped = false;
|
||||
|
||||
|
||||
public static synchronized MessagingController getInstance(Context context) {
|
||||
if (inst == null) {
|
||||
Context appContext = context.getApplicationContext();
|
||||
NotificationController notificationController = DI.get(NotificationController.class);
|
||||
Contacts contacts = Contacts.getInstance(context);
|
||||
AccountStatsCollector accountStatsCollector = new DefaultAccountStatsCollector(context);
|
||||
CoreResourceProvider resourceProvider = DI.get(CoreResourceProvider.class);
|
||||
inst = new MessagingController(appContext, notificationController, contacts,
|
||||
accountStatsCollector, resourceProvider);
|
||||
}
|
||||
return inst;
|
||||
public static MessagingController getInstance(Context context) {
|
||||
return DI.get(MessagingController.class);
|
||||
}
|
||||
|
||||
|
||||
@VisibleForTesting
|
||||
MessagingController(Context context, NotificationController notificationController, Contacts contacts,
|
||||
AccountStatsCollector accountStatsCollector, CoreResourceProvider resourceProvider) {
|
||||
AccountStatsCollector accountStatsCollector, CoreResourceProvider resourceProvider,
|
||||
BackendManager backendManager, List<ControllerExtension> controllerExtensions) {
|
||||
this.context = context;
|
||||
this.notificationController = notificationController;
|
||||
this.contacts = contacts;
|
||||
this.accountStatsCollector = accountStatsCollector;
|
||||
this.resourceProvider = resourceProvider;
|
||||
this.backendManager = backendManager;
|
||||
|
||||
controllerThread = new Thread(new Runnable() {
|
||||
@Override
|
||||
|
@ -165,6 +156,32 @@ public class MessagingController {
|
|||
controllerThread.setName("MessagingController");
|
||||
controllerThread.start();
|
||||
addListener(memorizingMessagingListener);
|
||||
|
||||
initializeControllerExtensions(controllerExtensions);
|
||||
}
|
||||
|
||||
private void initializeControllerExtensions(List<ControllerExtension> controllerExtensions) {
|
||||
if (controllerExtensions.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
ControllerInternals internals = new ControllerInternals() {
|
||||
@Override
|
||||
public void put(@NotNull String description, @Nullable MessagingListener listener,
|
||||
@NotNull Runnable runnable) {
|
||||
MessagingController.this.put(description, listener, runnable);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void putBackground(@NotNull String description, @Nullable MessagingListener listener,
|
||||
@NotNull Runnable runnable) {
|
||||
MessagingController.this.putBackground(description, listener, runnable);
|
||||
}
|
||||
};
|
||||
|
||||
for (ControllerExtension extension : controllerExtensions) {
|
||||
extension.init(this, backendManager, internals);
|
||||
}
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
|
|
|
@ -16,6 +16,7 @@ import com.fsck.k9.CoreResourceProvider;
|
|||
import com.fsck.k9.K9;
|
||||
import com.fsck.k9.K9RobolectricTest;
|
||||
import com.fsck.k9.Preferences;
|
||||
import com.fsck.k9.backend.BackendManager;
|
||||
import com.fsck.k9.backend.api.Backend;
|
||||
import com.fsck.k9.helper.Contacts;
|
||||
import com.fsck.k9.mail.AuthenticationFailedException;
|
||||
|
@ -74,6 +75,8 @@ public class MessagingControllerTest extends K9RobolectricTest {
|
|||
|
||||
private MessagingController controller;
|
||||
@Mock
|
||||
private BackendManager backendManager;
|
||||
@Mock
|
||||
private Backend backend;
|
||||
@Mock
|
||||
private Contacts contacts;
|
||||
|
@ -134,11 +137,11 @@ public class MessagingControllerTest extends K9RobolectricTest {
|
|||
MockitoAnnotations.initMocks(this);
|
||||
appContext = RuntimeEnvironment.application;
|
||||
|
||||
MessagingControllerTestExtra.backendManagerProvides(backend);
|
||||
|
||||
controller = new MessagingController(appContext, notificationController, contacts,
|
||||
accountStatsCollector, mock(CoreResourceProvider.class));
|
||||
accountStatsCollector, mock(CoreResourceProvider.class), backendManager,
|
||||
Collections.<ControllerExtension>emptyList());
|
||||
|
||||
configureBackendManager();
|
||||
configureAccount();
|
||||
configureLocalStore();
|
||||
}
|
||||
|
@ -527,6 +530,10 @@ public class MessagingControllerTest extends K9RobolectricTest {
|
|||
controller.addListener(listener);
|
||||
}
|
||||
|
||||
private void configureBackendManager() {
|
||||
when(backendManager.getBackend(account)).thenReturn(backend);
|
||||
}
|
||||
|
||||
private void configureAccount() throws MessagingException {
|
||||
when(account.isAvailable(appContext)).thenReturn(true);
|
||||
when(account.getLocalStore()).thenReturn(localStore);
|
||||
|
|
|
@ -1,20 +0,0 @@
|
|||
@file:JvmName("MessagingControllerTestExtra")
|
||||
package com.fsck.k9.controller
|
||||
|
||||
import com.fsck.k9.backend.BackendManager
|
||||
import com.fsck.k9.backend.api.Backend
|
||||
import com.nhaarman.mockito_kotlin.any
|
||||
import com.nhaarman.mockito_kotlin.doReturn
|
||||
import com.nhaarman.mockito_kotlin.mock
|
||||
import org.koin.dsl.module.applicationContext
|
||||
import org.koin.standalone.StandAloneContext.loadKoinModules
|
||||
|
||||
fun backendManagerProvides(backend: Backend) {
|
||||
val backendManager = mock<BackendManager> {
|
||||
on { getBackend(any()) } doReturn backend
|
||||
}
|
||||
|
||||
loadKoinModules(applicationContext {
|
||||
bean { backendManager }
|
||||
})
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
package com.fsck.k9
|
||||
|
||||
import com.fsck.k9.backends.backendsModule
|
||||
import com.fsck.k9.controller.ControllerExtension
|
||||
import com.fsck.k9.external.BroadcastSenderListener
|
||||
import com.fsck.k9.external.externalModule
|
||||
import com.fsck.k9.notification.notificationModule
|
||||
|
@ -20,6 +21,7 @@ private val mainAppModule = applicationContext {
|
|||
get<BroadcastSenderListener>()
|
||||
))
|
||||
}
|
||||
bean("controllerExtensions") { emptyList<ControllerExtension>() }
|
||||
}
|
||||
|
||||
val appModules = listOf(
|
||||
|
|
Loading…
Reference in a new issue