Compare commits

..

2 Commits

171 changed files with 365 additions and 1218 deletions
+1 -7
View File
@@ -4,20 +4,14 @@ on:
workflows: ["Upload Preview APK"]
types: [completed]
permissions: {}
jobs:
artifacts-url-comments:
name: add artifact links to pull request
permissions:
pull-requests: write
actions: read
contents: read
runs-on: ubuntu-latest
if: ${{ github.event.workflow_run.conclusion == 'success' }}
steps:
- name: add artifact links to pull request
uses: tonyhallett/artifacts-url-comments@0965ff1a7ae03c5c1644d3c30f956effea4e05ef # v1.1.0
uses: tonyhallett/artifacts-url-comments@v1.1.0
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
+3 -6
View File
@@ -10,8 +10,6 @@ on:
- 'jni/dc_wrapper.c'
- 'scripts/ndk-make.sh'
permissions: {}
jobs:
build:
runs-on: ubuntu-latest
@@ -19,15 +17,14 @@ jobs:
- uses: actions/checkout@v5
with:
submodules: recursive
persist-credentials: false
- uses: android-actions/setup-android@40fd30fb8d7440372e1316f5d1809ec01dcd3699 # v4.0.1
- uses: nttld/setup-ndk@ed92fe6cadad69be94a966a7ee3271275e62f779 # v1.6.0
- uses: android-actions/setup-android@v3
- uses: nttld/setup-ndk@v1
id: setup-ndk
with:
ndk-version: r27
- uses: Swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4 # v2.9.1
- uses: Swatinem/rust-cache@v2
with:
workspaces: jni/deltachat-core-rust
+1 -5
View File
@@ -5,8 +5,6 @@ on:
branches: [main]
pull_request:
permissions: {}
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: ${{ github.ref != 'refs/heads/main' }}
@@ -19,8 +17,6 @@ jobs:
contents: read
steps:
- uses: actions/checkout@v5
with:
persist-credentials: false
- uses: actions/setup-java@v5
with:
java-version: 17
@@ -34,6 +30,6 @@ jobs:
restore-keys: |
${{ runner.os }}-gradle-
- name: Validate Gradle Wrapper
uses: gradle/actions/wrapper-validation@50e97c2cd7a37755bbfafc9c5b7cafaece252f6e # v6.1.0
uses: gradle/actions/wrapper-validation@v4
- name: Check formatting
run: ./gradlew spotlessCheck
+4 -7
View File
@@ -6,8 +6,6 @@ concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: ${{ github.ref != 'refs/heads/main' }}
permissions: {}
jobs:
build:
name: Upload Preview APK
@@ -16,7 +14,6 @@ jobs:
- uses: actions/checkout@v5
with:
submodules: recursive
persist-credentials: false
- name: Validate Fastlane Metadata
uses: ashutoshgngwr/validate-fastlane-supply-metadata@v2
@@ -36,15 +33,15 @@ jobs:
${{ runner.os }}-gradle-
- name: Validate Gradle Wrapper
uses: gradle/actions/wrapper-validation@50e97c2cd7a37755bbfafc9c5b7cafaece252f6e # v6.1.0
uses: gradle/actions/wrapper-validation@v4
- uses: android-actions/setup-android@40fd30fb8d7440372e1316f5d1809ec01dcd3699 # v4.0.1
- uses: nttld/setup-ndk@ed92fe6cadad69be94a966a7ee3271275e62f779 # v1.6.0
- uses: android-actions/setup-android@v3
- uses: nttld/setup-ndk@v1
id: setup-ndk
with:
ndk-version: r27
- uses: Swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4 # v2.9.1
- uses: Swatinem/rust-cache@v2
with:
workspaces: jni/deltachat-core-rust
-26
View File
@@ -1,26 +0,0 @@
name: GitHub Actions Security Analysis with zizmor
on:
push:
branches: ["main"]
pull_request:
branches: ["**"]
permissions: {}
jobs:
zizmor:
name: Run zizmor
runs-on: ubuntu-latest
permissions:
security-events: write # Required for upload-sarif (used by zizmor-action) to upload SARIF files.
contents: read
actions: read
steps:
- name: Checkout repository
uses: actions/checkout@v6
with:
persist-credentials: false
- name: Run zizmor
uses: zizmorcore/zizmor-action@b1d7e1fb5de872772f31590499237e7cce841e8e # v0.5.3
-6
View File
@@ -1,6 +0,0 @@
rules:
unpinned-uses:
config:
policies:
actions/*: ref-pin
dependabot/*: ref-pin
+1 -2
View File
@@ -244,8 +244,7 @@ $ANDROID_NDK_ROOT/ndk-stack --sym obj/local/armeabi-v7a --dump crash.txt > decod
Replace `armeabi-v7a` by the correct architecture the logs come from (can be guessed by trial and error)
### Deobfuscating Java Stack Traces
### Deobfuscating Java/Kotlin Stack Traces
Because the app uses code minification (ProGuard/R8), Java stack traces in crash reports are obfuscated.
To decode them, use `retrace` with the `mapping.txt` file that is included in the symbols zip:
-9
View File
@@ -4,18 +4,9 @@
* Better incoming call system integration
* Calls are not experimental anymore and don't need to be manually enabled
* Channels are no longer experimental and are available by default
* Display a permanent notification when doing location streaming and get rid of dangerous "Access Location in Background" permission
* Autoplay all voice messages in a chat
* Allow to share location for 24 hours
* Allow mini-apps to play audio without user interaction
* Mark chats as unread (long tap a chat and select the corresponding option from the three-dot-menu)
* Add "Mark all as read" option to profile menu in the profile switcher
* Fix process of upgrading from a very old version of the app
* Show more recent added stickers at the top of the sticker picker
* Allow to open links in messages via actions in TalkBack menu
* Allow to open map if user clicks "Location streaming enabled" system message
* Fix: do not accidentally set draft in chats that don't allow sending messages
## v2.49.0
2026-04
@@ -39,7 +39,7 @@ public class EnterChatsBenchmark {
// PLEASE BACKUP YOUR ACCOUNT BEFORE RUNNING THIS!
// ==============================================================================================
private static final String TAG = "EnterChatsBenchmark";
private static final String TAG = EnterChatsBenchmark.class.getSimpleName();
@Rule
public ActivityScenarioRule<ConversationListActivity> activityRule =
@@ -6,7 +6,7 @@ import android.util.Log;
/** Non-GMS, always uses the platform LocationManager. */
public final class LocationSourceFactory {
private static final String TAG = "LocationSourceFactory";
private static final String TAG = LocationSourceFactory.class.getSimpleName();
private LocationSourceFactory() {}
@@ -14,7 +14,7 @@ import com.google.android.gms.location.Priority;
public class GmsLocationSource implements LocationSource {
private static final String TAG = "GmsLocationSource";
private static final String TAG = GmsLocationSource.class.getSimpleName();
private static final long UPDATE_INTERVAL_MS = 3_000;
private static final long FASTEST_INTERVAL_MS = 1_000;
@@ -11,7 +11,7 @@ import com.google.android.gms.common.GoogleApiAvailability;
*/
public final class LocationSourceFactory {
private static final String TAG = "LocationSourceFactory";
private static final String TAG = LocationSourceFactory.class.getSimpleName();
private LocationSourceFactory() {}
@@ -17,7 +17,7 @@ import org.thoughtcrime.securesms.service.FetchForegroundService;
import org.thoughtcrime.securesms.util.Util;
public class FcmReceiveService extends FirebaseMessagingService {
private static final String TAG = "FcmReceiveService";
private static final String TAG = FcmReceiveService.class.getSimpleName();
private static final Object INIT_LOCK = new Object();
private static boolean initialized;
private static volatile boolean triedRegistering;
+1 -2
View File
@@ -71,7 +71,6 @@
android:name="android.permission.FOREGROUND_SERVICE_MEDIA_PLAYBACK" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_CAMERA" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_MICROPHONE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_PHONE_CALL" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_LOCATION" />
<uses-permission android:name="android.permission.MANAGE_OWN_CALLS" />
@@ -491,7 +490,7 @@
android:name=".calls.CallService"
android:enabled="true"
android:exported="false"
android:foregroundServiceType="camera|microphone|phoneCall" />
android:foregroundServiceType="camera|microphone" />
<receiver
android:name=".notifications.MarkReadReceiver"
@@ -59,6 +59,8 @@ public class DcMsg {
public static final int DC_VIDEOCHATTYPE_UNKNOWN = 0;
public static final int DC_VIDEOCHATTYPE_BASICWEBRTC = 1;
private static final String TAG = DcMsg.class.getSimpleName();
public DcMsg(DcContext context, int viewtype) {
msgCPtr = context.createMsgCPtr(viewtype);
}
@@ -27,7 +27,6 @@ import com.google.android.material.tabs.TabLayout;
import com.google.common.util.concurrent.ListenableFuture;
import java.util.ArrayList;
import org.thoughtcrime.securesms.components.audioplay.AudioPlaybackViewModel;
import org.thoughtcrime.securesms.components.audioplay.ChatAudioQueueProvider;
import org.thoughtcrime.securesms.connect.DcEventCenter;
import org.thoughtcrime.securesms.connect.DcHelper;
import org.thoughtcrime.securesms.service.AudioPlaybackService;
@@ -36,7 +35,7 @@ import org.thoughtcrime.securesms.util.ViewUtil;
public class AllMediaActivity extends PassphraseRequiredActionBarActivity
implements DcEventCenter.DcEventDelegate {
private static final String TAG = "AllMediaActivity";
private static final String TAG = AllMediaActivity.class.getSimpleName();
public static final String CHAT_ID_EXTRA = "chat_id";
public static final String CONTACT_ID_EXTRA = "contact_id";
@@ -108,9 +107,7 @@ public class AllMediaActivity extends PassphraseRequiredActionBarActivity
eventCenter.addObserver(DcContext.DC_EVENT_CHAT_MODIFIED, this);
eventCenter.addObserver(DcContext.DC_EVENT_CONTACTS_CHANGED, this);
int accountId = DcHelper.getAccounts(this).getSelectedAccount().getAccountId();
playbackViewModel = new ViewModelProvider(this).get(AudioPlaybackViewModel.class);
playbackViewModel.setQueueProvider(new ChatAudioQueueProvider(this, chatId, accountId));
initializeMediaController();
}
@@ -122,7 +119,6 @@ public class AllMediaActivity extends PassphraseRequiredActionBarActivity
mediaController = null;
playbackViewModel.setMediaController(null);
}
playbackViewModel.setQueueProvider(null);
super.onDestroy();
}
@@ -52,7 +52,7 @@ import org.thoughtcrime.securesms.util.Util;
import org.thoughtcrime.securesms.webxdc.WebxdcGarbageCollectionWorker;
public class ApplicationContext extends MultiDexApplication {
private static final String TAG = "ApplicationContext";
private static final String TAG = ApplicationContext.class.getSimpleName();
private static final Object initLock = new Object();
private static volatile boolean isInitialized = false;
@@ -218,7 +218,7 @@ public class ApplicationContext extends MultiDexApplication {
Log.i(TAG, "DcAccounts created");
rpc = new Rpc(new FFITransport(dcAccounts.getJsonrpcInstance()));
Log.i(TAG, "Rpc created");
AccountManager.getInstance().migrateToDcAccounts(this, dcAccounts);
AccountManager.getInstance().migrateToDcAccounts(this);
int[] allAccounts = dcAccounts.getAll();
Log.i(TAG, "Number of profiles: " + allAccounts.length);
@@ -20,7 +20,7 @@ import org.thoughtcrime.securesms.util.ViewUtil;
public abstract class BaseActionBarActivity extends AppCompatActivity {
private static final String TAG = "BaseActionBarActivity";
private static final String TAG = BaseActionBarActivity.class.getSimpleName();
protected DynamicTheme dynamicTheme = new DynamicTheme();
protected void onPreCreate() {
@@ -47,7 +47,7 @@ import org.thoughtcrime.securesms.util.task.SnackbarAsyncTask;
import org.thoughtcrime.securesms.util.views.ProgressDialog;
public abstract class BaseConversationListFragment extends Fragment implements ActionMode.Callback {
private static final String TAG = "BaseConversationListFragment";
private static final String TAG = BaseConversationListFragment.class.getSimpleName();
protected ActionMode actionMode;
protected PulsingFloatingActionButton fab;
@@ -29,7 +29,7 @@ import org.thoughtcrime.securesms.util.ViewUtil;
*/
public abstract class ContactSelectionActivity extends PassphraseRequiredActionBarActivity
implements ContactSelectionListFragment.OnContactSelectedListener {
private static final String TAG = "ContactSelectionActivity";
private static final String TAG = ContactSelectionActivity.class.getSimpleName();
protected ContactSelectionListFragment contactsFragment;
@@ -67,7 +67,7 @@ import org.thoughtcrime.securesms.util.ViewUtil;
*/
public class ContactSelectionListFragment extends Fragment
implements LoaderManager.LoaderCallbacks<DcContactsLoader.Ret>, DcEventCenter.DcEventDelegate {
private static final String TAG = "ContactSelectionListFragment";
private static final String TAG = ContactSelectionListFragment.class.getSimpleName();
public static final String MULTI_SELECT = "multi_select";
public static final String SELECT_UNENCRYPTED_EXTRA = "select_unencrypted_extra";
@@ -101,7 +101,6 @@ import org.thoughtcrime.securesms.components.ScaleStableImageView;
import org.thoughtcrime.securesms.components.SendButton;
import org.thoughtcrime.securesms.components.audioplay.AudioPlaybackViewModel;
import org.thoughtcrime.securesms.components.audioplay.AudioView;
import org.thoughtcrime.securesms.components.audioplay.ChatAudioQueueProvider;
import org.thoughtcrime.securesms.components.emoji.MediaKeyboard;
import org.thoughtcrime.securesms.connect.AccountManager;
import org.thoughtcrime.securesms.connect.DcEventCenter;
@@ -149,7 +148,7 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
InputPanel.Listener,
InputPanel.MediaListener,
AudioView.OnActionListener {
private static final String TAG = "ConversationActivity";
private static final String TAG = ConversationActivity.class.getSimpleName();
public static final String ACCOUNT_ID_EXTRA = "account_id";
public static final String CHAT_ID_EXTRA = "chat_id";
@@ -224,9 +223,7 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
initializeViews();
initializeResources();
int accountId = DcHelper.getAccounts(this).getSelectedAccount().getAccountId();
playbackViewModel = new ViewModelProvider(this).get(AudioPlaybackViewModel.class);
playbackViewModel.setQueueProvider(new ChatAudioQueueProvider(this, chatId, accountId));
initializeMediaController();
initializeSecurity(false, isDefaultSms)
@@ -416,7 +413,6 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
mediaController = null;
playbackViewModel.setMediaController(null);
}
playbackViewModel.setQueueProvider(null);
super.onDestroy();
}
@@ -676,14 +672,8 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
}
public void setDraftText(String txt) {
try {
if (rpc.canSend(rpc.getSelectedAccountId(), chatId)) {
composeText.setText(txt);
composeText.setSelection(composeText.getText().length());
}
} catch (RpcException e) {
Log.e(TAG, "Rpc error", e);
}
composeText.setText(txt);
composeText.setSelection(composeText.getText().length());
}
public void hideSoftKeyboard() {
@@ -1129,7 +1119,6 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
if (chatId == DcChat.DC_CHAT_NO_CHAT)
throw new IllegalStateException("can't display a conversation for no chat.");
dcChat = DcHelper.getContext(context).getChat(chatId);
attachmentTypeSelector = null;
recipient = new Recipient(this, dcChat);
glideRequests = GlideApp.with(this);
@@ -1278,7 +1267,6 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
DcContext dcContext = DcHelper.getContext(context);
final int currentChatId = dcChat.getId();
final boolean canSend = dcChat.canSend();
Util.runOnAnyBackgroundThread(
() -> {
DcMsg msg = null;
@@ -1401,8 +1389,7 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
}
}
} else {
// set or clear draft if user can't send in chat since they can't delete it otherwise
dcContext.setDraft(currentChatId, canSend ? msg : null);
dcContext.setDraft(currentChatId, msg);
}
future.set(currentChatId);
});
@@ -80,7 +80,7 @@ import org.thoughtcrime.securesms.util.views.ConversationAdaptiveActionsToolbar;
@SuppressLint("StaticFieldLeak")
public class ConversationFragment extends MessageSelectorFragment {
private static final String TAG = "ConversationFragment";
private static final String TAG = ConversationFragment.class.getSimpleName();
private static final int SCROLL_ANIMATION_THRESHOLD = 50;
@@ -944,8 +944,6 @@ public class ConversationFragment extends MessageSelectorFragment {
WebxdcActivity.openWebxdcActivity(
getContext(), messageRecord.getParent(), messageRecord.getWebxdcHref());
}
} else if (messageRecord.getInfoType() == DcMsg.DC_INFO_LOCATIONSTREAMING_ENABLED) {
WebxdcActivity.openMaps(getContext(), (int) chatId);
} else if (messageRecord.getInfoType() == DcMsg.DC_INFO_CHAT_DESCRIPTION_CHANGED) {
Intent intent = new Intent(getContext(), ProfileActivity.class);
intent.putExtra(ProfileActivity.CHAT_ID_EXTRA, (int) chatId);
@@ -24,7 +24,6 @@ import android.graphics.PorterDuff;
import android.graphics.Rect;
import android.os.Build;
import android.text.Spannable;
import android.text.Spanned;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.util.Log;
@@ -37,7 +36,6 @@ import androidx.annotation.DimenRes;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog;
import androidx.core.view.ViewCompat;
import chat.delta.rpc.RpcException;
import chat.delta.rpc.types.CallInfo;
import chat.delta.rpc.types.CallState;
@@ -46,7 +44,6 @@ import chat.delta.rpc.types.VcardContact;
import com.b44t.messenger.DcChat;
import com.b44t.messenger.DcContact;
import com.b44t.messenger.DcMsg;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import org.thoughtcrime.securesms.calls.CallCoordinator;
@@ -75,7 +72,6 @@ import org.thoughtcrime.securesms.mms.VcardSlide;
import org.thoughtcrime.securesms.reactions.ReactionsConversationView;
import org.thoughtcrime.securesms.recipients.Recipient;
import org.thoughtcrime.securesms.util.Linkifier;
import org.thoughtcrime.securesms.util.LongClickCopySpan;
import org.thoughtcrime.securesms.util.LongClickMovementMethod;
import org.thoughtcrime.securesms.util.MarkdownUtil;
import org.thoughtcrime.securesms.util.MediaUtil;
@@ -90,7 +86,7 @@ import org.thoughtcrime.securesms.util.views.Stub;
* @author Moxie Marlinspike
*/
public class ConversationItem extends BaseConversationItem {
private static final String TAG = "ConversationItem";
private static final String TAG = ConversationItem.class.getSimpleName();
private static final Rect SWIPE_RECT = new Rect();
@@ -124,9 +120,6 @@ public class ConversationItem extends BaseConversationItem {
private Stub<CallItemView> callViewStub;
private @Nullable EventListener eventListener;
// IDs of accessibility actions registered via ViewCompat.addAccessibilityAction
private final List<Integer> linkActionIds = new ArrayList<>();
private int measureCalls;
private int incomingBubbleColor;
@@ -431,12 +424,6 @@ public class ConversationItem extends BaseConversationItem {
bodyText.setClickable(false);
bodyText.setFocusable(false);
// Remove any link actions registered for the previous message binding
for (int id : linkActionIds) {
ViewCompat.removeAccessibilityAction(this, id);
}
linkActionIds.clear();
String subject = messageRecord.getSubject();
String text = messageRecord.getText();
@@ -446,33 +433,12 @@ public class ConversationItem extends BaseConversationItem {
if (messageRecord.getType() == DcMsg.DC_MSG_CALL || text.isEmpty()) {
bodyText.setVisibility(View.GONE);
} else {
Spannable spannable = MarkdownUtil.toMarkdown(context, text);
Spannable spannable = (Spannable) MarkdownUtil.toMarkdown(context, text);
if (batchSelected.isEmpty()) {
Linkifier.linkify(spannable);
spannable = Linkifier.linkify(spannable);
}
bodyText.setText(spannable);
bodyText.setVisibility(View.VISIBLE);
// Register a TalkBack "Actions" entry for each link in the message
Spanned spanned = (Spanned) spannable;
final TextView tv = bodyText;
for (LongClickCopySpan span :
spanned.getSpans(0, spanned.length(), LongClickCopySpan.class)) {
int start = spanned.getSpanStart(span);
int end = spanned.getSpanEnd(span);
if (start >= 0 && end > start && end <= spanned.length()) {
String linkText = spanned.subSequence(start, end).toString();
String label = context.getString(R.string.accessibility_link_action, linkText);
linkActionIds.add(
ViewCompat.addAccessibilityAction(
this,
label,
(v, args) -> {
span.onClick(tv);
return true;
}));
}
}
}
int downloadState = messageRecord.getDownloadState();
@@ -91,7 +91,7 @@ import org.thoughtcrime.securesms.util.ViewUtil;
public class ConversationListActivity extends PassphraseRequiredActionBarActivity
implements ConversationListFragment.ConversationSelectedListener {
private static final String TAG = "ConversationListActivity";
private static final String TAG = ConversationListActivity.class.getSimpleName();
private static final String OPENPGP4FPR = "openpgp4fpr";
private static final String NDK_ARCH_WARNED = "ndk_arch_warned";
public static final String CLEAR_NOTIFICATIONS = "clear_notifications";
@@ -56,7 +56,7 @@ public class ConversationListFragment extends BaseConversationListFragment
public static final String ARCHIVE = "archive";
public static final String RELOAD_LIST = "reload_list";
private static final String TAG = "ConversationListFragment";
private static final String TAG = ConversationListFragment.class.getSimpleName();
private RecyclerView list;
private View emptyState;
@@ -42,7 +42,7 @@ import org.thoughtcrime.securesms.util.ViewUtil;
@SuppressLint("StaticFieldLeak")
public class CreateProfileActivity extends BaseActionBarActivity {
private static final String TAG = "CreateProfileActivity";
private static final String TAG = CreateProfileActivity.class.getSimpleName();
private static final int REQUEST_CODE_AVATAR = 1;
@@ -15,7 +15,7 @@ import org.thoughtcrime.securesms.util.ViewUtil;
public class EphemeralMessagesDialog {
private static final String TAG = "EphemeralMessagesDialog";
private static final String TAG = EphemeralMessagesDialog.class.getSimpleName();
public static void show(
final Context context,
@@ -15,7 +15,6 @@ import chat.delta.rpc.types.HttpResponse;
import com.b44t.messenger.DcContext;
import java.io.ByteArrayInputStream;
import java.lang.ref.WeakReference;
import java.util.Locale;
import org.thoughtcrime.securesms.connect.DcHelper;
import org.thoughtcrime.securesms.util.DynamicTheme;
import org.thoughtcrime.securesms.util.JsonUtils;
@@ -121,7 +120,6 @@ public class FullMsgActivity extends WebViewActivity {
try {
FullMsgActivity activity = activityReference.get();
String html = activity.dcContext.getMsgHtml(activity.msgId);
html = withAutoTextDirection(html);
activity.runOnUiThread(
() -> {
@@ -143,31 +141,6 @@ public class FullMsgActivity extends WebViewActivity {
});
}
private static String withAutoTextDirection(String html) {
if (html == null || html.isEmpty()) {
return html;
}
String lowercaseHtml = html.toLowerCase(Locale.US);
int bodyTagStart = lowercaseHtml.indexOf("<body");
if (bodyTagStart >= 0) {
int bodyTagEnd = lowercaseHtml.indexOf(">", bodyTagStart);
if (bodyTagEnd < 0) {
return html;
}
String bodyTag = html.substring(bodyTagStart, bodyTagEnd + 1);
String lowercaseBodyTag = lowercaseHtml.substring(bodyTagStart, bodyTagEnd + 1);
if (lowercaseBodyTag.contains("dir=")) {
return html;
}
if (lowercaseBodyTag.endsWith("/>")) {
return html;
}
String updatedBodyTag = bodyTag.substring(0, bodyTag.length() - 1) + " dir=\"auto\">";
return html.substring(0, bodyTagStart) + updatedBodyTag + html.substring(bodyTagEnd + 1);
}
return "<div dir=\"auto\">" + html + "</div>";
}
@Override
protected void onPause() {
super.onPause();
@@ -46,7 +46,7 @@ import org.thoughtcrime.securesms.util.ViewUtil;
public class GroupCreateActivity extends PassphraseRequiredActionBarActivity
implements ItemClickListener {
private static final String TAG = "GroupCreateActivity";
private static final String TAG = GroupCreateActivity.class.getSimpleName();
public static final String EDIT_GROUP_CHAT_ID = "edit_group_chat_id";
public static final String CREATE_BROADCAST = "create_broadcast";
public static final String UNENCRYPTED = "unencrypted";
@@ -307,7 +307,8 @@ public class GroupCreateActivity extends PassphraseRequiredActionBarActivity
private boolean showGroupNameEmptyToast(String groupName) {
if (groupName == null) {
Toast.makeText(this, getString(R.string.please_enter_chat_name), Toast.LENGTH_LONG).show();
Toast.makeText(this, getString(R.string.group_please_enter_group_name), Toast.LENGTH_LONG)
.show();
return true;
}
return false;
@@ -65,7 +65,7 @@ import org.thoughtcrime.securesms.util.views.ProgressDialog;
public class InstantOnboardingActivity extends BaseActionBarActivity
implements DcEventCenter.DcEventDelegate {
private static final String TAG = "InstantOnboardingActivity";
private static final String TAG = InstantOnboardingActivity.class.getSimpleName();
private static final String DCACCOUNT = "dcaccount";
private static final String DCLOGIN = "dclogin";
private static final String INSTANCES_URL = "https://chatmail.at/relays";
@@ -18,7 +18,7 @@ import org.thoughtcrime.securesms.util.FileProviderUtil;
public class LogViewActivity extends BaseActionBarActivity {
private static final String TAG = "LogViewActivity";
private static final String TAG = LogViewActivity.class.getSimpleName();
LogViewFragment logViewFragment;
@@ -69,7 +69,7 @@ import org.thoughtcrime.securesms.util.Util;
public class MediaPreviewActivity extends PassphraseRequiredActionBarActivity
implements RecipientModifiedListener, LoaderManager.LoaderCallbacks<DcMediaGalleryElement> {
private static final String TAG = "MediaPreviewActivity";
private static final String TAG = MediaPreviewActivity.class.getSimpleName();
public static final String ACTIVITY_TITLE_EXTRA = "activity_title";
public static final String EDIT_AVATAR_CHAT_ID = "avatar_for_chat_id";
@@ -41,7 +41,7 @@ import org.thoughtcrime.securesms.qr.QrCodeHandler;
*/
public class NewConversationActivity extends ContactSelectionActivity {
private static final String TAG = "NewConversationActivity";
private static final String TAG = NewConversationActivity.class.getSimpleName();
@Override
public void onCreate(Bundle bundle, boolean ready) {
@@ -7,7 +7,7 @@ import org.thoughtcrime.securesms.connect.DcHelper;
import org.thoughtcrime.securesms.service.GenericForegroundService;
public abstract class PassphraseRequiredActionBarActivity extends BaseActionBarActivity {
private static final String TAG = "PassphraseRequiredActionBarActivity";
private static final String TAG = PassphraseRequiredActionBarActivity.class.getSimpleName();
@Override
protected final void onCreate(Bundle savedInstanceState) {
@@ -29,7 +29,7 @@ import org.thoughtcrime.securesms.mms.GlideRequests;
import org.thoughtcrime.securesms.util.Util;
public class ProfileAdapter extends RecyclerView.Adapter {
private static final String TAG = "ProfileAdapter";
private static final String TAG = ProfileAdapter.class.getSimpleName();
public static final int ITEM_AVATAR = 10;
public static final int ITEM_DIVIDER = 20;
@@ -38,7 +38,7 @@ import org.thoughtcrime.securesms.util.ViewUtil;
public class ProfileFragment extends Fragment
implements ProfileAdapter.ItemClickListener, DcEventCenter.DcEventDelegate {
private static final String TAG = "ProfileFragment";
private static final String TAG = ProfileFragment.class.getSimpleName();
public static final String CHAT_ID_EXTRA = "chat_id";
public static final String CONTACT_ID_EXTRA = "contact_id";
@@ -17,7 +17,7 @@ import org.thoughtcrime.securesms.providers.PersistentBlobProvider;
public class ResolveMediaTask extends AsyncTask<Uri, Void, Uri> {
private static final String TAG = "ResolveMediaTask";
private static final String TAG = ResolveMediaTask.class.getSimpleName();
interface OnMediaResolvedListener {
void onMediaResolved(Uri uri);
@@ -47,7 +47,7 @@ import org.thoughtcrime.securesms.util.ShareUtil;
*/
public class ShareActivity extends PassphraseRequiredActionBarActivity
implements ResolveMediaTask.OnMediaResolvedListener {
private static final String TAG = "ShareActivity";
private static final String TAG = ShareActivity.class.getSimpleName();
public static final String EXTRA_ACC_ID = "acc_id";
public static final String EXTRA_CHAT_ID = "chat_id";
@@ -18,18 +18,21 @@ public class ShareLocationDialog {
switch (which) {
default:
case 0:
shareLocationUnit = 30 * 60;
shareLocationUnit = 5 * 60;
break;
case 1:
shareLocationUnit = 60 * 60;
shareLocationUnit = 30 * 60;
break;
case 2:
shareLocationUnit = 2 * 60 * 60;
shareLocationUnit = 60 * 60;
break;
case 3:
shareLocationUnit = 6 * 60 * 60;
shareLocationUnit = 2 * 60 * 60;
break;
case 4:
shareLocationUnit = 6 * 60 * 60;
break;
case 5:
shareLocationUnit = 24 * 60 * 60;
break;
}
@@ -32,7 +32,7 @@ import org.thoughtcrime.securesms.util.ViewUtil;
public class WebViewActivity extends PassphraseRequiredActionBarActivity
implements SearchView.OnQueryTextListener, WebView.FindListener {
private static final String TAG = "WebViewActivity";
private static final String TAG = WebViewActivity.class.getSimpleName();
// Regex to extract the host from a URL for IDN conversion.
private static final Pattern URL_PATTERN =
Pattern.compile("^((?:[a-zA-Z0-9]+://)?)([^/?#]+)(.*)$");
@@ -59,7 +59,7 @@ import org.thoughtcrime.securesms.util.MediaUtil;
import org.thoughtcrime.securesms.util.Util;
public class WebxdcActivity extends WebViewActivity implements DcEventCenter.DcEventDelegate {
private static final String TAG = "WebxdcActivity";
private static final String TAG = WebxdcActivity.class.getSimpleName();
private static final String EXTRA_ACCOUNT_ID = "accountId";
private static final String EXTRA_APP_MSG_ID = "appMessageId";
private static final String EXTRA_HIDE_ACTION_BAR = "hideActionBar";
@@ -30,7 +30,7 @@ import org.thoughtcrime.securesms.util.Util;
import org.thoughtcrime.securesms.util.ViewUtil;
public class WebxdcStoreActivity extends PassphraseRequiredActionBarActivity {
private static final String TAG = "WebxdcStoreActivity";
private static final String TAG = WebxdcStoreActivity.class.getSimpleName();
private DcContext dcContext;
private Rpc rpc;
@@ -48,7 +48,7 @@ public class WelcomeActivity extends BaseActionBarActivity
implements DcEventCenter.DcEventDelegate {
public static final String BACKUP_QR_EXTRA = "backup_qr_extra";
public static final int PICK_BACKUP = 20574;
private static final String TAG = "WelcomeActivity";
private static final String TAG = WelcomeActivity.class.getSimpleName();
public static final String TMP_BACKUP_FILE = "tmp-backup-file";
private ProgressDialog progressDialog = null;
@@ -41,7 +41,7 @@ import org.thoughtcrime.securesms.util.ViewUtil;
public class AccountSelectionListFragment extends DialogFragment
implements DcEventCenter.DcEventDelegate {
private static final String TAG = "AccountSelectionListFragment";
private static final String TAG = AccountSelectionListFragment.class.getSimpleName();
private static final String ARG_SELECT_ONLY = "select_only";
private RecyclerView recyclerView;
private AccountSelectionListAdapter adapter;
@@ -157,12 +157,6 @@ public class AccountSelectionListFragment extends DialogFragment
onSetTag(accountId);
} else if (itemId == R.id.menu_move_to_top) {
onMoveToTop(accountId);
} else if (itemId == R.id.menu_mark_all_as_read) {
try {
DcHelper.getRpc(requireActivity()).marknoticedAllChats(accountId);
} catch (RpcException e) {
Log.e(TAG, "Error calling rpc.marknoticedAllChats()", e);
}
}
}
@@ -15,7 +15,7 @@ import org.thoughtcrime.securesms.util.Prefs;
public class AudioCodec {
private static final String TAG = "AudioCodec";
private static final String TAG = AudioCodec.class.getSimpleName();
private static final int SAMPLE_RATE_BALANCED = 44100;
private static final int BIT_RATE_BALANCED = 32000;
@@ -196,7 +196,7 @@ public class AudioCodec {
setFinished();
}
},
"AudioCodec")
AudioCodec.class.getSimpleName())
.start();
}
@@ -18,7 +18,7 @@ import org.thoughtcrime.securesms.util.Util;
public class AudioRecorder {
private static final String TAG = "AudioRecorder";
private static final String TAG = AudioRecorder.class.getSimpleName();
private static final ExecutorService executor = ThreadUtil.newDynamicSingleThreadedExecutor();
@@ -20,7 +20,7 @@ import org.thoughtcrime.securesms.R;
/** Bottom sheet dialog for selecting audio output device */
@RequiresApi(Build.VERSION_CODES.O)
public class AudioDevicePickerDialog extends BottomSheetDialog {
private static final String TAG = "AudioDevicePickerDialog";
private static final String TAG = AudioDevicePickerDialog.class.getSimpleName();
public interface OnDeviceSelectedListener {
void onDeviceSelected(CallEndpointCompat endpoint);
@@ -51,7 +51,7 @@ import org.webrtc.VideoTrack;
@RequiresApi(api = Build.VERSION_CODES.O)
public class CallActivity extends AppCompatActivity {
private static final String TAG = "CallActivity";
private static final String TAG = CallActivity.class.getSimpleName();
private static final int MIC_PERMISSION_REQUEST_CODE = 1001;
private static final int CAMERA_PERMISSION_REQUEST_CODE = 1002;
@@ -63,7 +63,7 @@ import org.webrtc.VideoTrack;
@RequiresApi(api = Build.VERSION_CODES.O)
public class CallCoordinator implements DcEventCenter.DcEventDelegate {
private static final String TAG = "CallCoordinator";
private static final String TAG = CallCoordinator.class.getSimpleName();
// Notification channels
private static final String CHANNEL_ID_INCOMING = "voip_incoming_calls";
@@ -215,8 +215,7 @@ public class CallCoordinator implements DcEventCenter.DcEventDelegate {
calleeName = "Unknown";
}
showOrUpdateOngoingNotification(
appContext.getString(R.string.calling_person, calleeName));
showOrUpdateOngoingNotification("Calling " + calleeName + "...");
}
// Initialize call
@@ -403,15 +402,6 @@ public class CallCoordinator implements DcEventCenter.DcEventDelegate {
callService.stopRingtone();
}
// Promote the service to foreground immediately. Waiting until onIncomingCallAccepted
// on executor pool thread is too late on stricter OEM.
//
// Do not cancel() but use showOrUpdateOngoingNotification to replace incoming
// notification without a gap.
String callerName = displayName.getValue();
if (callerName == null) callerName = "Unknown";
showOrUpdateOngoingNotification(appContext.getString(R.string.call_with, callerName));
// Notify Android system with CallControlScope
CallControlScope scope = activeCallControlScope;
if (scope != null) {
@@ -435,6 +425,8 @@ public class CallCoordinator implements DcEventCenter.DcEventDelegate {
}
});
}
notificationManager.cancel(NOTIFICATION_ID_CALL);
}
public void answerWebRTC() {
@@ -929,7 +921,7 @@ public class CallCoordinator implements DcEventCenter.DcEventDelegate {
callerName = "Unknown";
}
showOrUpdateOngoingNotification(appContext.getString(R.string.call_with, callerName));
showOrUpdateOngoingNotification("Call with " + callerName);
}
private synchronized void onCallAnsweredOnOtherDevice() {
@@ -1016,7 +1008,7 @@ public class CallCoordinator implements DcEventCenter.DcEventDelegate {
if (calleeName == null) {
calleeName = "Unknown";
}
showOrUpdateOngoingNotification(appContext.getString(R.string.call_with, calleeName));
showOrUpdateOngoingNotification("Call with " + calleeName);
}
private synchronized void onCallEnded(int accId, int callId) {
@@ -1109,14 +1101,6 @@ public class CallCoordinator implements DcEventCenter.DcEventDelegate {
return;
}
if (callService != null) {
try {
callService.stopForegroundAndDismiss();
} catch (Exception e) {
Log.w(TAG, "stopForegroundAndDismiss failed", e);
}
}
// Clear state
this.activeAccId = null;
this.activeCallId = null;
@@ -4,7 +4,6 @@ import android.app.Notification;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ServiceInfo;
import android.media.AudioAttributes;
import android.media.AudioFocusRequest;
import android.media.AudioManager;
@@ -14,9 +13,7 @@ import android.media.ToneGenerator;
import android.net.Uri;
import android.os.Binder;
import android.os.Build;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.util.Log;
import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
@@ -36,7 +33,7 @@ import org.webrtc.VideoTrack;
@RequiresApi(api = Build.VERSION_CODES.O)
public class CallService extends Service implements WebRTCClient.Callbacks {
private static final String TAG = "CallService";
private static final String TAG = CallService.class.getSimpleName();
private final IBinder binder = new LocalBinder();
@@ -435,12 +432,6 @@ public class CallService extends Service implements WebRTCClient.Callbacks {
disposeWebRTC();
try {
stopForeground(STOP_FOREGROUND_REMOVE);
} catch (Exception e) {
Log.w(TAG, "stopForeground failed", e);
}
stopService();
}
@@ -503,44 +494,13 @@ public class CallService extends Service implements WebRTCClient.Callbacks {
// Foreground Notification
public void startForegroundWithNotification(int id, Notification notification) {
// Always run on main thread
if (Looper.myLooper() != Looper.getMainLooper()) {
new Handler(Looper.getMainLooper())
.post(() -> startForegroundWithNotification(id, notification));
return;
}
Log.d(TAG, "Starting call FGS with notification id: " + id);
try {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
startForeground(id, notification, ServiceInfo.FOREGROUND_SERVICE_TYPE_PHONE_CALL);
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
int types =
ServiceInfo.FOREGROUND_SERVICE_TYPE_MICROPHONE
| ServiceInfo.FOREGROUND_SERVICE_TYPE_CAMERA;
startForeground(id, notification, types);
} else {
startForeground(id, notification);
}
} catch (Exception e) {
Log.e(TAG, "startForeground failed", e);
if (callCoordinator != null) {
callCoordinator.reportError("Failed to activate call FGS: " + e.getMessage());
}
}
Log.d(TAG, "Starting foreground with notification id: " + id);
startForeground(id, notification);
}
public void stopForegroundAndDismiss() {
if (Looper.myLooper() != Looper.getMainLooper()) {
new Handler(Looper.getMainLooper()).post(this::stopForegroundAndDismiss);
return;
}
Log.d(TAG, "Stopping call FGS and dismissing notification");
try {
stopForeground(STOP_FOREGROUND_REMOVE);
} catch (Exception e) {
Log.w(TAG, "stopForeground failed", e);
}
Log.d(TAG, "Stopping foreground and dismissing notification");
stopForeground(STOP_FOREGROUND_REMOVE);
}
// Cleanup
@@ -21,7 +21,7 @@ import org.thoughtcrime.securesms.recipients.Recipient;
import org.thoughtcrime.securesms.util.BitmapUtil;
public class CallUtil {
private static final String TAG = "CallUtil";
private static final String TAG = CallUtil.class.getSimpleName();
@RequiresApi(api = Build.VERSION_CODES.O)
public static void startAudioCall(Context context, int chatId) {
@@ -20,7 +20,7 @@ import org.webrtc.VideoTrack;
@RequiresApi(api = Build.VERSION_CODES.O)
public class CallViewModel extends AndroidViewModel {
private static final String TAG = "CallViewModel";
private static final String TAG = CallViewModel.class.getSimpleName();
private final CallCoordinator callCoordinator;
@@ -24,7 +24,7 @@ import org.webrtc.VideoTrack;
public class MediaStreamManager {
private static final String TAG = "MediaStreamManager";
private static final String TAG = MediaStreamManager.class.getSimpleName();
private static final String STREAM_ID = "local_stream";
private static final String AUDIO_TRACK_ID = "audio_track";
private static final String VIDEO_TRACK_ID = "video_track";
@@ -92,10 +92,6 @@ public class AttachmentTypeSelector extends PopupWindow {
ViewUtil.findById(layout, R.id.location_linear_layout).setVisibility(View.GONE);
}
if (DcHelper.getContext(context).getChat(chatId).isOutBroadcast()) {
ViewUtil.findById(layout, R.id.webxdc_linear_layout).setVisibility(View.GONE);
}
setLocationButtonImage(context);
setContentView(layout);
@@ -15,7 +15,7 @@ import org.thoughtcrime.securesms.R;
import org.thoughtcrime.securesms.util.DateUtils;
public class CallItemView extends FrameLayout {
private static final String TAG = "CallItemView";
private static final String TAG = CallItemView.class.getSimpleName();
private final @NonNull ImageView icon;
private final @NonNull TextView title;
@@ -43,7 +43,7 @@ public class InputPanel extends ConstraintLayout
KeyboardAwareLinearLayout.OnKeyboardShownListener,
MediaKeyboard.MediaKeyboardListener {
private static final String TAG = "InputPanel";
private static final String TAG = InputPanel.class.getSimpleName();
private static final int FADE_TIME = 150;
@@ -38,7 +38,7 @@ import org.thoughtcrime.securesms.util.ViewUtil;
* been opened and what its height would be.
*/
public class KeyboardAwareLinearLayout extends LinearLayoutCompat {
private static final String TAG = "KeyboardAwareLinearLayout";
private static final String TAG = KeyboardAwareLinearLayout.class.getSimpleName();
private static final long KEYBOARD_DEBOUNCE = 150;
@@ -38,7 +38,7 @@ import org.thoughtcrime.securesms.util.Util;
public class QuoteView extends FrameLayout implements RecipientForeverObserver {
private static final String TAG = "QuoteView";
private static final String TAG = QuoteView.class.getSimpleName();
private static final int MESSAGE_TYPE_PREVIEW = 0;
@@ -30,7 +30,7 @@ public class ScaleStableImageView extends AppCompatImageView
implements KeyboardAwareLinearLayout.OnKeyboardShownListener,
KeyboardAwareLinearLayout.OnKeyboardHiddenListener {
private static final String TAG = "ScaleStableImageView";
private static final String TAG = ScaleStableImageView.class.getSimpleName();
private Drawable defaultDrawable;
private Drawable currentDrawable;
@@ -22,7 +22,7 @@ import org.thoughtcrime.securesms.animation.AnimationCompleteListener;
public class SearchToolbar extends LinearLayout {
private static final String TAG = "SearchToolbar";
private static final String TAG = SearchToolbar.class.getSimpleName();
private float x, y;
private MenuItem searchItem;
private EditText searchText;
@@ -30,7 +30,7 @@ import org.thoughtcrime.securesms.util.Util;
public class ThumbnailView extends FrameLayout {
private static final String TAG = "ThumbnailView";
private static final String TAG = ThumbnailView.class.getSimpleName();
private static final int WIDTH = 0;
private static final int HEIGHT = 1;
private static final int MIN_WIDTH = 0;
@@ -17,7 +17,7 @@ import org.thoughtcrime.securesms.mms.VcardSlide;
import org.thoughtcrime.securesms.recipients.Recipient;
public class VcardView extends FrameLayout {
private static final String TAG = "VcardView";
private static final String TAG = VcardView.class.getSimpleName();
private final @NonNull AvatarView avatar;
private final @NonNull TextView name;
@@ -6,26 +6,22 @@ import android.net.Uri;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.ViewModel;
import androidx.media3.common.MediaItem;
import androidx.media3.common.PlaybackException;
import androidx.media3.common.Player;
import androidx.media3.session.MediaController;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class AudioPlaybackViewModel extends ViewModel {
private static final String TAG = "AudioPlaybackViewModel";
private static final String TAG = AudioPlaybackViewModel.class.getSimpleName();
private static final int NON_MESSAGE_AUDIO_MSG_ID =
0; // Audios not attached to a message doesn't have message id.
@@ -38,8 +34,6 @@ public class AudioPlaybackViewModel extends ViewModel {
private final ExecutorService extractionExecutor = Executors.newFixedThreadPool(2);
private @Nullable MediaController mediaController;
private @Nullable ChatAudioQueueProvider queueProvider;
private @Nullable Player.Listener playerListener;
private final Handler handler;
private boolean isUserSeeking = false;
@@ -53,11 +47,6 @@ public class AudioPlaybackViewModel extends ViewModel {
}
public void setMediaController(@Nullable MediaController controller) {
if (this.mediaController != null && playerListener != null) {
this.mediaController.removeListener(playerListener);
}
playerListener = null;
this.mediaController = controller;
if (mediaController != null && mediaController.isPlaying()) {
startUpdateProgress();
@@ -70,41 +59,30 @@ public class AudioPlaybackViewModel extends ViewModel {
public void loadAudioAndPlay(int msgId, Uri audioUri) {
if (mediaController == null) return;
String mediaId = String.valueOf(msgId);
// Set media item if we have a different audio.
if (isDifferentAudio(msgId, audioUri)) {
updateState(msgId, audioUri, AudioPlaybackState.PlaybackStatus.LOADING, 0, 0);
MediaItem current = mediaController.getCurrentMediaItem();
if (current != null && mediaId.equals(current.mediaId)) {
mediaController.play();
return;
MediaItem mediaItem =
new MediaItem.Builder().setMediaId(String.valueOf(msgId)).setUri(audioUri).build();
mediaController.setMediaItem(mediaItem);
mediaController.prepare();
}
updateState(msgId, audioUri, AudioPlaybackState.PlaybackStatus.LOADING, 0, 0);
List<MediaItem> items = null;
int startIndex = -1;
if (queueProvider != null) {
items = queueProvider.buildAudioQueue();
startIndex = indexOfMediaId(items, mediaId);
}
if (startIndex < 0) {
items =
Collections.singletonList(
new MediaItem.Builder().setMediaId(mediaId).setUri(audioUri).build());
startIndex = 0;
}
mediaController.setMediaItems(items, startIndex, 0);
mediaController.prepare();
mediaController.play();
play(msgId, audioUri);
}
private static int indexOfMediaId(List<MediaItem> items, String mediaId) {
for (int i = 0; i < items.size(); i++) {
if (mediaId.equals(items.get(i).mediaId)) return i;
}
return -1;
private boolean isSameAudio(int msgId, Uri audioUri) {
return !isDifferentAudio(msgId, audioUri);
}
private boolean isDifferentAudio(int msgId, Uri audioUri) {
AudioPlaybackState currentState = playbackState.getValue();
return currentState != null
&& (msgId != currentState.getMsgId()
|| currentState.getAudioUri() == null
|| currentState.getAudioUri() != null && !currentState.getAudioUri().equals(audioUri));
}
public LiveData<Map<Integer, Long>> getDurations() {
@@ -160,72 +138,46 @@ public class AudioPlaybackViewModel extends ViewModel {
}
}
public void pause(int msgId) {
if (isCurrentItem(msgId)) {
public void pause(int msgId, Uri audioUri) {
if (mediaController != null && isSameAudio(msgId, audioUri)) {
mediaController.pause();
}
}
public void play(int msgId) {
if (isCurrentItem(msgId)) {
public void play(int msgId, Uri audioUri) {
if (mediaController != null && isSameAudio(msgId, audioUri)) {
mediaController.play();
}
}
public void seekTo(long position, int msgId) {
if (isCurrentItem(msgId)) {
public void seekTo(long position, int msgId, Uri audioUri) {
if (mediaController != null && isSameAudio(msgId, audioUri)) {
mediaController.seekTo(position);
}
}
public void stop(int msgId) {
if (isCurrentItem(msgId)) {
public void stop(int msgId, Uri audioUri) {
if (mediaController != null && isSameAudio(msgId, audioUri)) {
mediaController.stop();
mediaController.clearMediaItems();
stopUpdateProgress();
playbackState.setValue(AudioPlaybackState.idle());
}
}
private boolean isCurrentItem(int msgId) {
if (mediaController == null) return false;
MediaItem current = mediaController.getCurrentMediaItem();
return current != null && String.valueOf(msgId).equals(current.mediaId);
}
public void stopNonMessageAudioPlayback() {
stopByIds(NON_MESSAGE_AUDIO_MSG_ID);
}
// A special method for deleting message, where we only use message Ids
public void stopByIds(int... msgIds) {
if (mediaController == null) return;
AudioPlaybackState currentState = playbackState.getValue();
boolean stoppedCurrent = false;
if (currentState != null) {
if (mediaController != null && currentState != null) {
for (int msgId : msgIds) {
if (msgId == currentState.getMsgId()) {
mediaController.stop();
mediaController.clearMediaItems();
stopUpdateProgress();
playbackState.setValue(AudioPlaybackState.idle());
stoppedCurrent = true;
break;
}
}
}
if (!stoppedCurrent) {
Set<String> deletedMediaIds = new HashSet<>();
for (int msgId : msgIds) {
deletedMediaIds.add(String.valueOf(msgId));
}
for (int i = mediaController.getMediaItemCount() - 1; i >= 0; i--) {
MediaItem item = mediaController.getMediaItemAt(i);
if (deletedMediaIds.contains(item.mediaId)) {
mediaController.removeMediaItem(i);
}
}
}
@@ -239,10 +191,10 @@ public class AudioPlaybackViewModel extends ViewModel {
private void setupPlayerListener() {
if (mediaController == null) return;
playerListener =
mediaController.addListener(
new Player.Listener() {
@Override
public void onEvents(@NonNull Player player, @NonNull Player.Events events) {
public void onEvents(Player player, Player.Events events) {
if (events.containsAny(Player.EVENT_IS_PLAYING_CHANGED)) {
if (player.isPlaying()) {
startUpdateProgress();
@@ -251,40 +203,20 @@ public class AudioPlaybackViewModel extends ViewModel {
}
updateCurrentState(false);
}
if (events.containsAny(Player.EVENT_MEDIA_ITEM_TRANSITION)) {
updateCurrentState(true);
}
if (events.containsAny(Player.EVENT_PLAYBACK_STATE_CHANGED)) {
if (player.getPlaybackState() == Player.STATE_READY) {
updateCurrentState(false);
} else if (player.getPlaybackState() == Player.STATE_ENDED
&& !player.hasNextMediaItem()) {
} else if (player.getPlaybackState() == Player.STATE_ENDED) {
// This is to prevent automatically playing after the audio
// has been play to the end once, then user dragged the seek bar again
mediaController.setPlayWhenReady(false);
}
}
}
@Override
public void onPlayerError(@NonNull PlaybackException error) {
Log.w(
TAG,
"Playback error on msgId="
+ (mediaController.getCurrentMediaItem() != null
? mediaController.getCurrentMediaItem().mediaId
: "null"),
error);
if (mediaController.hasNextMediaItem()) {
mediaController.seekToNextMediaItem();
mediaController.prepare();
mediaController.play();
} else {
if (events.containsAny(Player.EVENT_PLAYER_ERROR)) {
updateCurrentAudioState(AudioPlaybackState.PlaybackStatus.ERROR, 0, 0);
mediaController.clearMediaItems();
}
}
};
mediaController.addListener(playerListener);
});
}
private void updateCurrentState(boolean queryPlaying) {
@@ -353,11 +285,6 @@ public class AudioPlaybackViewModel extends ViewModel {
}
}
// Playing Queue
public void setQueueProvider(@Nullable ChatAudioQueueProvider provider) {
this.queueProvider = provider;
}
// Progress tracking
private final Runnable progressRunnable =
new Runnable() {
@@ -23,7 +23,7 @@ import org.thoughtcrime.securesms.util.DateUtils;
public class AudioView extends FrameLayout {
private static final String TAG = "AudioView";
private static final String TAG = AudioView.class.getSimpleName();
private final @NonNull ImageView playPauseButton;
private final AnimatedVectorDrawableCompat playToPauseDrawable;
@@ -109,12 +109,12 @@ public class AudioView extends FrameLayout {
AudioPlaybackState state = viewModel.getPlaybackState().getValue();
if (state != null && msgId == state.getMsgId()) {
if (state != null && msgId == state.getMsgId() && audioUri.equals(state.getAudioUri())) {
// Same audio
if (state.getStatus() == AudioPlaybackState.PlaybackStatus.PLAYING) {
viewModel.pause(msgId);
viewModel.pause(msgId, audioUri);
} else {
viewModel.play(msgId);
viewModel.play(msgId, audioUri);
}
} else {
// Different audio
@@ -145,7 +145,7 @@ public class AudioView extends FrameLayout {
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
viewModel.setUserSeeking(false);
viewModel.seekTo(seekBar.getProgress(), msgId);
viewModel.seekTo(seekBar.getProgress(), msgId, audioUri);
}
});
@@ -305,7 +305,7 @@ public class AudioView extends FrameLayout {
if (audioUri == null || state == null) return;
// Check if this state is about this message
boolean isThisMessage = msgId == state.getMsgId();
boolean isThisMessage = msgId == state.getMsgId() && audioUri.equals(state.getAudioUri());
if (isThisMessage) {
updateUIForPlaybackState(state);
@@ -340,9 +340,13 @@ public class AudioView extends FrameLayout {
private void onDurationsChanged(Map<Integer, Long> durations) {
AudioPlaybackState state = viewModel.getPlaybackState().getValue();
// When there is no playback happening, msgId can be -1
if (state != null && msgId >= 0 && msgId == state.getMsgId()) {
return;
// When there is no playback happening, msgId can be -1 and audioUri is null
if (state != null
&& msgId >= 0
&& msgId == state.getMsgId()
&& audioUri != null
&& audioUri.equals(state.getAudioUri())) {
return; // Is playing this message
}
Long duration = durations.get(msgId);
@@ -1,41 +0,0 @@
package org.thoughtcrime.securesms.components.audioplay;
import android.content.Context;
import android.net.Uri;
import androidx.annotation.NonNull;
import androidx.media3.common.MediaItem;
import com.b44t.messenger.DcContext;
import com.b44t.messenger.DcMsg;
import java.util.ArrayList;
import java.util.List;
import org.thoughtcrime.securesms.connect.DcHelper;
public class ChatAudioQueueProvider {
private final Context context;
private final int chatId;
private final int accountId;
public ChatAudioQueueProvider(@NonNull Context context, int chatId, int accountId) {
this.context = context.getApplicationContext();
this.chatId = chatId;
this.accountId = accountId;
}
@NonNull
public List<MediaItem> buildAudioQueue() {
DcContext dcContext = DcHelper.getContext(context);
int[] msgIds = dcContext.getChatMedia(chatId, DcMsg.DC_MSG_AUDIO, DcMsg.DC_MSG_VOICE, 0);
List<MediaItem> items = new ArrayList<>(msgIds.length);
for (int msgId : msgIds) {
String id = String.valueOf(msgId);
items.add(
new MediaItem.Builder()
.setMediaId(id)
.setUri(Uri.parse("dcmsg://" + accountId + "/" + id))
.build());
}
return items;
}
}
@@ -22,7 +22,7 @@ import org.thoughtcrime.securesms.util.ResUtil;
public class MediaKeyboard extends LinearLayout
implements InputView, Consumer<EmojiViewItem>, StickerPickerView.StickerPickerListener {
private static final String TAG = "MediaKeyboard";
private static final String TAG = MediaKeyboard.class.getSimpleName();
@Nullable private MediaKeyboardListener keyboardListener;
private EmojiPickerView emojiPicker;
@@ -71,7 +71,7 @@ public class StickerPickerView extends RecyclerView {
}
// Sort stickers just to provide consistent order
Collections.sort(stickerFiles, (f1, f2) -> f2.getName().compareToIgnoreCase(f1.getName()));
Collections.sort(stickerFiles, (f1, f2) -> f1.getName().compareToIgnoreCase(f2.getName()));
return stickerFiles;
}
@@ -23,7 +23,7 @@ import org.thoughtcrime.securesms.util.Prefs;
@SuppressLint("BatteryLife")
public class DozeReminder {
private static final String TAG = "DozeReminder";
private static final String TAG = DozeReminder.class.getSimpleName();
public static boolean isEligible(Context context) {
if (context == null) {
@@ -19,7 +19,7 @@ import androidx.viewpager.widget.ViewPager;
*/
public class HackyViewPager extends ViewPager {
private static final String TAG = "HackyViewPager";
private static final String TAG = HackyViewPager.class.getSimpleName();
public HackyViewPager(Context context) {
super(context);
@@ -18,7 +18,7 @@ import org.thoughtcrime.securesms.accounts.AccountSelectionListFragment;
public class AccountManager {
private static final String TAG = "AccountManager";
private static final String TAG = AccountManager.class.getSimpleName();
private static final String LAST_ACCOUNT_ID = "last_account_id";
private static AccountManager self;
@@ -38,7 +38,7 @@ public class AccountManager {
return self;
}
public void migrateToDcAccounts(Context context, DcAccounts dcAccounts) {
public void migrateToDcAccounts(ApplicationContext context) {
try {
int selectAccountId = 0;
@@ -49,7 +49,8 @@ public class AccountManager {
if (!file.isDirectory()
&& file.getName().startsWith("messenger")
&& file.getName().endsWith(".db")) {
int accountId = dcAccounts.migrateAccount(file.getAbsolutePath());
int accountId =
ApplicationContext.getDcAccounts().migrateAccount(file.getAbsolutePath());
if (accountId != 0) {
String selName =
PreferenceManager.getDefaultSharedPreferences(context)
@@ -66,7 +67,7 @@ public class AccountManager {
}
if (selectAccountId != 0) {
dcAccounts.selectAccount(selectAccountId);
ApplicationContext.getDcAccounts().selectAccount(selectAccountId);
}
} catch (Exception e) {
Log.e(TAG, "Error in migrateToDcAccounts()", e);
@@ -5,6 +5,7 @@ import androidx.annotation.NonNull;
import com.b44t.messenger.DcContact;
import com.b44t.messenger.DcContext;
import org.thoughtcrime.securesms.util.AsyncLoader;
import org.thoughtcrime.securesms.util.Prefs;
import org.thoughtcrime.securesms.util.Util;
public class DcContactsLoader extends AsyncLoader<DcContactsLoader.Ret> {
@@ -52,7 +53,10 @@ public class DcContactsLoader extends AsyncLoader<DcContactsLoader.Ret> {
}
if (query == null && addCreateGroupLinks) {
additional_items = Util.appendInt(additional_items, DcContact.DC_CONTACT_ID_NEW_GROUP);
additional_items = Util.appendInt(additional_items, DcContact.DC_CONTACT_ID_NEW_BROADCAST);
final boolean broadcastsEnabled = Prefs.isNewBroadcastAvailable(getContext());
if (broadcastsEnabled)
additional_items = Util.appendInt(additional_items, DcContact.DC_CONTACT_ID_NEW_BROADCAST);
if (!dcContext.isChatmail()) {
additional_items =
@@ -14,7 +14,7 @@ import org.thoughtcrime.securesms.service.FetchForegroundService;
import org.thoughtcrime.securesms.util.Util;
public class DcEventCenter {
private static final String TAG = "DcEventCenter";
private static final String TAG = DcEventCenter.class.getSimpleName();
private @NonNull final Hashtable<Integer, ArrayList<DcEventDelegate>> currentAccountObservers =
new Hashtable<>();
private @NonNull final Hashtable<Integer, ArrayList<DcEventDelegate>> multiAccountObservers =
@@ -42,7 +42,7 @@ import org.thoughtcrime.securesms.util.Util;
public class DcHelper {
private static final String TAG = "DcHelper";
private static final String TAG = DcHelper.class.getSimpleName();
public static final String CONFIG_CONFIGURED_ADDRESS = "configured_addr";
public static final String CONFIG_DISPLAY_NAME = "displayname";
@@ -225,8 +225,6 @@ public class DcHelper {
dcContext.setStockTranslation(201, context.getString(R.string.qrshow_join_channel_hint));
dcContext.setStockTranslation(202, context.getString(R.string.you_joined_the_channel));
dcContext.setStockTranslation(203, context.getString(R.string.secure_join_channel_started));
dcContext.setStockTranslation(204, context.getString(R.string.channel_name_changed));
dcContext.setStockTranslation(205, context.getString(R.string.channel_image_changed));
dcContext.setStockTranslation(210, context.getString(R.string.stats_msg_body));
dcContext.setStockTranslation(220, context.getString(R.string.proxy_enabled));
dcContext.setStockTranslation(221, context.getString(R.string.proxy_enabled_hint));
@@ -40,7 +40,7 @@ import org.thoughtcrime.securesms.util.Util;
*/
public class DirectShareUtil {
private static final String TAG = "DirectShareUtil";
private static final String TAG = DirectShareUtil.class.getSimpleName();
private static final String SHORTCUT_CATEGORY = "android.shortcut.conversation";
public static void clearShortcut(@NonNull Context context, int chatId) {
@@ -21,7 +21,7 @@ import org.thoughtcrime.securesms.util.Prefs;
public class KeepAliveService extends Service {
private static final String TAG = "KeepAliveService";
private static final String TAG = KeepAliveService.class.getSimpleName();
static KeepAliveService s_this = null;
@@ -10,7 +10,7 @@ import android.util.Log;
public class NetworkStateReceiver extends BroadcastReceiver {
private static final String TAG = "NetworkStateReceiver";
private static final String TAG = NetworkStateReceiver.class.getSimpleName();
private int debugConnectedCount;
@Override
@@ -22,6 +22,7 @@ import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.thoughtcrime.securesms.ContactSelectionListFragment;
import org.thoughtcrime.securesms.util.Hash;
import org.thoughtcrime.securesms.util.Prefs;
@@ -36,7 +37,7 @@ import org.thoughtcrime.securesms.util.Prefs;
* @author Moxie Marlinspike
*/
public class ContactAccessor {
private static final String TAG = "ContactAccessor";
private static final String TAG = ContactSelectionListFragment.class.getSimpleName();
private static final int CONTACT_CURSOR_NAME = 0;
@@ -12,7 +12,7 @@ import org.thoughtcrime.securesms.util.AsyncLoader;
public class PagingMediaLoader extends AsyncLoader<DcMediaGalleryElement> {
private static final String TAG = "PagingMediaLoader";
private static final String TAG = PagingMediaLoader.class.getSimpleName();
private final DcMsg msg;
private final boolean leftIsRecent;
@@ -23,7 +23,7 @@ import org.thoughtcrime.securesms.connect.DcHelper;
public class LocationStreamingService extends Service {
private static final String TAG = "LocationStreamingService";
private static final String TAG = LocationStreamingService.class.getSimpleName();
private static final String ACTION_STOP = "org.thoughtcrime.securesms.geolocation.STOP_STREAMING";
private static final int NOTIFICATION_ID = 8801;
private static final String CHANNEL_ID = "location_streaming";
@@ -15,7 +15,7 @@ import java.util.concurrent.Executor;
public class PlatformLocationSource implements LocationSource {
private static final String TAG = "PlatformLocationSource";
private static final String TAG = PlatformLocationSource.class.getSimpleName();
private static final long UPDATE_INTERVAL_MS = 0;
private LocationManager locationManager;
@@ -36,7 +36,7 @@ public class PlatformLocationSource implements LocationSource {
registered = requestProvider(context, LocationManager.FUSED_PROVIDER, callback);
}
// Fall back with individual providers
// Fall back (or complement) with individual providers
if (!registered) {
requestProvider(context, LocationManager.GPS_PROVIDER, callback);
requestProvider(context, LocationManager.NETWORK_PROVIDER, callback);
@@ -19,7 +19,7 @@ import androidx.annotation.NonNull;
class JobConsumer extends Thread {
private static final String TAG = "JobConsumer";
private static final String TAG = JobConsumer.class.getSimpleName();
enum JobResult {
SUCCESS,
@@ -75,7 +75,7 @@ import org.thoughtcrime.securesms.util.views.Stub;
public class AttachmentManager {
private static final String TAG = "AttachmentManager";
private static final String TAG = AttachmentManager.class.getSimpleName();
private final @NonNull Context context;
private final @NonNull Stub<View> attachmentViewStub;
@@ -283,7 +283,7 @@ public class AttachmentManager {
removableMediaView.display(audioView, false);
removableMediaView.addRemoveClickListener(
v -> {
playbackViewModel.stop(audioView.getMsgId());
playbackViewModel.stop(audioView.getMsgId(), audioView.getAudioUri());
});
result.set(true);
} else if (slide.isVcard()) {
@@ -11,7 +11,7 @@ import java.io.InputStream;
class DecryptableStreamLocalUriFetcher extends StreamLocalUriFetcher {
private static final String TAG = "DecryptableStreamLocalUriFetcher";
private static final String TAG = DecryptableStreamLocalUriFetcher.class.getSimpleName();
private final Context context;
@@ -7,7 +7,7 @@ import android.util.Log;
import org.thoughtcrime.securesms.R;
public class InChatSounds {
private static final String TAG = "InChatSounds";
private static final String TAG = InChatSounds.class.getSimpleName();
private static volatile InChatSounds instance;
private SoundPool soundPool = null;
@@ -54,7 +54,7 @@ import org.thoughtcrime.securesms.util.Prefs;
import org.thoughtcrime.securesms.util.Util;
public class NotificationCenter {
private static final String TAG = "NotificationCenter";
private static final String TAG = NotificationCenter.class.getSimpleName();
@NonNull private final ApplicationContext context;
private volatile ChatData visibleChat = null;
private volatile Pair<Integer, Integer> visibleWebxdc = null;
@@ -33,7 +33,7 @@ import org.thoughtcrime.securesms.util.Util;
/** Get the response text from the Wearable Device and sends an message as a reply */
public class RemoteReplyReceiver extends BroadcastReceiver {
public static final String TAG = "RemoteReplyReceiver";
public static final String TAG = RemoteReplyReceiver.class.getSimpleName();
public static final String REPLY_ACTION = "org.thoughtcrime.securesms.notifications.WEAR_REPLY";
public static final String ACCOUNT_ID_EXTRA = "account_id";
public static final String CHAT_ID_EXTRA = "chat_id";
@@ -44,7 +44,7 @@ import org.thoughtcrime.securesms.util.Util;
public class AdvancedPreferenceFragment extends ListSummaryPreferenceFragment
implements DcEventCenter.DcEventDelegate {
private static final String TAG = "AdvancedPreferenceFragment";
private static final String TAG = AdvancedPreferenceFragment.class.getSimpleName();
private ListPreference showEmails;
CheckBoxPreference selfReportingCheckbox;
@@ -34,7 +34,7 @@ import org.thoughtcrime.securesms.util.Prefs;
public class NotificationsPreferenceFragment extends ListSummaryPreferenceFragment
implements Preference.OnPreferenceChangeListener {
private static final String TAG = "NotificationsPreferenceFragment";
private static final String TAG = NotificationsPreferenceFragment.class.getSimpleName();
private CheckBoxPreference ignoreBattery;
private CheckBoxPreference notificationsEnabled;
@@ -24,7 +24,7 @@ import org.thoughtcrime.securesms.util.Util;
public class PersistentBlobProvider {
private static final String TAG = "PersistentBlobProvider";
private static final String TAG = PersistentBlobProvider.class.getSimpleName();
private static final String URI_STRING = "content://org.thoughtcrime.securesms/capture-new";
public static final Uri CONTENT_URI = Uri.parse(URI_STRING);
@@ -26,7 +26,7 @@ import org.thoughtcrime.securesms.util.Util;
public class BackupProviderFragment extends Fragment implements DcEventCenter.DcEventDelegate {
private static final String TAG = "BackupProviderFragment";
private static final String TAG = BackupProviderFragment.class.getSimpleName();
private DcContext dcContext;
private DcBackupProvider dcBackupProvider;
@@ -19,7 +19,7 @@ import org.thoughtcrime.securesms.util.Util;
public class BackupReceiverFragment extends Fragment implements DcEventCenter.DcEventDelegate {
private static final String TAG = "BackupProviderFragment";
private static final String TAG = BackupProviderFragment.class.getSimpleName();
private DcContext dcContext;
private TextView statusLine;
@@ -27,7 +27,7 @@ import org.thoughtcrime.securesms.util.ViewUtil;
public class BackupTransferActivity extends BaseActionBarActivity {
private static final String TAG = "BackupTransferActivity";
private static final String TAG = BackupTransferActivity.class.getSimpleName();
public enum TransferMode {
INVALID(0),
@@ -40,7 +40,7 @@ import org.thoughtcrime.securesms.util.ViewUtil;
public class QrActivity extends BaseActionBarActivity implements View.OnClickListener {
private static final String TAG = "QrActivity";
private static final String TAG = QrActivity.class.getSimpleName();
public static final String EXTRA_SCAN_RELAY = "scan_relay";
private static final int REQUEST_CODE_IMAGE = 46243;
@@ -26,7 +26,7 @@ import org.thoughtcrime.securesms.util.Util;
import org.thoughtcrime.securesms.util.views.ProgressDialog;
public class QrCodeHandler {
private static final String TAG = "QrCodeHandler";
private static final String TAG = QrCodeHandler.class.getSimpleName();
public static int SECUREJOIN_SOURCE_EXTERNAL_LINK = 1;
public static int SECUREJOIN_SOURCE_INTERNAL_LINK = 2;
@@ -363,24 +363,20 @@ public class QrCodeHandler {
SecurejoinSource source,
SecurejoinUiPath uipath) {
String msg;
int positiveButton;
switch (qrParsed.getState()) {
case DcContext.DC_QR_ASK_VERIFYGROUP:
msg = activity.getString(R.string.qrscan_ask_join_group, qrParsed.getText1());
positiveButton = R.string.join_group;
break;
case DcContext.DC_QR_ASK_JOIN_BROADCAST:
msg = activity.getString(R.string.qrscan_ask_join_channel, qrParsed.getText1());
positiveButton = R.string.join_channel;
break;
default:
msg = activity.getString(R.string.ask_start_chat_with, name);
positiveButton = R.string.ok;
break;
}
builder.setMessage(msg);
builder.setPositiveButton(
positiveButton,
android.R.string.ok,
(dialogInterface, i) -> {
secureJoinByQr(qrRawString, source, uipath);
});
@@ -19,7 +19,7 @@ import org.thoughtcrime.securesms.util.ViewUtil;
public class QrScanFragment extends Fragment {
private static final String TAG = "QrScanFragment";
private static final String TAG = QrScanFragment.class.getSimpleName();
private CompoundBarcodeView barcodeScannerView;
private MyCaptureManager capture;
@@ -29,7 +29,7 @@ import org.thoughtcrime.securesms.util.Util;
public class QrShowFragment extends Fragment implements DcEventCenter.DcEventDelegate {
private static final String TAG = "QrShowFragment";
private static final String TAG = QrShowFragment.class.getSimpleName();
public static final int WHITE = 0xFFFFFFFF;
private static final int BLACK = 0xFF000000;
private static final int WIDTH = 400;
@@ -31,7 +31,7 @@ import org.thoughtcrime.securesms.util.ViewUtil;
public class ReactionsDetailsFragment extends DialogFragment
implements DcEventCenter.DcEventDelegate {
private static final String TAG = "ReactionsDetailsFragment";
private static final String TAG = ReactionsDetailsFragment.class.getSimpleName();
private static final String ARG_MSG_ID = "msg_id";
private RecyclerView recyclerView;
@@ -56,7 +56,7 @@ public class EditRelayActivity extends BaseActionBarActivity
PORT,
}
private static final String TAG = "EditRelayActivity";
private static final String TAG = EditRelayActivity.class.getSimpleName();
public static final String EXTRA_ADDR = "extra_addr";
private TextInputEditText emailInput;
@@ -37,7 +37,7 @@ import org.thoughtcrime.securesms.util.ViewUtil;
public class RelayListActivity extends BaseActionBarActivity
implements RelayListAdapter.OnRelayClickListener, DcEventCenter.DcEventDelegate {
private static final String TAG = "RelayListActivity";
private static final String TAG = RelayListActivity.class.getSimpleName();
public static final String EXTRA_QR_DATA = "qr_data";
private RelayListAdapter adapter;

Some files were not shown because too many files have changed in this diff Show More