diff --git a/app/src/main/java/com/nextcloud/talk/activities/CallActivity.java b/app/src/main/java/com/nextcloud/talk/activities/CallActivity.java index 2402579e6..81c1030d2 100644 --- a/app/src/main/java/com/nextcloud/talk/activities/CallActivity.java +++ b/app/src/main/java/com/nextcloud/talk/activities/CallActivity.java @@ -90,7 +90,6 @@ import com.nextcloud.talk.utils.NotificationUtils; import com.nextcloud.talk.utils.animations.PulseAnimation; import com.nextcloud.talk.utils.permissions.PlatformPermissionUtil; import com.nextcloud.talk.utils.power.PowerManagerUtils; -import com.nextcloud.talk.utils.preferences.AppPreferences; import com.nextcloud.talk.utils.singletons.ApplicationWideCurrentRoomHolder; import com.nextcloud.talk.webrtc.MagicWebRTCUtils; import com.nextcloud.talk.webrtc.MagicWebSocketInstance; @@ -100,7 +99,6 @@ import com.nextcloud.talk.webrtc.WebSocketConnectionHelper; import com.wooplr.spotlight.SpotlightView; import org.apache.commons.lang3.StringEscapeUtils; -import org.greenrobot.eventbus.EventBus; import org.greenrobot.eventbus.Subscribe; import org.greenrobot.eventbus.ThreadMode; import org.webrtc.AudioSource; @@ -178,14 +176,13 @@ public class CallActivity extends CallBaseActivity { @Inject NcApi ncApi; - @Inject - EventBus eventBus; + @Inject UserManager userManager; - @Inject - AppPreferences appPreferences; + @Inject Cache cache; + @Inject PlatformPermissionUtil permissionUtil; @@ -367,7 +364,7 @@ public class CallActivity extends CallBaseActivity { powerManagerUtils = new PowerManagerUtils(); - if (extras.getString("state", "").equalsIgnoreCase("resume")) { + if ("resume".equalsIgnoreCase(extras.getString("state", ""))) { setCallState(CallStatus.IN_CONVERSATION); } else { setCallState(CallStatus.CONNECTING); @@ -592,7 +589,7 @@ public class CallActivity extends CallBaseActivity { private void handleFromNotification() { int apiVersion = ApiUtils.getConversationApiVersion(conversationUser, new int[]{ApiUtils.APIv4, 1}); - ncApi.getRooms(credentials, ApiUtils.getUrlForRooms(apiVersion, baseUrl), false) + ncApi.getRooms(credentials, ApiUtils.getUrlForRooms(apiVersion, baseUrl), Boolean.FALSE) .retry(3) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) diff --git a/app/src/main/java/com/nextcloud/talk/activities/CallBaseActivity.java b/app/src/main/java/com/nextcloud/talk/activities/CallBaseActivity.java index 8401fd9ea..6f13a2aae 100644 --- a/app/src/main/java/com/nextcloud/talk/activities/CallBaseActivity.java +++ b/app/src/main/java/com/nextcloud/talk/activities/CallBaseActivity.java @@ -21,7 +21,7 @@ public abstract class CallBaseActivity extends BaseActivity { public static final String TAG = "CallBaseActivity"; public PictureInPictureParams.Builder mPictureInPictureParamsBuilder; - public Boolean isInPipMode = false; + public Boolean isInPipMode = Boolean.FALSE; long onCreateTime; @SuppressLint("ClickableViewAccessibility") diff --git a/app/src/main/java/com/nextcloud/talk/adapters/items/AdvancedUserItem.java b/app/src/main/java/com/nextcloud/talk/adapters/items/AdvancedUserItem.java index 36f652da1..a5ac03a25 100644 --- a/app/src/main/java/com/nextcloud/talk/adapters/items/AdvancedUserItem.java +++ b/app/src/main/java/com/nextcloud/talk/adapters/items/AdvancedUserItem.java @@ -125,9 +125,9 @@ public class AdvancedUserItem extends AbstractFlexibleItem props = new ArrayList<>(); + List props = new ArrayList<>(20); props.add(DisplayName.NAME); props.add(GetContentType.NAME); @@ -104,22 +98,12 @@ public class DavUtils { public static void registerCustomFactories() { PropertyRegistry propertyRegistry = PropertyRegistry.INSTANCE; - try { - Field factories = propertyRegistry.getClass().getDeclaredField("factories"); - factories.setAccessible(true); - Map reflectionMap = (HashMap) factories.get(propertyRegistry); - reflectionMap.put(OCId.NAME, new OCId.Factory()); - reflectionMap.put(NCPreview.NAME, new NCPreview.Factory()); - reflectionMap.put(NCEncrypted.NAME, new NCEncrypted.Factory()); - reflectionMap.put(OCFavorite.NAME, new OCFavorite.Factory()); - reflectionMap.put(OCSize.NAME, new OCSize.Factory()); - reflectionMap.put(NCPermission.NAME, new NCPermission.Factory()); - - factories.set(propertyRegistry, reflectionMap); - } catch (NoSuchFieldException | IllegalAccessException e) { - Log.w(TAG, "Error registering custom factories", e); - } + propertyRegistry.register(new OCId.Factory()); + propertyRegistry.register(new NCPreview.Factory()); + propertyRegistry.register(new NCEncrypted.Factory()); + propertyRegistry.register(new OCFavorite.Factory()); + propertyRegistry.register(new OCSize.Factory()); + propertyRegistry.register(new NCPermission.Factory()); } } diff --git a/app/src/main/java/com/nextcloud/talk/components/filebrowser/webdav/ReadFilesystemOperation.java b/app/src/main/java/com/nextcloud/talk/components/filebrowser/webdav/ReadFilesystemOperation.java index 31b08d1ec..b8cb247c0 100644 --- a/app/src/main/java/com/nextcloud/talk/components/filebrowser/webdav/ReadFilesystemOperation.java +++ b/app/src/main/java/com/nextcloud/talk/components/filebrowser/webdav/ReadFilesystemOperation.java @@ -69,7 +69,6 @@ public class ReadFilesystemOperation { DavResponse davResponse = new DavResponse(); final List memberElements = new ArrayList<>(); final Response[] rootElement = new Response[1]; - final List remoteFiles = new ArrayList<>(); try { new DavResource(okHttpClient, HttpUrl.parse(url)).propfind(depth, DavUtils.getAllPropSet(), @@ -94,6 +93,7 @@ public class ReadFilesystemOperation { Log.w(TAG, "Error reading remote path"); } + final List remoteFiles = new ArrayList<>(1 + memberElements.size()); remoteFiles.add(BrowserFile.Companion.getModelFromResponse(rootElement[0], rootElement[0].getHref().toString().substring(basePath.length()))); for (Response memberElement : memberElements) { diff --git a/app/src/main/java/com/nextcloud/talk/dagger/modules/RestModule.java b/app/src/main/java/com/nextcloud/talk/dagger/modules/RestModule.java index 06b91d670..4733d4f47 100644 --- a/app/src/main/java/com/nextcloud/talk/dagger/modules/RestModule.java +++ b/app/src/main/java/com/nextcloud/talk/dagger/modules/RestModule.java @@ -249,9 +249,7 @@ public class RestModule { .method(original.method(), original.body()) .build(); - Response response = chain.proceed(request); - - return response; + return chain.proceed(request); } } diff --git a/app/src/main/java/com/nextcloud/talk/events/EventStatus.java b/app/src/main/java/com/nextcloud/talk/events/EventStatus.java index 70f0a392a..fa32ad424 100644 --- a/app/src/main/java/com/nextcloud/talk/events/EventStatus.java +++ b/app/src/main/java/com/nextcloud/talk/events/EventStatus.java @@ -89,8 +89,7 @@ public class EventStatus { result = result * PRIME + (int) ($userId >>> 32 ^ $userId); final Object $eventType = this.getEventType(); result = result * PRIME + ($eventType == null ? 43 : $eventType.hashCode()); - result = result * PRIME + (this.isAllGood() ? 79 : 97); - return result; + return result * PRIME + (this.isAllGood() ? 79 : 97); } public String toString() { diff --git a/app/src/main/java/com/nextcloud/talk/events/MoreMenuClickEvent.java b/app/src/main/java/com/nextcloud/talk/events/MoreMenuClickEvent.java index 38d452a79..742c948a3 100644 --- a/app/src/main/java/com/nextcloud/talk/events/MoreMenuClickEvent.java +++ b/app/src/main/java/com/nextcloud/talk/events/MoreMenuClickEvent.java @@ -58,8 +58,7 @@ public class MoreMenuClickEvent { final int PRIME = 59; int result = 1; final Object $conversation = this.getConversation(); - result = result * PRIME + ($conversation == null ? 43 : $conversation.hashCode()); - return result; + return result * PRIME + ($conversation == null ? 43 : $conversation.hashCode()); } public String toString() { diff --git a/app/src/main/java/com/nextcloud/talk/events/NetworkEvent.java b/app/src/main/java/com/nextcloud/talk/events/NetworkEvent.java index 2167c92c4..7489c053b 100644 --- a/app/src/main/java/com/nextcloud/talk/events/NetworkEvent.java +++ b/app/src/main/java/com/nextcloud/talk/events/NetworkEvent.java @@ -56,8 +56,7 @@ public class NetworkEvent { final int PRIME = 59; int result = 1; final Object $networkConnectionEvent = this.getNetworkConnectionEvent(); - result = result * PRIME + ($networkConnectionEvent == null ? 43 : $networkConnectionEvent.hashCode()); - return result; + return result * PRIME + ($networkConnectionEvent == null ? 43 : $networkConnectionEvent.hashCode()); } public String toString() { diff --git a/app/src/main/java/com/nextcloud/talk/events/UserMentionClickEvent.java b/app/src/main/java/com/nextcloud/talk/events/UserMentionClickEvent.java index 467a18412..b19aab076 100644 --- a/app/src/main/java/com/nextcloud/talk/events/UserMentionClickEvent.java +++ b/app/src/main/java/com/nextcloud/talk/events/UserMentionClickEvent.java @@ -56,8 +56,7 @@ public class UserMentionClickEvent { final int PRIME = 59; int result = 1; final Object $userId = this.getUserId(); - result = result * PRIME + ($userId == null ? 43 : $userId.hashCode()); - return result; + return result * PRIME + ($userId == null ? 43 : $userId.hashCode()); } public String toString() { diff --git a/app/src/main/java/com/nextcloud/talk/events/WebSocketCommunicationEvent.java b/app/src/main/java/com/nextcloud/talk/events/WebSocketCommunicationEvent.java index 532869e9f..3662b4e80 100644 --- a/app/src/main/java/com/nextcloud/talk/events/WebSocketCommunicationEvent.java +++ b/app/src/main/java/com/nextcloud/talk/events/WebSocketCommunicationEvent.java @@ -75,8 +75,7 @@ public class WebSocketCommunicationEvent { final Object $type = this.getType(); result = result * PRIME + ($type == null ? 43 : $type.hashCode()); final Object $hashMap = this.getHashMap(); - result = result * PRIME + ($hashMap == null ? 43 : $hashMap.hashCode()); - return result; + return result * PRIME + ($hashMap == null ? 43 : $hashMap.hashCode()); } public String toString() { diff --git a/app/src/main/java/com/nextcloud/talk/models/ImportAccount.java b/app/src/main/java/com/nextcloud/talk/models/ImportAccount.java index 56dd426d8..6fd952897 100644 --- a/app/src/main/java/com/nextcloud/talk/models/ImportAccount.java +++ b/app/src/main/java/com/nextcloud/talk/models/ImportAccount.java @@ -98,8 +98,7 @@ public class ImportAccount { final Object $token = this.getToken(); result = result * PRIME + ($token == null ? 43 : $token.hashCode()); final Object $baseUrl = this.getBaseUrl(); - result = result * PRIME + ($baseUrl == null ? 43 : $baseUrl.hashCode()); - return result; + return result * PRIME + ($baseUrl == null ? 43 : $baseUrl.hashCode()); } public String toString() { diff --git a/app/src/main/java/com/nextcloud/talk/presenters/MentionAutocompletePresenter.java b/app/src/main/java/com/nextcloud/talk/presenters/MentionAutocompletePresenter.java index f6a28dab8..8aa553714 100644 --- a/app/src/main/java/com/nextcloud/talk/presenters/MentionAutocompletePresenter.java +++ b/app/src/main/java/com/nextcloud/talk/presenters/MentionAutocompletePresenter.java @@ -147,7 +147,8 @@ public class MentionAutocompletePresenter extends RecyclerViewPresenter if (mentionsList.size() == 0) { adapter.clear(); } else { - List internalAbstractFlexibleItemList = new ArrayList<>(); + List internalAbstractFlexibleItemList = + new ArrayList<>(mentionsList.size()); for (Mention mention : mentionsList) { internalAbstractFlexibleItemList.add( new MentionAutocompleteItem( diff --git a/app/src/main/java/com/nextcloud/talk/ui/StatusDrawable.java b/app/src/main/java/com/nextcloud/talk/ui/StatusDrawable.java index 258263327..b2a1fe1b8 100644 --- a/app/src/main/java/com/nextcloud/talk/ui/StatusDrawable.java +++ b/app/src/main/java/com/nextcloud/talk/ui/StatusDrawable.java @@ -42,9 +42,9 @@ import androidx.core.content.res.ResourcesCompat; */ public class StatusDrawable extends Drawable { private String text; - private @DrawableRes int icon = -1; + private StatusDrawableType icon = StatusDrawableType.UNDEFINED; private Paint textPaint; - private int backgroundColor; + private final int backgroundColor; private final float radius; private Context context; @@ -54,17 +54,17 @@ public class StatusDrawable extends Drawable { if ("dnd".equals(status)) { - icon = R.drawable.ic_user_status_dnd; + icon = StatusDrawableType.DND; this.context = context; } else if (TextUtils.isEmpty(statusIcon) && status != null) { switch (status) { case "online": - icon = R.drawable.online_status; + icon = StatusDrawableType.ONLINE; this.context = context; break; case "away": - icon = R.drawable.ic_user_status_away; + icon = StatusDrawableType.AWAY; this.context = context; break; @@ -95,7 +95,7 @@ public class StatusDrawable extends Drawable { canvas.drawText(text, radius, radius - ((textPaint.descent() + textPaint.ascent()) / 2), textPaint); } - if (icon != -1) { + if (icon != StatusDrawableType.UNDEFINED) { Paint backgroundPaint = new Paint(); backgroundPaint.setStyle(Paint.Style.FILL); @@ -104,7 +104,7 @@ public class StatusDrawable extends Drawable { canvas.drawCircle(radius, radius, radius, backgroundPaint); - Drawable drawable = ResourcesCompat.getDrawable(context.getResources(), icon, null); + Drawable drawable = ResourcesCompat.getDrawable(context.getResources(), icon.drawableId, null); if (drawable != null) { drawable.setBounds(0, @@ -130,4 +130,18 @@ public class StatusDrawable extends Drawable { public int getOpacity() { return PixelFormat.TRANSLUCENT; } + + private enum StatusDrawableType { + DND(R.drawable.ic_user_status_dnd), + ONLINE(R.drawable.online_status), + AWAY(R.drawable.ic_user_status_away), + UNDEFINED(-1); + + @DrawableRes + private final int drawableId; + + StatusDrawableType(int drawableId) { + this.drawableId = drawableId; + } + } } diff --git a/app/src/main/java/com/nextcloud/talk/ui/dialog/SortingOrderDialogFragment.java b/app/src/main/java/com/nextcloud/talk/ui/dialog/SortingOrderDialogFragment.java index d3744072a..ac75659df 100644 --- a/app/src/main/java/com/nextcloud/talk/ui/dialog/SortingOrderDialogFragment.java +++ b/app/src/main/java/com/nextcloud/talk/ui/dialog/SortingOrderDialogFragment.java @@ -177,7 +177,6 @@ public class SortingOrderDialogFragment extends DialogFragment implements View.O binding.cancel.setOnClickListener(view -> dismiss()); for (View view : taggedViews) { - Log.i("SortOrder", "view="+view.getTag().toString()); view.setOnClickListener(this); } } diff --git a/app/src/main/java/com/nextcloud/talk/utils/AuthenticatorService.java b/app/src/main/java/com/nextcloud/talk/utils/AuthenticatorService.java index a91bcbe95..4aa831bd5 100644 --- a/app/src/main/java/com/nextcloud/talk/utils/AuthenticatorService.java +++ b/app/src/main/java/com/nextcloud/talk/utils/AuthenticatorService.java @@ -62,8 +62,7 @@ public class AuthenticatorService extends Service { } @Override - public Bundle getAuthToken(AccountAuthenticatorResponse response, Account account, String authTokenType, Bundle options) - throws NetworkErrorException { + public Bundle getAuthToken(AccountAuthenticatorResponse response, Account account, String authTokenType, Bundle options) throws NetworkErrorException { return null; } @@ -73,8 +72,7 @@ public class AuthenticatorService extends Service { } @Override - public Bundle hasFeatures(AccountAuthenticatorResponse response, - Account account, String[] features) { + public Bundle hasFeatures(AccountAuthenticatorResponse response, Account account, String[] features) { return null; } @@ -82,7 +80,6 @@ public class AuthenticatorService extends Service { public Bundle updateCredentials(AccountAuthenticatorResponse response, Account account, String authTokenType, Bundle options) { return null; } - } protected Authenticator getAuthenticator() { @@ -95,7 +92,7 @@ public class AuthenticatorService extends Service { @Override public IBinder onBind(Intent intent) { - if (intent.getAction().equals(AccountManager.ACTION_AUTHENTICATOR_INTENT)) { + if (AccountManager.ACTION_AUTHENTICATOR_INTENT.equals(intent.getAction())) { return getAuthenticator().getIBinder(); } else { return null; diff --git a/app/src/main/java/com/nextcloud/talk/utils/DeviceUtils.java b/app/src/main/java/com/nextcloud/talk/utils/DeviceUtils.java index e53149078..8decb12ff 100644 --- a/app/src/main/java/com/nextcloud/talk/utils/DeviceUtils.java +++ b/app/src/main/java/com/nextcloud/talk/utils/DeviceUtils.java @@ -35,14 +35,17 @@ public class DeviceUtils { private static final String TAG = "DeviceUtils"; public static void ignoreSpecialBatteryFeatures() { - if (Build.MANUFACTURER.equalsIgnoreCase("xiaomi") || Build.MANUFACTURER.equalsIgnoreCase("meizu")) { + if ("xiaomi".equalsIgnoreCase(Build.MANUFACTURER) || "meizu".equalsIgnoreCase(Build.MANUFACTURER)) { try { @SuppressLint("PrivateApi") Class appOpsUtilsClass = Class.forName("android.miui.AppOpsUtils"); if (appOpsUtilsClass != null) { Method setApplicationAutoStartMethod = appOpsUtilsClass.getMethod("setApplicationAutoStart", Context .class, String.class, Boolean.TYPE); if (setApplicationAutoStartMethod != null) { - Context applicationContext = NextcloudTalkApplication.Companion.getSharedApplication().getApplicationContext(); + Context applicationContext = NextcloudTalkApplication + .Companion + .getSharedApplication() + .getApplicationContext(); setApplicationAutoStartMethod.invoke(appOpsUtilsClass, applicationContext, applicationContext .getPackageName(), Boolean.TRUE); } @@ -56,10 +59,10 @@ public class DeviceUtils { } catch (InvocationTargetException e) { Log.e(TAG, "InvocationTargetException"); } - } else if (Build.MANUFACTURER.equalsIgnoreCase("huawei")) { + } else if ("huawei".equalsIgnoreCase(Build.MANUFACTURER)) { try { - @SuppressLint("PrivateApi") Class protectAppControlClass = Class.forName("com.huawei.systemmanager.optimize.process" + - ".ProtectAppControl"); + @SuppressLint("PrivateApi") Class protectAppControlClass = Class.forName( + "com.huawei.systemmanager.optimize.process.ProtectAppControl"); if (protectAppControlClass != null) { Context applicationContext = NextcloudTalkApplication.Companion.getSharedApplication().getApplicationContext(); diff --git a/app/src/main/java/com/nextcloud/talk/utils/DisplayUtils.java b/app/src/main/java/com/nextcloud/talk/utils/DisplayUtils.java index 50303a506..e48ed823a 100644 --- a/app/src/main/java/com/nextcloud/talk/utils/DisplayUtils.java +++ b/app/src/main/java/com/nextcloud/talk/utils/DisplayUtils.java @@ -369,8 +369,6 @@ public class DisplayUtils { decor.setSystemUiVisibility(0); } window.setStatusBarColor(color); - } else if (isLightTheme) { - window.setStatusBarColor(Color.BLACK); } } @@ -380,7 +378,7 @@ public class DisplayUtils { * @param color the color * @return true if primaryColor is lighter than MAX_LIGHTNESS */ - @SuppressWarnings("correctness") + @SuppressWarnings("CLI_CONSTANT_LIST_INDEX") public static boolean lightTheme(int color) { float[] hsl = colorToHSL(color); @@ -455,10 +453,12 @@ public class DisplayUtils { avatarId = user.getUsername(); } - if (deleteCache) { - ImageViewExtensionsKt.replaceAvatar(avatarImageView, user, avatarId, true); - } else { - ImageViewExtensionsKt.loadAvatar(avatarImageView, user, avatarId, true); + if (avatarId != null) { + if (deleteCache) { + ImageViewExtensionsKt.replaceAvatar(avatarImageView, user, avatarId, true); + } else { + ImageViewExtensionsKt.loadAvatar(avatarImageView, user, avatarId, true); + } } } diff --git a/app/src/main/java/com/nextcloud/talk/utils/MagicCharPolicy.java b/app/src/main/java/com/nextcloud/talk/utils/MagicCharPolicy.java index e63d58184..d198732eb 100644 --- a/app/src/main/java/com/nextcloud/talk/utils/MagicCharPolicy.java +++ b/app/src/main/java/com/nextcloud/talk/utils/MagicCharPolicy.java @@ -37,43 +37,57 @@ public class MagicCharPolicy implements AutocompletePolicy { } @Nullable - public static int[] getQueryRange(Spannable text) { + public static TextSpan getQueryRange(Spannable text) { QuerySpan[] span = text.getSpans(0, text.length(), QuerySpan.class); - if (span == null || span.length == 0) return null; - if (span.length > 1) { - // Do absolutely nothing + if (span == null || span.length == 0) { + return null; + } else { + QuerySpan sp = span[0]; + return new TextSpan(text.getSpanStart(sp), text.getSpanEnd(sp)); } - QuerySpan sp = span[0]; - return new int[]{text.getSpanStart(sp), text.getSpanEnd(sp)}; } - private int[] checkText(Spannable text, int cursorPos) { + private TextSpan checkText(Spannable text, int cursorPos) { if (text.length() == 0) { return null; } - int[] span = new int[2]; Pattern pattern = Pattern.compile("@+\\S*", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE); Matcher matcher = pattern.matcher(text); while (matcher.find()) { - if (cursorPos >= matcher.start() && cursorPos <= matcher.end()) { - span[0] = matcher.start(); - span[1] = matcher.end(); - if (text.subSequence(matcher.start(), matcher.end()).charAt(0) == character) { - return span; - } + if (cursorPos >= matcher.start() && cursorPos <= matcher.end() && + text.subSequence(matcher.start(), matcher.end()).charAt(0) == character) { + return new TextSpan(matcher.start(), matcher.end()); } } return null; } + public static class TextSpan { + int start; + int end; + + public TextSpan(int start, int end) { + this.start = start; + this.end = end; + } + + public int getStart() { + return start; + } + + public int getEnd() { + return end; + } + } + @Override public boolean shouldShowPopup(Spannable text, int cursorPos) { - int[] show = checkText(text, cursorPos); + TextSpan show = checkText(text, cursorPos); if (show != null) { - text.setSpan(new QuerySpan(), show[0], show[1], Spanned.SPAN_INCLUSIVE_INCLUSIVE); + text.setSpan(new QuerySpan(), show.getStart(), show.getEnd(), Spanned.SPAN_INCLUSIVE_INCLUSIVE); return true; } return false; diff --git a/app/src/main/java/com/nextcloud/talk/utils/preferences/preferencestorage/DatabaseStorageModule.java b/app/src/main/java/com/nextcloud/talk/utils/preferences/preferencestorage/DatabaseStorageModule.java index 9e891efec..3b4d59cf5 100644 --- a/app/src/main/java/com/nextcloud/talk/utils/preferences/preferencestorage/DatabaseStorageModule.java +++ b/app/src/main/java/com/nextcloud/talk/utils/preferences/preferencestorage/DatabaseStorageModule.java @@ -78,7 +78,7 @@ public class DatabaseStorageModule implements StorageModule { @Override public void saveBoolean(String key, boolean value) { - if (key.equals("call_notifications")) { + if ("call_notifications".equals(key)) { int apiVersion = ApiUtils.getConversationApiVersion(conversationUser, new int[]{4}); ncApi.notificationCalls(ApiUtils.getCredentials(conversationUser.getUsername(), conversationUser.getToken()), @@ -112,7 +112,7 @@ public class DatabaseStorageModule implements StorageModule { ); } - if (!key.equals("conversation_lobby")) { + if (!"conversation_lobby".equals(key)) { arbitraryStorageManager.storeStorageSetting(accountIdentifier, key, Boolean.toString(value), @@ -124,7 +124,7 @@ public class DatabaseStorageModule implements StorageModule { @Override public void saveString(String key, String value) { - if (key.equals("message_expire_key")) { + if ("message_expire_key".equals(key)) { int apiVersion = ApiUtils.getConversationApiVersion(conversationUser, new int[]{4}); String trimmedValue = value.replace("expire_", ""); @@ -163,7 +163,7 @@ public class DatabaseStorageModule implements StorageModule { } }); - } else if (key.equals("message_notification_level")) { + } else if ("message_notification_level".equals(key)) { if (CapabilitiesUtilNew.hasSpreedFeatureCapability(conversationUser, "notification-levels")) { if (!TextUtils.isEmpty(messageNotificationLevel) && !messageNotificationLevel.equals(value)) { int intValue; @@ -232,7 +232,7 @@ public class DatabaseStorageModule implements StorageModule { @Override public boolean getBoolean(String key, boolean defaultVal) { - if (key.equals("conversation_lobby")) { + if ("conversation_lobby".equals(key)) { return lobbyValue; } else { return arbitraryStorageManager @@ -244,7 +244,7 @@ public class DatabaseStorageModule implements StorageModule { @Override public String getString(String key, String defaultVal) { - if (key.equals("message_expire_key")) { + if ("message_expire_key".equals(key)) { switch (messageExpiration) { case 2419200: return "expire_2419200"; @@ -259,7 +259,7 @@ public class DatabaseStorageModule implements StorageModule { default: return "expire_0"; } - } else if (key.equals("message_notification_level")) { + } else if ("message_notification_level".equals(key)) { return messageNotificationLevel; } else { return arbitraryStorageManager diff --git a/app/src/main/java/com/nextcloud/talk/utils/text/Spans.java b/app/src/main/java/com/nextcloud/talk/utils/text/Spans.java index 50d6bfa07..12de790a1 100644 --- a/app/src/main/java/com/nextcloud/talk/utils/text/Spans.java +++ b/app/src/main/java/com/nextcloud/talk/utils/text/Spans.java @@ -87,13 +87,11 @@ public class Spans { final Object $id = this.getId(); result = result * PRIME + ($id == null ? 43 : $id.hashCode()); final Object $label = this.getLabel(); - result = result * PRIME + ($label == null ? 43 : $label.hashCode()); - return result; + return result * PRIME + ($label == null ? 43 : $label.hashCode()); } public String toString() { return "Spans.MentionChipSpan(id=" + this.getId() + ", label=" + this.getLabel() + ")"; } } - } diff --git a/app/src/main/java/com/nextcloud/talk/webrtc/Globals.java b/app/src/main/java/com/nextcloud/talk/webrtc/Globals.java index 5e27542ee..317e2939e 100644 --- a/app/src/main/java/com/nextcloud/talk/webrtc/Globals.java +++ b/app/src/main/java/com/nextcloud/talk/webrtc/Globals.java @@ -4,4 +4,5 @@ public class Globals { public static final String ROOM_TOKEN = "roomToken"; public static final String TARGET_PARTICIPANTS = "participants"; + public static final String TARGET_ROOM = "room"; } diff --git a/app/src/main/java/com/nextcloud/talk/webrtc/MagicWebSocketInstance.java b/app/src/main/java/com/nextcloud/talk/webrtc/MagicWebSocketInstance.java index da98e27f3..9c7cc3f94 100644 --- a/app/src/main/java/com/nextcloud/talk/webrtc/MagicWebSocketInstance.java +++ b/app/src/main/java/com/nextcloud/talk/webrtc/MagicWebSocketInstance.java @@ -35,6 +35,7 @@ import com.nextcloud.talk.models.json.websocket.BaseWebSocketMessage; import com.nextcloud.talk.models.json.websocket.ByeWebSocketMessage; import com.nextcloud.talk.models.json.websocket.CallOverallWebSocketMessage; import com.nextcloud.talk.models.json.websocket.ErrorOverallWebSocketMessage; +import com.nextcloud.talk.models.json.websocket.ErrorWebSocketMessage; import com.nextcloud.talk.models.json.websocket.EventOverallWebSocketMessage; import com.nextcloud.talk.models.json.websocket.HelloResponseOverallWebSocketMessage; import com.nextcloud.talk.models.json.websocket.JoinedRoomOverallWebSocketMessage; @@ -54,6 +55,7 @@ import java.util.Map; import javax.inject.Inject; +import androidx.annotation.NonNull; import autodagger.AutoInjector; import okhttp3.OkHttpClient; import okhttp3.Request; @@ -66,12 +68,12 @@ import static com.nextcloud.talk.models.json.participants.Participant.ActorType. import static com.nextcloud.talk.models.json.participants.Participant.ActorType.USERS; import static com.nextcloud.talk.webrtc.Globals.ROOM_TOKEN; import static com.nextcloud.talk.webrtc.Globals.TARGET_PARTICIPANTS; +import static com.nextcloud.talk.webrtc.Globals.TARGET_ROOM; @AutoInjector(NextcloudTalkApplication.class) public class MagicWebSocketInstance extends WebSocketListener { private static final String TAG = "MagicWebSocketInstance"; - @Inject OkHttpClient okHttpClient; @@ -81,18 +83,17 @@ public class MagicWebSocketInstance extends WebSocketListener { @Inject Context context; - private User conversationUser; - private String webSocketTicket; + private final User conversationUser; + private final String webSocketTicket; private String resumeId; private String sessionId; private boolean hasMCU; private boolean connected; - private WebSocketConnectionHelper webSocketConnectionHelper; + private final WebSocketConnectionHelper webSocketConnectionHelper; private WebSocket internalWebSocket; - private String connectionUrl; + private final String connectionUrl; private String currentRoomToken; - private int restartCount = 0; private boolean reconnecting = false; private HashMap usersHashMap; @@ -121,9 +122,13 @@ public class MagicWebSocketInstance extends WebSocketListener { private void sendHello() { try { if (TextUtils.isEmpty(resumeId)) { - internalWebSocket.send(LoganSquare.serialize(webSocketConnectionHelper.getAssembledHelloModel(conversationUser, webSocketTicket))); + internalWebSocket.send( + LoganSquare.serialize(webSocketConnectionHelper + .getAssembledHelloModel(conversationUser, webSocketTicket))); } else { - internalWebSocket.send(LoganSquare.serialize(webSocketConnectionHelper.getAssembledHelloModelForResume(resumeId))); + internalWebSocket.send( + LoganSquare.serialize(webSocketConnectionHelper + .getAssembledHelloModelForResume(resumeId))); } } catch (IOException e) { Log.e(TAG, "Failed to serialize hello model"); @@ -152,142 +157,49 @@ public class MagicWebSocketInstance extends WebSocketListener { resumeId = ""; } - public void restartWebSocket() { + public final void restartWebSocket() { reconnecting = true; // TODO when improving logging, keep in mind this issue: https://github.com/nextcloud/talk-android/issues/1013 Log.d(TAG, "restartWebSocket: " + connectionUrl); Request request = new Request.Builder().url(connectionUrl).build(); okHttpClient.newWebSocket(request, this); - restartCount++; } @Override - public void onMessage(WebSocket webSocket, String text) { + public void onMessage(@NonNull WebSocket webSocket, @NonNull String text) { if (webSocket == internalWebSocket) { - Log.d(TAG, "Receiving : " + webSocket.toString() + " " + text); + Log.d(TAG, "Receiving : " + webSocket + " " + text); try { BaseWebSocketMessage baseWebSocketMessage = LoganSquare.parse(text, BaseWebSocketMessage.class); String messageType = baseWebSocketMessage.getType(); - switch (messageType) { - case "hello": - connected = true; - reconnecting = false; - restartCount = 0; - String oldResumeId = resumeId; - HelloResponseOverallWebSocketMessage helloResponseWebSocketMessage = LoganSquare.parse(text, HelloResponseOverallWebSocketMessage.class); - resumeId = helloResponseWebSocketMessage.getHelloResponseWebSocketMessage().getResumeId(); - sessionId = helloResponseWebSocketMessage.getHelloResponseWebSocketMessage().getSessionId(); - hasMCU = helloResponseWebSocketMessage.getHelloResponseWebSocketMessage().serverHasMCUSupport(); - - for (int i = 0; i < messagesQueue.size(); i++) { - webSocket.send(messagesQueue.get(i)); - } - - messagesQueue = new ArrayList<>(); - HashMap helloHasHap = new HashMap<>(); - if (!TextUtils.isEmpty(oldResumeId)) { - helloHasHap.put("oldResumeId", oldResumeId); - } else { - currentRoomToken = ""; - } - - if (!TextUtils.isEmpty(currentRoomToken)) { - helloHasHap.put(ROOM_TOKEN, currentRoomToken); - } - eventBus.post(new WebSocketCommunicationEvent("hello", helloHasHap)); - break; - case "error": - Log.e(TAG, "Received error: " + text); - ErrorOverallWebSocketMessage errorOverallWebSocketMessage = LoganSquare.parse(text, ErrorOverallWebSocketMessage.class); - if (("no_such_session").equals(errorOverallWebSocketMessage.getErrorWebSocketMessage().getCode())) { - Log.d(TAG, "WebSocket " + webSocket.hashCode() + " resumeID " + resumeId + " expired"); + if (messageType != null) { + switch (messageType) { + case "hello": + processHelloMessage(webSocket, text); + break; + case "error": + processErrorMessage(webSocket, text); + break; + case "room": + processJoinedRoomMessage(text); + break; + case "event": + processEventMessage(text); + break; + case "message": + processMessage(text); + break; + case "bye": + connected = false; resumeId = ""; - currentRoomToken = ""; - restartWebSocket(); - } else if (("hello_expected").equals(errorOverallWebSocketMessage.getErrorWebSocketMessage().getCode())) { - restartWebSocket(); - } - - break; - case "room": - JoinedRoomOverallWebSocketMessage joinedRoomOverallWebSocketMessage = LoganSquare.parse(text, JoinedRoomOverallWebSocketMessage.class); - currentRoomToken = joinedRoomOverallWebSocketMessage.getRoomWebSocketMessage().getRoomId(); - if (joinedRoomOverallWebSocketMessage.getRoomWebSocketMessage().getRoomPropertiesWebSocketMessage() != null && !TextUtils.isEmpty(currentRoomToken)) { - sendRoomJoinedEvent(); - } - break; - case "event": - EventOverallWebSocketMessage eventOverallWebSocketMessage = LoganSquare.parse(text, EventOverallWebSocketMessage.class); - if (eventOverallWebSocketMessage.getEventMap() != null) { - String target = (String) eventOverallWebSocketMessage.getEventMap().get("target"); - switch (target) { - case "room": - if (eventOverallWebSocketMessage.getEventMap().get("type").equals("message")) { - Map messageHashMap = - (Map) eventOverallWebSocketMessage.getEventMap().get("message"); - if (messageHashMap.containsKey("data")) { - Map dataHashMap = (Map) messageHashMap.get( - "data"); - if (dataHashMap.containsKey("chat")) { - boolean shouldRefreshChat; - Map chatMap = (Map) dataHashMap.get("chat"); - if (chatMap.containsKey("refresh")) { - shouldRefreshChat = (boolean) chatMap.get("refresh"); - if (shouldRefreshChat) { - HashMap refreshChatHashMap = new HashMap<>(); - refreshChatHashMap.put(BundleKeys.KEY_ROOM_TOKEN, (String) messageHashMap.get("roomid")); - refreshChatHashMap.put(BundleKeys.KEY_INTERNAL_USER_ID, Long.toString(conversationUser.getId())); - eventBus.post(new WebSocketCommunicationEvent("refreshChat", refreshChatHashMap)); - } - } - } - } - } else if (eventOverallWebSocketMessage.getEventMap().get("type").equals("join")) { - List> joinEventList = (List>) eventOverallWebSocketMessage.getEventMap().get("join"); - HashMap internalHashMap; - Participant participant; - for (int i = 0; i < joinEventList.size(); i++) { - internalHashMap = joinEventList.get(i); - HashMap userMap = (HashMap) internalHashMap.get("user"); - participant = new Participant(); - String userId = (String) internalHashMap.get("userid"); - if (userId != null) { - participant.setActorType(USERS); - participant.setActorId(userId); - } else { - participant.setActorType(GUESTS); - // FIXME seems to be not given by the HPB: participant.setActorId(); - } - if (userMap != null) { - // There is no "user" attribute for guest participants. - participant.setDisplayName((String) userMap.get("displayname")); - } - usersHashMap.put((String) internalHashMap.get("sessionid"), participant); - } - } - break; - case TARGET_PARTICIPANTS: - signalingMessageReceiver.process(eventOverallWebSocketMessage.getEventMap()); - break; - } - } - break; - case "message": - CallOverallWebSocketMessage callOverallWebSocketMessage = LoganSquare.parse(text, CallOverallWebSocketMessage.class); - NCSignalingMessage ncSignalingMessage = callOverallWebSocketMessage.getCallWebSocketMessage().getNcSignalingMessage(); - if (TextUtils.isEmpty(ncSignalingMessage.getFrom()) && callOverallWebSocketMessage.getCallWebSocketMessage().getSenderWebSocketMessage() != null) { - ncSignalingMessage.setFrom(callOverallWebSocketMessage.getCallWebSocketMessage().getSenderWebSocketMessage().getSessionId()); - } - - signalingMessageReceiver.process(ncSignalingMessage); - break; - case "bye": - connected = false; - resumeId = ""; - default: - break; + break; + default: + break; + } + } else { + Log.e(TAG, "Received message with type: null"); } } catch (IOException e) { Log.e(TAG, "Failed to recognize WebSocket message", e); @@ -295,6 +207,158 @@ public class MagicWebSocketInstance extends WebSocketListener { } } + private void processMessage(String text) throws IOException { + CallOverallWebSocketMessage callOverallWebSocketMessage = + LoganSquare.parse(text, CallOverallWebSocketMessage.class); + + if (callOverallWebSocketMessage.getCallWebSocketMessage() != null) { + NCSignalingMessage ncSignalingMessage = callOverallWebSocketMessage + .getCallWebSocketMessage() + .getNcSignalingMessage(); + if (ncSignalingMessage != null && TextUtils.isEmpty(ncSignalingMessage.getFrom()) && + callOverallWebSocketMessage.getCallWebSocketMessage().getSenderWebSocketMessage() != null) { + ncSignalingMessage.setFrom( + callOverallWebSocketMessage.getCallWebSocketMessage().getSenderWebSocketMessage().getSessionId()); + } + + signalingMessageReceiver.process(ncSignalingMessage); + } + } + + private void processEventMessage(String text) throws IOException { + EventOverallWebSocketMessage eventOverallWebSocketMessage = + LoganSquare.parse(text, EventOverallWebSocketMessage.class); + if (eventOverallWebSocketMessage.getEventMap() != null) { + String target = (String) eventOverallWebSocketMessage.getEventMap().get("target"); + if (target != null) { + switch (target) { + case TARGET_ROOM: + if ("message".equals(eventOverallWebSocketMessage.getEventMap().get("type"))) { + processRoomMessageMessage(eventOverallWebSocketMessage); + } else if ("join".equals(eventOverallWebSocketMessage.getEventMap().get("type"))) { + processRoomJoinMessage(eventOverallWebSocketMessage); + } + break; + case TARGET_PARTICIPANTS: + signalingMessageReceiver.process(eventOverallWebSocketMessage.getEventMap()); + break; + default: + Log.i(TAG, "Received unknown/ignored event target: " + target); + break; + } + } else { + Log.w(TAG, "Received message with event target: null"); + } + } + } + + private void processRoomMessageMessage(EventOverallWebSocketMessage eventOverallWebSocketMessage) { + Map messageHashMap = (Map) eventOverallWebSocketMessage + .getEventMap() + .get("message"); + if (messageHashMap != null && messageHashMap.containsKey("data")) { + Map dataHashMap = (Map) messageHashMap.get("data"); + if (dataHashMap != null && dataHashMap.containsKey("chat")) { + Map chatMap = (Map) dataHashMap.get("chat"); + if (chatMap != null && chatMap.containsKey("refresh") && (boolean) chatMap.get("refresh")) { + HashMap refreshChatHashMap = new HashMap<>(); + refreshChatHashMap.put(BundleKeys.KEY_ROOM_TOKEN, (String) messageHashMap.get("roomid")); + refreshChatHashMap.put(BundleKeys.KEY_INTERNAL_USER_ID, Long.toString(conversationUser.getId())); + eventBus.post(new WebSocketCommunicationEvent("refreshChat", refreshChatHashMap)); + } + } + } + } + + private void processRoomJoinMessage(EventOverallWebSocketMessage eventOverallWebSocketMessage) { + List> joinEventList = (List>) eventOverallWebSocketMessage + .getEventMap() + .get("join"); + HashMap internalHashMap; + Participant participant; + for (int i = 0; i < joinEventList.size(); i++) { + internalHashMap = joinEventList.get(i); + HashMap userMap = (HashMap) internalHashMap.get("user"); + participant = new Participant(); + String userId = (String) internalHashMap.get("userid"); + if (userId != null) { + participant.setActorType(USERS); + participant.setActorId(userId); + } else { + participant.setActorType(GUESTS); + // FIXME seems to be not given by the HPB: participant.setActorId(); + } + if (userMap != null) { + // There is no "user" attribute for guest participants. + participant.setDisplayName((String) userMap.get("displayname")); + } + usersHashMap.put((String) internalHashMap.get("sessionid"), participant); + } + } + + private void processJoinedRoomMessage(String text) throws IOException { + JoinedRoomOverallWebSocketMessage joinedRoomOverallWebSocketMessage = + LoganSquare.parse(text, JoinedRoomOverallWebSocketMessage.class); + if (joinedRoomOverallWebSocketMessage.getRoomWebSocketMessage() != null) { + currentRoomToken = joinedRoomOverallWebSocketMessage.getRoomWebSocketMessage().getRoomId(); + + if (joinedRoomOverallWebSocketMessage + .getRoomWebSocketMessage() + .getRoomPropertiesWebSocketMessage() != null && + !TextUtils.isEmpty(currentRoomToken)) { + sendRoomJoinedEvent(); + } + } + } + + private void processErrorMessage(WebSocket webSocket, String text) throws IOException { + Log.e(TAG, "Received error: " + text); + ErrorOverallWebSocketMessage errorOverallWebSocketMessage = + LoganSquare.parse(text, ErrorOverallWebSocketMessage.class); + ErrorWebSocketMessage message = errorOverallWebSocketMessage.getErrorWebSocketMessage(); + + if(message != null) { + if ("no_such_session".equals(message.getCode())) { + Log.d(TAG, "WebSocket " + webSocket.hashCode() + " resumeID " + resumeId + " expired"); + resumeId = ""; + currentRoomToken = ""; + restartWebSocket(); + } else if ("hello_expected".equals(message.getCode())) { + restartWebSocket(); + } + } + } + + private void processHelloMessage(WebSocket webSocket, String text) throws IOException { + connected = true; + reconnecting = false; + String oldResumeId = resumeId; + HelloResponseOverallWebSocketMessage helloResponseWebSocketMessage = + LoganSquare.parse(text, HelloResponseOverallWebSocketMessage.class); + if (helloResponseWebSocketMessage.getHelloResponseWebSocketMessage() != null) { + resumeId = helloResponseWebSocketMessage.getHelloResponseWebSocketMessage().getResumeId(); + sessionId = helloResponseWebSocketMessage.getHelloResponseWebSocketMessage().getSessionId(); + hasMCU = helloResponseWebSocketMessage.getHelloResponseWebSocketMessage().serverHasMCUSupport(); + } + + for (int i = 0; i < messagesQueue.size(); i++) { + webSocket.send(messagesQueue.get(i)); + } + + messagesQueue = new ArrayList<>(); + HashMap helloHasHap = new HashMap<>(); + if (!TextUtils.isEmpty(oldResumeId)) { + helloHasHap.put("oldResumeId", oldResumeId); + } else { + currentRoomToken = ""; + } + + if (!TextUtils.isEmpty(currentRoomToken)) { + helloHasHap.put(ROOM_TOKEN, currentRoomToken); + } + eventBus.post(new WebSocketCommunicationEvent("hello", helloHasHap)); + } + private void sendRoomJoinedEvent() { HashMap joinRoomHashMap = new HashMap<>(); joinRoomHashMap.put(ROOM_TOKEN, currentRoomToken); @@ -302,12 +366,12 @@ public class MagicWebSocketInstance extends WebSocketListener { } @Override - public void onMessage(WebSocket webSocket, ByteString bytes) { + public void onMessage(@NonNull WebSocket webSocket, ByteString bytes) { Log.d(TAG, "Receiving bytes : " + bytes.hex()); } @Override - public void onClosing(WebSocket webSocket, int code, String reason) { + public void onClosing(@NonNull WebSocket webSocket, int code, @NonNull String reason) { Log.d(TAG, "Closing : " + code + " / " + reason); } @@ -330,7 +394,8 @@ public class MagicWebSocketInstance extends WebSocketListener { Log.d(TAG, " roomToken: " + roomToken); Log.d(TAG, " session: " + normalBackendSession); try { - String message = LoganSquare.serialize(webSocketConnectionHelper.getAssembledJoinOrLeaveRoomModel(roomToken, normalBackendSession)); + String message = LoganSquare.serialize( + webSocketConnectionHelper.getAssembledJoinOrLeaveRoomModel(roomToken, normalBackendSession)); if (!connected || reconnecting) { messagesQueue.add(message); } else { @@ -347,7 +412,8 @@ public class MagicWebSocketInstance extends WebSocketListener { private void sendCallMessage(NCSignalingMessage ncSignalingMessage) { try { - String message = LoganSquare.serialize(webSocketConnectionHelper.getAssembledCallMessageModel(ncSignalingMessage)); + String message = LoganSquare.serialize( + webSocketConnectionHelper.getAssembledCallMessageModel(ncSignalingMessage)); if (!connected || reconnecting) { messagesQueue.add(message); } else { @@ -388,7 +454,8 @@ public class MagicWebSocketInstance extends WebSocketListener { @Subscribe(threadMode = ThreadMode.BACKGROUND) public void onMessageEvent(NetworkEvent networkEvent) { - if (networkEvent.getNetworkConnectionEvent() == NetworkEvent.NetworkConnectionEvent.NETWORK_CONNECTED && !isConnected()) { + if (networkEvent.getNetworkConnectionEvent() == NetworkEvent.NetworkConnectionEvent.NETWORK_CONNECTED && + !isConnected()) { restartWebSocket(); } } @@ -404,9 +471,9 @@ public class MagicWebSocketInstance extends WebSocketListener { /** * Temporary implementation of SignalingMessageReceiver until signaling related code is extracted to a Signaling * class. - * - * All listeners are called in the WebSocket reader thread. This thread should be the same as long as the - * WebSocket stays connected, but it may change whenever it is connected again. + *

+ * All listeners are called in the WebSocket reader thread. This thread should be the same as long as the WebSocket + * stays connected, but it may change whenever it is connected again. */ private static class ExternalSignalingMessageReceiver extends SignalingMessageReceiver { public void process(Map eventMap) { diff --git a/app/src/main/java/com/nextcloud/talk/webrtc/PeerConnectionWrapper.java b/app/src/main/java/com/nextcloud/talk/webrtc/PeerConnectionWrapper.java index f4a7d6b7e..98ef3ba5d 100644 --- a/app/src/main/java/com/nextcloud/talk/webrtc/PeerConnectionWrapper.java +++ b/app/src/main/java/com/nextcloud/talk/webrtc/PeerConnectionWrapper.java @@ -171,7 +171,7 @@ public class PeerConnectionWrapper { dataChannel.registerObserver(new MagicDataChannelObserver()); if (isMCUPublisher) { peerConnection.createOffer(magicSdpObserver, mediaConstraints); - } else if (hasMCU && this.videoStreamType.equals("video")) { + } else if (hasMCU && "video".equals(this.videoStreamType)) { // If the connection type is "screen" the client sharing the screen will send an // offer; offers should be requested only for videos. // "to" property is not actually needed in the "requestoffer" signaling message, but it is used to @@ -360,8 +360,9 @@ public class PeerConnectionWrapper { @Override public void onStateChange() { - if (dataChannel != null && dataChannel.state() == DataChannel.State.OPEN && - dataChannel.label().equals("status")) { + if (dataChannel != null && + dataChannel.state() == DataChannel.State.OPEN && + "status".equals(dataChannel.label())) { sendInitialMediaStatus(); } } @@ -493,7 +494,7 @@ public class PeerConnectionWrapper { @Override public void onDataChannel(DataChannel dataChannel) { - if (dataChannel.label().equals("status") || dataChannel.label().equals("JanusDataChannel")) { + if ("status".equals(dataChannel.label()) || "JanusDataChannel".equals(dataChannel.label())) { PeerConnectionWrapper.this.dataChannel = dataChannel; PeerConnectionWrapper.this.dataChannel.registerObserver(new MagicDataChannelObserver()); } diff --git a/app/src/main/java/com/nextcloud/talk/webrtc/WebRtcAudioManager.java b/app/src/main/java/com/nextcloud/talk/webrtc/WebRtcAudioManager.java index f7e36034e..a3cf70773 100644 --- a/app/src/main/java/com/nextcloud/talk/webrtc/WebRtcAudioManager.java +++ b/app/src/main/java/com/nextcloud/talk/webrtc/WebRtcAudioManager.java @@ -399,7 +399,7 @@ public class WebRtcAudioManager { return false; } - public void updateAudioDeviceState() { + public final void updateAudioDeviceState() { ThreadUtils.checkIsOnMainThread(); Log.d(TAG, "--- updateAudioDeviceState: " + "wired headset=" + hasWiredHeadset + ", " diff --git a/app/src/main/java/com/nextcloud/talk/webrtc/WebRtcBluetoothManager.java b/app/src/main/java/com/nextcloud/talk/webrtc/WebRtcBluetoothManager.java index 2655f9ba7..ba530f1c3 100644 --- a/app/src/main/java/com/nextcloud/talk/webrtc/WebRtcBluetoothManager.java +++ b/app/src/main/java/com/nextcloud/talk/webrtc/WebRtcBluetoothManager.java @@ -109,8 +109,6 @@ public class WebRtcBluetoothManager { return bluetoothState; } - ; - /** * Activates components required to detect Bluetooth devices and to enable * BT SCO (audio is routed via BT SCO) for the headset profile. The end @@ -297,7 +295,7 @@ public class WebRtcBluetoothManager { /** * Stubs for test mocks. */ - protected AudioManager getAudioManager(Context context) { + protected final AudioManager getAudioManager(Context context) { return (AudioManager) context.getSystemService(Context.AUDIO_SERVICE); } @@ -502,8 +500,10 @@ public class WebRtcBluetoothManager { Log.d(TAG, "onServiceConnected done: BT state=" + bluetoothState); } + /** + * Notifies the client when the proxy object has been disconnected from the service. + */ @Override - /** Notifies the client when the proxy object has been disconnected from the service. */ public void onServiceDisconnected(int profile) { if (profile != BluetoothProfile.HEADSET || bluetoothState == State.UNINITIALIZED) { return; @@ -531,7 +531,7 @@ public class WebRtcBluetoothManager { // change does not tell us anything about whether we're streaming // audio to BT over SCO. Typically received when user turns on a BT // headset while audio is active using another audio device. - if (action.equals(BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED)) { + if (BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED.equals(action)) { final int state = intent.getIntExtra(BluetoothHeadset.EXTRA_STATE, BluetoothHeadset.STATE_DISCONNECTED); Log.d(TAG, "BluetoothHeadsetBroadcastReceiver.onReceive: " @@ -543,8 +543,10 @@ public class WebRtcBluetoothManager { scoConnectionAttempts = 0; updateAudioDeviceState(); } else if (state == BluetoothHeadset.STATE_CONNECTING) { + Log.d(TAG, "+++ Bluetooth is connecting..."); // No action needed. } else if (state == BluetoothHeadset.STATE_DISCONNECTING) { + Log.d(TAG, "+++ Bluetooth is disconnecting..."); // No action needed. } else if (state == BluetoothHeadset.STATE_DISCONNECTED) { // Bluetooth is probably powered off during the call. @@ -553,7 +555,7 @@ public class WebRtcBluetoothManager { } // Change in the audio (SCO) connection state of the Headset profile. // Typically received after call to startScoAudio() has finalized. - } else if (action.equals(BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED)) { + } else if (BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED.equals(action)) { final int state = intent.getIntExtra( BluetoothHeadset.EXTRA_STATE, BluetoothHeadset.STATE_AUDIO_DISCONNECTED); Log.d(TAG, "BluetoothHeadsetBroadcastReceiver.onReceive: " diff --git a/app/src/main/java/com/nextcloud/talk/webrtc/WebSocketConnectionHelper.java b/app/src/main/java/com/nextcloud/talk/webrtc/WebSocketConnectionHelper.java index 096e71b10..52259b03c 100644 --- a/app/src/main/java/com/nextcloud/talk/webrtc/WebSocketConnectionHelper.java +++ b/app/src/main/java/com/nextcloud/talk/webrtc/WebSocketConnectionHelper.java @@ -60,11 +60,13 @@ public class WebSocketConnectionHelper { @SuppressLint("LongLogTag") public static synchronized MagicWebSocketInstance getMagicWebSocketInstanceForUserId(long userId) { - if (userId != -1 && magicWebSocketInstanceMap.containsKey(userId)) { - return magicWebSocketInstanceMap.get(userId); + MagicWebSocketInstance webSocketInstance = magicWebSocketInstanceMap.get(userId); + + if (webSocketInstance == null) { + Log.d(TAG, "No magicWebSocketInstance found for user " + userId); } - Log.d(TAG, "no magicWebSocketInstance found"); - return null; + + return webSocketInstance; } public static synchronized MagicWebSocketInstance getExternalSignalingInstanceForServer(String url,