diff --git a/app/src/main/java/org/session/libsession/messaging/utilities/MessageWrapper.kt b/app/src/main/java/org/session/libsession/messaging/utilities/MessageWrapper.kt deleted file mode 100644 index b069d5c28c..0000000000 --- a/app/src/main/java/org/session/libsession/messaging/utilities/MessageWrapper.kt +++ /dev/null @@ -1,14 +0,0 @@ -package org.session.libsession.messaging.utilities - -import org.session.libsignal.protos.WebSocketProtos -import org.session.protos.SessionProtos.Envelope - -object MessageWrapper { - - fun unwrap(data: ByteArray): Envelope { - val webSocketMessage = WebSocketProtos.WebSocketMessage.parseFrom(data) - val envelopeAsData = webSocketMessage.request.body - return Envelope.parseFrom(envelopeAsData) - } - // endregion -} diff --git a/app/src/main/java/org/session/libsession/utilities/serializable/ByteArrayAsHexSerializer.kt b/app/src/main/java/org/session/libsession/utilities/serializable/ByteArrayAsHexSerializer.kt deleted file mode 100644 index 685c190e50..0000000000 --- a/app/src/main/java/org/session/libsession/utilities/serializable/ByteArrayAsHexSerializer.kt +++ /dev/null @@ -1,26 +0,0 @@ -package org.session.libsession.utilities.serializable - -import kotlinx.serialization.KSerializer -import kotlinx.serialization.descriptors.PrimitiveKind -import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor -import kotlinx.serialization.descriptors.SerialDescriptor -import kotlinx.serialization.encoding.Decoder -import kotlinx.serialization.encoding.Encoder -import org.session.libsignal.utilities.Hex -import org.session.libsignal.utilities.toHexString - -class ByteArrayAsHexSerializer : KSerializer { - override val descriptor: SerialDescriptor = - PrimitiveSerialDescriptor(javaClass.name, PrimitiveKind.STRING) - - override fun serialize( - encoder: Encoder, - value: ByteArray - ) { - encoder.encodeString(value.toHexString()) - } - - override fun deserialize(decoder: Decoder): ByteArray { - return decoder.decodeString().let(Hex::fromStringCondensed) - } -} \ No newline at end of file diff --git a/app/src/main/java/org/session/libsession/utilities/serializable/KeyPairAsArraySerializer.kt b/app/src/main/java/org/session/libsession/utilities/serializable/KeyPairAsArraySerializer.kt deleted file mode 100644 index d30d4969e3..0000000000 --- a/app/src/main/java/org/session/libsession/utilities/serializable/KeyPairAsArraySerializer.kt +++ /dev/null @@ -1,32 +0,0 @@ -package org.session.libsession.utilities.serializable - -import kotlinx.serialization.KSerializer -import kotlinx.serialization.builtins.ArraySerializer -import kotlinx.serialization.builtins.serializer -import kotlinx.serialization.encoding.Decoder -import kotlinx.serialization.encoding.Encoder -import network.loki.messenger.libsession_util.util.KeyPair -import org.session.libsignal.utilities.Base64 - -class KeyPairAsArraySerializer : KSerializer { - private val stringArraySerializer: KSerializer> = ArraySerializer(String::class, String.serializer()) - override val descriptor = stringArraySerializer.descriptor - - override fun serialize( - encoder: Encoder, - value: KeyPair - ) { - stringArraySerializer.serialize(encoder, arrayOf( - Base64.encodeBytes(value.pubKey.data), - Base64.encodeBytes(value.secretKey.data) - )) - } - - override fun deserialize(decoder: Decoder): KeyPair { - val (pubKeyBase64, secretKeyBase64) = stringArraySerializer.deserialize(decoder) - return KeyPair( - pubKey = Base64.decode(pubKeyBase64), - secretKey = Base64.decode(secretKeyBase64) - ) - } -} diff --git a/app/src/main/java/org/session/libsignal/streams/OutputStreamFactory.java b/app/src/main/java/org/session/libsignal/streams/OutputStreamFactory.java deleted file mode 100644 index 4ca2f1b6ef..0000000000 --- a/app/src/main/java/org/session/libsignal/streams/OutputStreamFactory.java +++ /dev/null @@ -1,9 +0,0 @@ -package org.session.libsignal.streams; - -import java.io.IOException; -import java.io.OutputStream; - -public interface OutputStreamFactory { - - public DigestingOutputStream createFor(OutputStream wrap) throws IOException; -} diff --git a/app/src/main/java/org/session/libsignal/utilities/Broadcaster.kt b/app/src/main/java/org/session/libsignal/utilities/Broadcaster.kt deleted file mode 100644 index 0af650ea67..0000000000 --- a/app/src/main/java/org/session/libsignal/utilities/Broadcaster.kt +++ /dev/null @@ -1,7 +0,0 @@ -package org.session.libsignal.utilities - -interface Broadcaster { - - fun broadcast(event: String) - fun broadcast(event: String, long: Long) -} diff --git a/app/src/main/java/org/session/libsignal/utilities/PrettifiedDescription.kt b/app/src/main/java/org/session/libsignal/utilities/PrettifiedDescription.kt deleted file mode 100644 index 5f08f1b56e..0000000000 --- a/app/src/main/java/org/session/libsignal/utilities/PrettifiedDescription.kt +++ /dev/null @@ -1,27 +0,0 @@ -package org.session.libsignal.utilities - -fun Any.prettifiedDescription(): String { - if (this is List<*>) { return prettifiedDescription() } - if (this is Map<*, *>) { return prettifiedDescription() } - return toString() -} - -fun List<*>.prettifiedDescription(): String { - if (isEmpty()) { return "[]" } - return "[ " + joinToString(", ") { it?.prettifiedDescription() ?: "null" } + " ]" -} - -fun Map<*, *>.prettifiedDescription(): String { - return "[ " + map { entry -> - val keyDescription = entry.key?.prettifiedDescription() ?: "null" - var valueDescription = entry.value?.prettifiedDescription() ?: "null" - if (valueDescription.isEmpty()) { valueDescription = "\"\"" } - val maxLength = 20 - val truncatedValueDescription = if (valueDescription.length > maxLength) { - valueDescription.substring(0 until maxLength) + "..." - } else { - valueDescription - } - "$keyDescription : $truncatedValueDescription" - }.joinToString(", ") + " ]" -} \ No newline at end of file diff --git a/app/src/main/java/org/session/libsignal/utilities/ProfileAvatarData.java b/app/src/main/java/org/session/libsignal/utilities/ProfileAvatarData.java deleted file mode 100644 index df0f45cd10..0000000000 --- a/app/src/main/java/org/session/libsignal/utilities/ProfileAvatarData.java +++ /dev/null @@ -1,36 +0,0 @@ -package org.session.libsignal.utilities; - -import org.session.libsignal.streams.OutputStreamFactory; - -import java.io.InputStream; - -public class ProfileAvatarData { - - private final InputStream data; - private final long dataLength; - private final String contentType; - private final OutputStreamFactory outputStreamFactory; - - public ProfileAvatarData(InputStream data, long dataLength, String contentType, OutputStreamFactory outputStreamFactory) { - this.data = data; - this.dataLength = dataLength; - this.contentType = contentType; - this.outputStreamFactory = outputStreamFactory; - } - - public InputStream getData() { - return data; - } - - public long getDataLength() { - return dataLength; - } - - public OutputStreamFactory getOutputStreamFactory() { - return outputStreamFactory; - } - - public String getContentType() { - return contentType; - } -} diff --git a/app/src/main/java/org/session/libsignal/utilities/PushAttachmentData.java b/app/src/main/java/org/session/libsignal/utilities/PushAttachmentData.java deleted file mode 100644 index 19d83f08fa..0000000000 --- a/app/src/main/java/org/session/libsignal/utilities/PushAttachmentData.java +++ /dev/null @@ -1,44 +0,0 @@ -/** - * Copyright (C) 2014-2016 Open Whisper Systems - * - * Licensed according to the LICENSE file in this repository. - */ - -package org.session.libsignal.utilities; - -import org.session.libsignal.streams.OutputStreamFactory; - -import java.io.InputStream; - -public class PushAttachmentData { - - private final String contentType; - private final InputStream data; - private final long dataSize; - private final OutputStreamFactory outputStreamFactory; - - public PushAttachmentData(String contentType, InputStream data, long dataSize, - OutputStreamFactory outputStreamFactory) - { - this.contentType = contentType; - this.data = data; - this.dataSize = dataSize; - this.outputStreamFactory = outputStreamFactory; - } - - public String getContentType() { - return contentType; - } - - public InputStream getData() { - return data; - } - - public long getDataSize() { - return dataSize; - } - - public OutputStreamFactory getOutputStreamFactory() { - return outputStreamFactory; - } -} diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/SquareImageView.java b/app/src/main/java/org/thoughtcrime/securesms/components/SquareImageView.java deleted file mode 100644 index bebf1d88bf..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/components/SquareImageView.java +++ /dev/null @@ -1,25 +0,0 @@ -package org.thoughtcrime.securesms.components; - -import android.content.Context; -import androidx.appcompat.widget.AppCompatImageView; -import android.util.AttributeSet; - -public class SquareImageView extends AppCompatImageView { - public SquareImageView(Context context) { - super(context); - } - - public SquareImageView(Context context, AttributeSet attrs) { - super(context, attrs); - } - - public SquareImageView(Context context, AttributeSet attrs, int defStyleAttr) { - super(context, attrs, defStyleAttr); - } - - @Override - public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { - //noinspection SuspiciousNameCombination - super.onMeasure(widthMeasureSpec, widthMeasureSpec); - } -} diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/StickerView.java b/app/src/main/java/org/thoughtcrime/securesms/components/StickerView.java deleted file mode 100644 index fd20283ae1..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/components/StickerView.java +++ /dev/null @@ -1,55 +0,0 @@ -package org.thoughtcrime.securesms.components; - -import android.content.Context; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import android.util.AttributeSet; -import android.view.View; -import android.widget.FrameLayout; - -import org.thoughtcrime.securesms.conversation.v2.utilities.ThumbnailView; -import com.bumptech.glide.RequestManager; - -import org.thoughtcrime.securesms.mms.Slide; -import org.thoughtcrime.securesms.mms.SlideClickListener; -import org.thoughtcrime.securesms.mms.SlidesClickedListener; - -import network.loki.messenger.R; - -public class StickerView extends FrameLayout { - - private ThumbnailView image; - private View missingShade; - - public StickerView(@NonNull Context context) { - super(context); - init(); - } - - public StickerView(@NonNull Context context, @Nullable AttributeSet attrs) { - super(context, attrs); - init(); - } - - private void init() { - inflate(getContext(), R.layout.sticker_view, this); - - this.image = findViewById(R.id.sticker_thumbnail); - this.missingShade = findViewById(R.id.sticker_missing_shade); - } - - @Override - public void setFocusable(boolean focusable) { - image.setFocusable(focusable); - } - - @Override - public void setClickable(boolean clickable) { - image.setClickable(clickable); - } - - @Override - public void setOnLongClickListener(@Nullable OnLongClickListener l) { - image.setOnLongClickListener(l); - } -} diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobmanager/Constraint.java b/app/src/main/java/org/thoughtcrime/securesms/jobmanager/Constraint.java deleted file mode 100644 index dd766bbbb3..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/jobmanager/Constraint.java +++ /dev/null @@ -1,14 +0,0 @@ -package org.thoughtcrime.securesms.jobmanager; - -import android.app.job.JobInfo; -import androidx.annotation.NonNull; -import androidx.annotation.RequiresApi; - -public interface Constraint { - - boolean isMet(); - - interface Factory { - T create(); - } -} diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobmanager/impl/NetworkConstraint.java b/app/src/main/java/org/thoughtcrime/securesms/jobmanager/impl/NetworkConstraint.java deleted file mode 100644 index 7b128bf9fe..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/jobmanager/impl/NetworkConstraint.java +++ /dev/null @@ -1,44 +0,0 @@ -package org.thoughtcrime.securesms.jobmanager.impl; - -import android.app.Application; -import android.app.job.JobInfo; -import android.content.Context; -import android.net.ConnectivityManager; -import android.net.NetworkInfo; -import androidx.annotation.NonNull; -import androidx.annotation.RequiresApi; - -import org.thoughtcrime.securesms.jobmanager.Constraint; - -public class NetworkConstraint implements Constraint { - - public static final String KEY = "NetworkConstraint"; - - private final Application application; - - private NetworkConstraint(@NonNull Application application) { - this.application = application; - } - - @Override - public boolean isMet() { - ConnectivityManager connectivityManager = (ConnectivityManager) application.getSystemService(Context.CONNECTIVITY_SERVICE); - NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo(); - - return activeNetworkInfo != null && activeNetworkInfo.isConnected(); - } - - public static final class Factory implements Constraint.Factory { - - private final Application application; - - public Factory(@NonNull Application application) { - this.application = application; - } - - @Override - public NetworkConstraint create() { - return new NetworkConstraint(application); - } - } -} diff --git a/app/src/main/java/org/thoughtcrime/securesms/mediasend/FlipTransformation.java b/app/src/main/java/org/thoughtcrime/securesms/mediasend/FlipTransformation.java deleted file mode 100644 index 0c4749b338..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/mediasend/FlipTransformation.java +++ /dev/null @@ -1,33 +0,0 @@ -package org.thoughtcrime.securesms.mediasend; - -import android.graphics.Bitmap; -import android.graphics.Canvas; -import android.graphics.Matrix; -import androidx.annotation.NonNull; - -import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool; -import com.bumptech.glide.load.resource.bitmap.BitmapTransformation; - -import java.security.MessageDigest; - -public class FlipTransformation extends BitmapTransformation { - - @Override - protected Bitmap transform(@NonNull BitmapPool pool, @NonNull Bitmap toTransform, int outWidth, int outHeight) { - Bitmap output = pool.get(toTransform.getWidth(), toTransform.getHeight(), toTransform.getConfig()); - - Canvas canvas = new Canvas(output); - Matrix matrix = new Matrix(); - matrix.setScale(-1, 1); - matrix.postTranslate(toTransform.getWidth(), 0); - - canvas.drawBitmap(toTransform, matrix, null); - - return output; - } - - @Override - public void updateDiskCacheKey(@NonNull MessageDigest messageDigest) { - messageDigest.update(FlipTransformation.class.getSimpleName().getBytes()); - } -} diff --git a/app/src/main/java/org/thoughtcrime/securesms/mediasend/OrderEnforcer.java b/app/src/main/java/org/thoughtcrime/securesms/mediasend/OrderEnforcer.java deleted file mode 100644 index 65974ac0c1..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/mediasend/OrderEnforcer.java +++ /dev/null @@ -1,91 +0,0 @@ -package org.thoughtcrime.securesms.mediasend; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; - -import java.util.LinkedHashMap; -import java.util.Map; -import java.util.Stack; - -@SuppressWarnings("ConstantConditions") -public class OrderEnforcer { - - private final Map stages = new LinkedHashMap<>(); - - public OrderEnforcer(@NonNull E... stages) { - for (E stage : stages) { - this.stages.put(stage, new StageDetails()); - } - } - - public synchronized void run(@NonNull E stage, Runnable r) { - if (isCompletedThrough(stage)) { - r.run(); - } else { - stages.get(stage).addAction(r); - } - } - - public synchronized void markCompleted(@NonNull E stage) { - stages.get(stage).markCompleted(); - - for (E s : stages.keySet()) { - StageDetails details = stages.get(s); - - if (details.isCompleted()) { - while (details.hasAction()) { - details.popAction().run(); - } - } else { - break; - } - } - } - - public synchronized void reset() { - for (StageDetails details : stages.values()) { - details.reset(); - } - } - - private boolean isCompletedThrough(@NonNull E stage) { - for (E s : stages.keySet()) { - if (s.equals(stage)) { - return stages.get(s).isCompleted(); - } else if (!stages.get(s).isCompleted()) { - return false; - } - } - return false; - } - - private static class StageDetails { - private boolean completed = false; - private Stack actions = new Stack<>(); - - boolean hasAction() { - return !actions.isEmpty(); - } - - @Nullable Runnable popAction() { - return actions.pop(); - } - - void addAction(@NonNull Runnable runnable) { - actions.push(runnable); - } - - void reset() { - actions.clear(); - completed = false; - } - - boolean isCompleted() { - return completed; - } - - void markCompleted() { - completed = true; - } - } -} diff --git a/app/src/main/java/org/thoughtcrime/securesms/reviews/ui/InAppReview.kt b/app/src/main/java/org/thoughtcrime/securesms/reviews/ui/InAppReview.kt index e95ac03390..ca784a9770 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/reviews/ui/InAppReview.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/reviews/ui/InAppReview.kt @@ -13,6 +13,7 @@ import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue +import androidx.compose.ui.graphics.Color import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.AnnotatedString @@ -128,6 +129,8 @@ private fun InAppReviewDialog( message: String, positiveButtonText: String, negativeButtonText: String? = null, + positiveButtonTextColor: Color = LocalColors.current.accentText, + negativeButtonTextColor: Color = LocalColors.current.text, positiveButtonQaTag: String, negativeButtonQaTag: String? = null, sendCommands: (InAppReviewViewModel.UiCommand) -> Unit, @@ -135,7 +138,7 @@ private fun InAppReviewDialog( val buttons = mutableListOf( DialogButtonData( text = GetString.FromString(positiveButtonText), - color = LocalColors.current.accentText, + color = positiveButtonTextColor, qaTag = positiveButtonQaTag, dismissOnClick = false ) { @@ -147,6 +150,7 @@ private fun InAppReviewDialog( buttons.add( DialogButtonData( text = GetString.FromString(negativeButtonText), + color = negativeButtonTextColor, qaTag = negativeButtonQaTag, dismissOnClick = false ) { @@ -183,10 +187,12 @@ private fun InAppReviewStartPrompt( .put(EMOJI_KEY, "❤\uFE0F") .format() .toString(), + negativeButtonTextColor = LocalColors.current.accentText, positiveButtonText = Phrase.from(context, R.string.enjoyingSessionButtonNegative) .put(EMOJI_KEY, "\uD83D\uDE15") .format() .toString(), + positiveButtonTextColor = LocalColors.current.text, negativeButtonQaTag = stringResource(R.string.qa_inapp_review_dialog_button_great), positiveButtonQaTag = stringResource(R.string.qa_inapp_review_dialog_button_work), sendCommands = sendCommands diff --git a/app/src/main/java/org/thoughtcrime/securesms/util/SingleLiveEvent.java b/app/src/main/java/org/thoughtcrime/securesms/util/SingleLiveEvent.java deleted file mode 100644 index 97b52c9b9f..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/util/SingleLiveEvent.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright 2017 Google Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.thoughtcrime.securesms.util; - -import androidx.lifecycle.LifecycleOwner; -import androidx.lifecycle.MutableLiveData; -import androidx.lifecycle.Observer; -import androidx.annotation.MainThread; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; - -import org.session.libsignal.utilities.Log; - -import java.util.concurrent.atomic.AtomicBoolean; - -/** - * A lifecycle-aware observable that sends only new updates after subscription, used for events like - * navigation and Snackbar messages. - *

- * This avoids a common problem with events: on configuration change (like rotation) an update - * can be emitted if the observer is active. This LiveData only calls the observable if there's an - * explicit call to setValue() or call(). - *

- * Note that only one observer is going to be notified of changes. - */ -public class SingleLiveEvent extends MutableLiveData { - - private static final String TAG = SingleLiveEvent.class.getSimpleName(); - - private final AtomicBoolean mPending = new AtomicBoolean(false); - - @MainThread - public void observe(@NonNull LifecycleOwner owner, @NonNull final Observer observer) { - if (hasActiveObservers()) { - Log.w(TAG, "Multiple observers registered but only one will be notified of changes."); - } - - // Observe the internal MutableLiveData - super.observe(owner, t -> { - if (mPending.compareAndSet(true, false)) { - observer.onChanged(t); - } - }); - } - - @MainThread - public void setValue(@Nullable T t) { - mPending.set(true); - super.setValue(t); - } - - /** - * Used for cases where T is Void, to make calls cleaner. - */ - @MainThread - public void call() { - setValue(null); - } -} diff --git a/app/src/main/java/org/thoughtcrime/securesms/util/WorkerThread.java b/app/src/main/java/org/thoughtcrime/securesms/util/WorkerThread.java deleted file mode 100644 index 7d77f54310..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/util/WorkerThread.java +++ /dev/null @@ -1,48 +0,0 @@ -/** - * Copyright (C) 2011 Whisper Systems - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package org.thoughtcrime.securesms.util; - -import java.util.List; - -public class WorkerThread extends Thread { - - private final List workQueue; - - public WorkerThread(List workQueue, String name) { - super(name); - this.workQueue = workQueue; - } - - private Runnable getWork() { - synchronized (workQueue) { - try { - while (workQueue.isEmpty()) - workQueue.wait(); - - return workQueue.remove(0); - } catch (InterruptedException ie) { - throw new AssertionError(ie); - } - } - } - - @Override - public void run() { - for (;;) - getWork().run(); - } -} diff --git a/app/src/main/res/layout/sticker_view.xml b/app/src/main/res/layout/sticker_view.xml deleted file mode 100644 index c3d1e47277..0000000000 --- a/app/src/main/res/layout/sticker_view.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - - - diff --git a/app/src/test/java/org/thoughtcrime/securesms/camera/OrderEnforcerTest.java b/app/src/test/java/org/thoughtcrime/securesms/camera/OrderEnforcerTest.java deleted file mode 100644 index fece0f7805..0000000000 --- a/app/src/test/java/org/thoughtcrime/securesms/camera/OrderEnforcerTest.java +++ /dev/null @@ -1,105 +0,0 @@ -package org.thoughtcrime.securesms.camera; - -import org.junit.Test; -import org.thoughtcrime.securesms.mediasend.OrderEnforcer; - -import java.util.concurrent.atomic.AtomicInteger; - -import static junit.framework.Assert.assertEquals; - -public class OrderEnforcerTest { - - @Test - public void markCompleted_singleEntry() { - AtomicInteger counter = new AtomicInteger(0); - - OrderEnforcer enforcer = new OrderEnforcer<>(Stage.A, Stage.B, Stage.C, Stage.D); - enforcer.run(Stage.A, new CountRunnable(counter)); - assertEquals(0, counter.get()); - - enforcer.markCompleted(Stage.A); - assertEquals(1, counter.get()); - } - - @Test - public void markCompleted_singleEntry_waterfall() { - AtomicInteger counter = new AtomicInteger(0); - - OrderEnforcer enforcer = new OrderEnforcer<>(Stage.A, Stage.B, Stage.C, Stage.D); - enforcer.run(Stage.C, new CountRunnable(counter)); - assertEquals(0, counter.get()); - - enforcer.markCompleted(Stage.A); - assertEquals(0, counter.get()); - - enforcer.markCompleted(Stage.C); - assertEquals(0, counter.get()); - - enforcer.markCompleted(Stage.B); - assertEquals(1, counter.get()); - } - - @Test - public void markCompleted_multipleEntriesPerStage_waterfall() { - AtomicInteger counter = new AtomicInteger(0); - - OrderEnforcer enforcer = new OrderEnforcer<>(Stage.A, Stage.B, Stage.C, Stage.D); - - enforcer.run(Stage.A, new CountRunnable(counter)); - enforcer.run(Stage.A, new CountRunnable(counter)); - assertEquals(0, counter.get()); - - enforcer.run(Stage.B, new CountRunnable(counter)); - enforcer.run(Stage.B, new CountRunnable(counter)); - assertEquals(0, counter.get()); - - enforcer.run(Stage.C, new CountRunnable(counter)); - enforcer.run(Stage.C, new CountRunnable(counter)); - assertEquals(0, counter.get()); - - enforcer.run(Stage.D, new CountRunnable(counter)); - enforcer.run(Stage.D, new CountRunnable(counter)); - assertEquals(0, counter.get()); - - enforcer.markCompleted(Stage.A); - assertEquals(counter.get(), 2); - - enforcer.markCompleted(Stage.D); - assertEquals(counter.get(), 2); - - enforcer.markCompleted(Stage.B); - assertEquals(counter.get(), 4); - - enforcer.markCompleted(Stage.C); - assertEquals(counter.get(), 8); - } - - @Test - public void run_alreadyCompleted() { - AtomicInteger counter = new AtomicInteger(0); - - OrderEnforcer enforcer = new OrderEnforcer<>(Stage.A, Stage.B, Stage.C, Stage.D); - enforcer.markCompleted(Stage.A); - enforcer.markCompleted(Stage.B); - - enforcer.run(Stage.B, new CountRunnable(counter)); - assertEquals(1, counter.get()); - } - - private static class CountRunnable implements Runnable { - private final AtomicInteger counter; - - public CountRunnable(AtomicInteger counter) { - this.counter = counter; - } - - @Override - public void run() { - counter.incrementAndGet(); - } - } - - private enum Stage { - A, B, C, D - } -}