mirror of
https://github.com/nextcloud/talk-android
synced 2025-06-20 20:19:42 +01:00
Merge pull request #2656 from nextcloud/chore/noid/spotbugsImprovements
Spotbugs improvements
This commit is contained in:
commit
34cd485d4b
@ -90,7 +90,6 @@ import com.nextcloud.talk.utils.NotificationUtils;
|
|||||||
import com.nextcloud.talk.utils.animations.PulseAnimation;
|
import com.nextcloud.talk.utils.animations.PulseAnimation;
|
||||||
import com.nextcloud.talk.utils.permissions.PlatformPermissionUtil;
|
import com.nextcloud.talk.utils.permissions.PlatformPermissionUtil;
|
||||||
import com.nextcloud.talk.utils.power.PowerManagerUtils;
|
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.utils.singletons.ApplicationWideCurrentRoomHolder;
|
||||||
import com.nextcloud.talk.webrtc.MagicWebRTCUtils;
|
import com.nextcloud.talk.webrtc.MagicWebRTCUtils;
|
||||||
import com.nextcloud.talk.webrtc.MagicWebSocketInstance;
|
import com.nextcloud.talk.webrtc.MagicWebSocketInstance;
|
||||||
@ -100,7 +99,6 @@ import com.nextcloud.talk.webrtc.WebSocketConnectionHelper;
|
|||||||
import com.wooplr.spotlight.SpotlightView;
|
import com.wooplr.spotlight.SpotlightView;
|
||||||
|
|
||||||
import org.apache.commons.lang3.StringEscapeUtils;
|
import org.apache.commons.lang3.StringEscapeUtils;
|
||||||
import org.greenrobot.eventbus.EventBus;
|
|
||||||
import org.greenrobot.eventbus.Subscribe;
|
import org.greenrobot.eventbus.Subscribe;
|
||||||
import org.greenrobot.eventbus.ThreadMode;
|
import org.greenrobot.eventbus.ThreadMode;
|
||||||
import org.webrtc.AudioSource;
|
import org.webrtc.AudioSource;
|
||||||
@ -178,14 +176,13 @@ public class CallActivity extends CallBaseActivity {
|
|||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
NcApi ncApi;
|
NcApi ncApi;
|
||||||
@Inject
|
|
||||||
EventBus eventBus;
|
|
||||||
@Inject
|
@Inject
|
||||||
UserManager userManager;
|
UserManager userManager;
|
||||||
@Inject
|
|
||||||
AppPreferences appPreferences;
|
|
||||||
@Inject
|
@Inject
|
||||||
Cache cache;
|
Cache cache;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
PlatformPermissionUtil permissionUtil;
|
PlatformPermissionUtil permissionUtil;
|
||||||
|
|
||||||
@ -367,7 +364,7 @@ public class CallActivity extends CallBaseActivity {
|
|||||||
|
|
||||||
powerManagerUtils = new PowerManagerUtils();
|
powerManagerUtils = new PowerManagerUtils();
|
||||||
|
|
||||||
if (extras.getString("state", "").equalsIgnoreCase("resume")) {
|
if ("resume".equalsIgnoreCase(extras.getString("state", ""))) {
|
||||||
setCallState(CallStatus.IN_CONVERSATION);
|
setCallState(CallStatus.IN_CONVERSATION);
|
||||||
} else {
|
} else {
|
||||||
setCallState(CallStatus.CONNECTING);
|
setCallState(CallStatus.CONNECTING);
|
||||||
@ -592,7 +589,7 @@ public class CallActivity extends CallBaseActivity {
|
|||||||
private void handleFromNotification() {
|
private void handleFromNotification() {
|
||||||
int apiVersion = ApiUtils.getConversationApiVersion(conversationUser, new int[]{ApiUtils.APIv4, 1});
|
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)
|
.retry(3)
|
||||||
.subscribeOn(Schedulers.io())
|
.subscribeOn(Schedulers.io())
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
|
@ -21,7 +21,7 @@ public abstract class CallBaseActivity extends BaseActivity {
|
|||||||
public static final String TAG = "CallBaseActivity";
|
public static final String TAG = "CallBaseActivity";
|
||||||
|
|
||||||
public PictureInPictureParams.Builder mPictureInPictureParamsBuilder;
|
public PictureInPictureParams.Builder mPictureInPictureParamsBuilder;
|
||||||
public Boolean isInPipMode = false;
|
public Boolean isInPipMode = Boolean.FALSE;
|
||||||
long onCreateTime;
|
long onCreateTime;
|
||||||
|
|
||||||
@SuppressLint("ClickableViewAccessibility")
|
@SuppressLint("ClickableViewAccessibility")
|
||||||
|
@ -125,9 +125,9 @@ public class AdvancedUserItem extends AbstractFlexibleItem<AdvancedUserItem.User
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (user != null && user.getBaseUrl() != null &&
|
if (user != null &&
|
||||||
user.getBaseUrl().startsWith("http://") ||
|
user.getBaseUrl() != null &&
|
||||||
user.getBaseUrl().startsWith("https://")) {
|
(user.getBaseUrl().startsWith("http://") || user.getBaseUrl().startsWith("https://"))) {
|
||||||
ImageViewExtensionsKt.loadAvatar(holder.binding.userIcon, user, participant.getCalculatedActorId(), true);
|
ImageViewExtensionsKt.loadAvatar(holder.binding.userIcon, user, participant.getCalculatedActorId(), true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -38,6 +38,7 @@ import com.nextcloud.talk.models.json.participants.Participant;
|
|||||||
import com.nextcloud.talk.ui.theme.ViewThemeUtils;
|
import com.nextcloud.talk.ui.theme.ViewThemeUtils;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
import androidx.core.content.res.ResourcesCompat;
|
import androidx.core.content.res.ResourcesCompat;
|
||||||
@ -171,10 +172,15 @@ public class ContactItem extends AbstractFlexibleItem<ContactItem.ContactItemVie
|
|||||||
if (!TextUtils.isEmpty(participant.getDisplayName())) {
|
if (!TextUtils.isEmpty(participant.getDisplayName())) {
|
||||||
displayName = participant.getDisplayName();
|
displayName = participant.getDisplayName();
|
||||||
} else {
|
} else {
|
||||||
displayName = NextcloudTalkApplication.Companion.getSharedApplication()
|
displayName = Objects.requireNonNull(NextcloudTalkApplication.Companion.getSharedApplication())
|
||||||
.getResources().getString(R.string.nc_guest);
|
.getResources().getString(R.string.nc_guest);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// absolute fallback to prevent NPE deference
|
||||||
|
if (displayName == null) {
|
||||||
|
displayName = "Guest";
|
||||||
|
}
|
||||||
|
|
||||||
ImageViewExtensionsKt.loadAvatar(holder.binding.avatarView, user, displayName, true);
|
ImageViewExtensionsKt.loadAvatar(holder.binding.avatarView, user, displayName, true);
|
||||||
} else if (participant.getCalculatedActorType() == Participant.ActorType.USERS ||
|
} else if (participant.getCalculatedActorType() == Participant.ActorType.USERS ||
|
||||||
PARTICIPANT_SOURCE_USERS.equals(participant.getSource())) {
|
PARTICIPANT_SOURCE_USERS.equals(participant.getSource())) {
|
||||||
|
@ -28,6 +28,7 @@ import com.nextcloud.talk.R;
|
|||||||
import com.nextcloud.talk.databinding.RvItemNotificationSoundBinding;
|
import com.nextcloud.talk.databinding.RvItemNotificationSoundBinding;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
import eu.davidea.flexibleadapter.FlexibleAdapter;
|
import eu.davidea.flexibleadapter.FlexibleAdapter;
|
||||||
import eu.davidea.flexibleadapter.items.AbstractFlexibleItem;
|
import eu.davidea.flexibleadapter.items.AbstractFlexibleItem;
|
||||||
@ -54,7 +55,25 @@ public class NotificationSoundItem extends AbstractFlexibleItem<NotificationSoun
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object o) {
|
public boolean equals(Object o) {
|
||||||
return false;
|
if (this == o) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (o == null || getClass() != o.getClass()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
NotificationSoundItem that = (NotificationSoundItem) o;
|
||||||
|
|
||||||
|
if (!Objects.equals(notificationSoundName, that.notificationSoundName)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return Objects.equals(notificationSoundUri, that.notificationSoundUri);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
int result = notificationSoundName != null ? notificationSoundName.hashCode() : 0;
|
||||||
|
return 31 * result + (notificationSoundUri != null ? notificationSoundUri.hashCode() : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -154,8 +154,11 @@ public class ParticipantItem extends AbstractFlexibleItem<ParticipantItem.Partic
|
|||||||
participant.getType() == Participant.ParticipantType.GUEST ||
|
participant.getType() == Participant.ParticipantType.GUEST ||
|
||||||
participant.getType() == Participant.ParticipantType.GUEST_MODERATOR) {
|
participant.getType() == Participant.ParticipantType.GUEST_MODERATOR) {
|
||||||
|
|
||||||
String displayName = NextcloudTalkApplication.Companion.getSharedApplication()
|
String displayName = NextcloudTalkApplication
|
||||||
.getResources().getString(R.string.nc_guest);
|
.Companion
|
||||||
|
.getSharedApplication()
|
||||||
|
.getResources()
|
||||||
|
.getString(R.string.nc_guest);
|
||||||
|
|
||||||
if (!TextUtils.isEmpty(participant.getDisplayName())) {
|
if (!TextUtils.isEmpty(participant.getDisplayName())) {
|
||||||
displayName = participant.getDisplayName();
|
displayName = participant.getDisplayName();
|
||||||
@ -164,8 +167,11 @@ public class ParticipantItem extends AbstractFlexibleItem<ParticipantItem.Partic
|
|||||||
ImageViewExtensionsKt.loadGuestAvatar(holder.binding.avatarView, user, displayName, false);
|
ImageViewExtensionsKt.loadGuestAvatar(holder.binding.avatarView, user, displayName, false);
|
||||||
|
|
||||||
} else if (participant.getCalculatedActorType() == Participant.ActorType.USERS ||
|
} else if (participant.getCalculatedActorType() == Participant.ActorType.USERS ||
|
||||||
participant.getSource().equals("users")) {
|
"users".equals(participant.getSource())) {
|
||||||
ImageViewExtensionsKt.loadAvatar(holder.binding.avatarView, user, participant.getCalculatedActorId(), true);
|
ImageViewExtensionsKt.loadAvatar(holder.binding.avatarView,
|
||||||
|
user,
|
||||||
|
participant.getCalculatedActorId(),
|
||||||
|
true);
|
||||||
}
|
}
|
||||||
|
|
||||||
Resources resources = NextcloudTalkApplication.Companion.getSharedApplication().getResources();
|
Resources resources = NextcloudTalkApplication.Companion.getSharedApplication().getResources();
|
||||||
@ -190,63 +196,61 @@ public class ParticipantItem extends AbstractFlexibleItem<ParticipantItem.Partic
|
|||||||
holder.binding.videoCallIcon.setVisibility(View.GONE);
|
holder.binding.videoCallIcon.setVisibility(View.GONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (holder.binding.secondaryText != null) {
|
String userType = "";
|
||||||
String userType = "";
|
|
||||||
|
|
||||||
switch (new EnumParticipantTypeConverter().convertToInt(participant.getType())) {
|
switch (new EnumParticipantTypeConverter().convertToInt(participant.getType())) {
|
||||||
case 1:
|
case 1:
|
||||||
//userType = NextcloudTalkApplication.Companion.getSharedApplication().getString(R.string.nc_owner);
|
//userType = NextcloudTalkApplication.Companion.getSharedApplication().getString(R.string.nc_owner);
|
||||||
//break;
|
//break;
|
||||||
case 2:
|
case 2:
|
||||||
case 6: // Guest moderator
|
case 6: // Guest moderator
|
||||||
|
userType = NextcloudTalkApplication
|
||||||
|
.Companion
|
||||||
|
.getSharedApplication()
|
||||||
|
.getString(R.string.nc_moderator);
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
userType = NextcloudTalkApplication
|
||||||
|
.Companion
|
||||||
|
.getSharedApplication()
|
||||||
|
.getString(R.string.nc_user);
|
||||||
|
if (participant.getCalculatedActorType() == Participant.ActorType.GROUPS) {
|
||||||
userType = NextcloudTalkApplication
|
userType = NextcloudTalkApplication
|
||||||
.Companion
|
.Companion
|
||||||
.getSharedApplication()
|
.getSharedApplication()
|
||||||
.getString(R.string.nc_moderator);
|
.getString(R.string.nc_group);
|
||||||
break;
|
}
|
||||||
case 3:
|
if (participant.getCalculatedActorType() == Participant.ActorType.CIRCLES) {
|
||||||
userType = NextcloudTalkApplication
|
userType = NextcloudTalkApplication
|
||||||
.Companion
|
.Companion
|
||||||
.getSharedApplication()
|
.getSharedApplication()
|
||||||
.getString(R.string.nc_user);
|
.getString(R.string.nc_circle);
|
||||||
if (participant.getCalculatedActorType() == Participant.ActorType.GROUPS) {
|
}
|
||||||
userType = NextcloudTalkApplication
|
break;
|
||||||
.Companion
|
case 4:
|
||||||
.getSharedApplication()
|
userType = NextcloudTalkApplication.Companion.getSharedApplication().getString(R.string.nc_guest);
|
||||||
.getString(R.string.nc_group);
|
if (participant.getCalculatedActorType() == Participant.ActorType.EMAILS) {
|
||||||
}
|
|
||||||
if (participant.getCalculatedActorType() == Participant.ActorType.CIRCLES) {
|
|
||||||
userType = NextcloudTalkApplication
|
|
||||||
.Companion
|
|
||||||
.getSharedApplication()
|
|
||||||
.getString(R.string.nc_circle);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 4:
|
|
||||||
userType = NextcloudTalkApplication.Companion.getSharedApplication().getString(R.string.nc_guest);
|
|
||||||
if (participant.getCalculatedActorType() == Participant.ActorType.EMAILS) {
|
|
||||||
userType = NextcloudTalkApplication
|
|
||||||
.Companion
|
|
||||||
.getSharedApplication()
|
|
||||||
.getString(R.string.nc_email);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 5:
|
|
||||||
userType = NextcloudTalkApplication
|
userType = NextcloudTalkApplication
|
||||||
.Companion
|
.Companion
|
||||||
.getSharedApplication()
|
.getSharedApplication()
|
||||||
.getString(R.string.nc_following_link);
|
.getString(R.string.nc_email);
|
||||||
break;
|
}
|
||||||
default:
|
break;
|
||||||
break;
|
case 5:
|
||||||
}
|
userType = NextcloudTalkApplication
|
||||||
|
.Companion
|
||||||
|
.getSharedApplication()
|
||||||
|
.getString(R.string.nc_following_link);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if (!userType.equals(NextcloudTalkApplication
|
if (!userType.equals(NextcloudTalkApplication
|
||||||
.Companion
|
.Companion
|
||||||
.getSharedApplication()
|
.getSharedApplication()
|
||||||
.getString(R.string.nc_user))) {
|
.getString(R.string.nc_user))) {
|
||||||
holder.binding.secondaryText.setText("(" + userType + ")");
|
holder.binding.secondaryText.setText("(" + userType + ")");
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -60,12 +60,10 @@ public class MentionAutocompleteCallback implements AutocompleteCallback<Mention
|
|||||||
@OptIn(markerClass = kotlin.ExperimentalStdlibApi.class)
|
@OptIn(markerClass = kotlin.ExperimentalStdlibApi.class)
|
||||||
@Override
|
@Override
|
||||||
public boolean onPopupItemClicked(Editable editable, Mention item) {
|
public boolean onPopupItemClicked(Editable editable, Mention item) {
|
||||||
int[] range = MagicCharPolicy.getQueryRange(editable);
|
MagicCharPolicy.TextSpan range = MagicCharPolicy.getQueryRange(editable);
|
||||||
if (range == null) {
|
if (range == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
int start = range[0];
|
|
||||||
int end = range[1];
|
|
||||||
String replacement = item.getLabel();
|
String replacement = item.getLabel();
|
||||||
|
|
||||||
StringBuilder replacementStringBuilder = new StringBuilder(item.getLabel());
|
StringBuilder replacementStringBuilder = new StringBuilder(item.getLabel());
|
||||||
@ -73,7 +71,7 @@ public class MentionAutocompleteCallback implements AutocompleteCallback<Mention
|
|||||||
replacementStringBuilder.delete(emojiRange.range.getStart(), emojiRange.range.getEndInclusive());
|
replacementStringBuilder.delete(emojiRange.range.getStart(), emojiRange.range.getEndInclusive());
|
||||||
}
|
}
|
||||||
|
|
||||||
editable.replace(start, end, replacementStringBuilder.toString() + " ");
|
editable.replace(range.getStart(), range.getEnd(), replacementStringBuilder + " ");
|
||||||
Spans.MentionChipSpan mentionChipSpan =
|
Spans.MentionChipSpan mentionChipSpan =
|
||||||
new Spans.MentionChipSpan(DisplayUtils.getDrawableForMentionChipSpan(context,
|
new Spans.MentionChipSpan(DisplayUtils.getDrawableForMentionChipSpan(context,
|
||||||
item.getId(),
|
item.getId(),
|
||||||
@ -85,7 +83,9 @@ public class MentionAutocompleteCallback implements AutocompleteCallback<Mention
|
|||||||
viewThemeUtils),
|
viewThemeUtils),
|
||||||
BetterImageSpan.ALIGN_CENTER,
|
BetterImageSpan.ALIGN_CENTER,
|
||||||
item.getId(), item.getLabel());
|
item.getId(), item.getLabel());
|
||||||
editable.setSpan(mentionChipSpan, start, start + replacementStringBuilder.toString().length(),
|
editable.setSpan(mentionChipSpan,
|
||||||
|
range.getStart(),
|
||||||
|
range.getStart() + replacementStringBuilder.length(),
|
||||||
Spanned.SPAN_INCLUSIVE_INCLUSIVE);
|
Spanned.SPAN_INCLUSIVE_INCLUSIVE);
|
||||||
|
|
||||||
|
|
||||||
|
@ -74,8 +74,7 @@ public class DavResponse {
|
|||||||
final Object $response = this.getResponse();
|
final Object $response = this.getResponse();
|
||||||
result = result * PRIME + ($response == null ? 43 : $response.hashCode());
|
result = result * PRIME + ($response == null ? 43 : $response.hashCode());
|
||||||
final Object $data = this.getData();
|
final Object $data = this.getData();
|
||||||
result = result * PRIME + ($data == null ? 43 : $data.hashCode());
|
return result * PRIME + ($data == null ? 43 : $data.hashCode());
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public String toString() {
|
public String toString() {
|
||||||
|
@ -22,8 +22,6 @@
|
|||||||
|
|
||||||
package com.nextcloud.talk.components.filebrowser.webdav;
|
package com.nextcloud.talk.components.filebrowser.webdav;
|
||||||
|
|
||||||
import android.util.Log;
|
|
||||||
|
|
||||||
import com.nextcloud.talk.components.filebrowser.models.properties.NCEncrypted;
|
import com.nextcloud.talk.components.filebrowser.models.properties.NCEncrypted;
|
||||||
import com.nextcloud.talk.components.filebrowser.models.properties.NCPermission;
|
import com.nextcloud.talk.components.filebrowser.models.properties.NCPermission;
|
||||||
import com.nextcloud.talk.components.filebrowser.models.properties.NCPreview;
|
import com.nextcloud.talk.components.filebrowser.models.properties.NCPreview;
|
||||||
@ -31,14 +29,10 @@ import com.nextcloud.talk.components.filebrowser.models.properties.OCFavorite;
|
|||||||
import com.nextcloud.talk.components.filebrowser.models.properties.OCId;
|
import com.nextcloud.talk.components.filebrowser.models.properties.OCId;
|
||||||
import com.nextcloud.talk.components.filebrowser.models.properties.OCSize;
|
import com.nextcloud.talk.components.filebrowser.models.properties.OCSize;
|
||||||
|
|
||||||
import java.lang.reflect.Field;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import at.bitfire.dav4jvm.Property;
|
import at.bitfire.dav4jvm.Property;
|
||||||
import at.bitfire.dav4jvm.PropertyFactory;
|
|
||||||
import at.bitfire.dav4jvm.PropertyRegistry;
|
import at.bitfire.dav4jvm.PropertyRegistry;
|
||||||
import at.bitfire.dav4jvm.property.CreationDate;
|
import at.bitfire.dav4jvm.property.CreationDate;
|
||||||
import at.bitfire.dav4jvm.property.DisplayName;
|
import at.bitfire.dav4jvm.property.DisplayName;
|
||||||
@ -49,7 +43,6 @@ import at.bitfire.dav4jvm.property.GetLastModified;
|
|||||||
import at.bitfire.dav4jvm.property.ResourceType;
|
import at.bitfire.dav4jvm.property.ResourceType;
|
||||||
|
|
||||||
public class DavUtils {
|
public class DavUtils {
|
||||||
private static final String TAG = "DavUtils";
|
|
||||||
|
|
||||||
public static final String OC_NAMESPACE = "http://owncloud.org/ns";
|
public static final String OC_NAMESPACE = "http://owncloud.org/ns";
|
||||||
public static final String NC_NAMESPACE = "http://nextcloud.org/ns";
|
public static final String NC_NAMESPACE = "http://nextcloud.org/ns";
|
||||||
@ -66,15 +59,16 @@ public class DavUtils {
|
|||||||
public static final String EXTENDED_PROPERTY_UNREAD_COMMENTS = "comments-unread";
|
public static final String EXTENDED_PROPERTY_UNREAD_COMMENTS = "comments-unread";
|
||||||
public static final String EXTENDED_PROPERTY_HAS_PREVIEW = "has-preview";
|
public static final String EXTENDED_PROPERTY_HAS_PREVIEW = "has-preview";
|
||||||
public static final String EXTENDED_PROPERTY_NOTE = "note";
|
public static final String EXTENDED_PROPERTY_NOTE = "note";
|
||||||
public static final String TRASHBIN_FILENAME = "trashbin-filename";
|
|
||||||
public static final String TRASHBIN_ORIGINAL_LOCATION = "trashbin-original-location";
|
|
||||||
public static final String TRASHBIN_DELETION_TIME = "trashbin-deletion-time";
|
|
||||||
|
|
||||||
public static final String PROPERTY_QUOTA_USED_BYTES = "quota-used-bytes";
|
// public static final String TRASHBIN_FILENAME = "trashbin-filename";
|
||||||
public static final String PROPERTY_QUOTA_AVAILABLE_BYTES = "quota-available-bytes";
|
// public static final String TRASHBIN_ORIGINAL_LOCATION = "trashbin-original-location";
|
||||||
|
// public static final String TRASHBIN_DELETION_TIME = "trashbin-deletion-time";
|
||||||
|
|
||||||
|
// public static final String PROPERTY_QUOTA_USED_BYTES = "quota-used-bytes";
|
||||||
|
// public static final String PROPERTY_QUOTA_AVAILABLE_BYTES = "quota-available-bytes";
|
||||||
|
|
||||||
static Property.Name[] getAllPropSet() {
|
static Property.Name[] getAllPropSet() {
|
||||||
List<Property.Name> props = new ArrayList<>();
|
List<Property.Name> props = new ArrayList<>(20);
|
||||||
|
|
||||||
props.add(DisplayName.NAME);
|
props.add(DisplayName.NAME);
|
||||||
props.add(GetContentType.NAME);
|
props.add(GetContentType.NAME);
|
||||||
@ -104,22 +98,12 @@ public class DavUtils {
|
|||||||
|
|
||||||
public static void registerCustomFactories() {
|
public static void registerCustomFactories() {
|
||||||
PropertyRegistry propertyRegistry = PropertyRegistry.INSTANCE;
|
PropertyRegistry propertyRegistry = PropertyRegistry.INSTANCE;
|
||||||
try {
|
|
||||||
Field factories = propertyRegistry.getClass().getDeclaredField("factories");
|
|
||||||
factories.setAccessible(true);
|
|
||||||
Map<Property.Name, PropertyFactory> reflectionMap = (HashMap<Property.Name,
|
|
||||||
PropertyFactory>) factories.get(propertyRegistry);
|
|
||||||
|
|
||||||
reflectionMap.put(OCId.NAME, new OCId.Factory());
|
propertyRegistry.register(new OCId.Factory());
|
||||||
reflectionMap.put(NCPreview.NAME, new NCPreview.Factory());
|
propertyRegistry.register(new NCPreview.Factory());
|
||||||
reflectionMap.put(NCEncrypted.NAME, new NCEncrypted.Factory());
|
propertyRegistry.register(new NCEncrypted.Factory());
|
||||||
reflectionMap.put(OCFavorite.NAME, new OCFavorite.Factory());
|
propertyRegistry.register(new OCFavorite.Factory());
|
||||||
reflectionMap.put(OCSize.NAME, new OCSize.Factory());
|
propertyRegistry.register(new OCSize.Factory());
|
||||||
reflectionMap.put(NCPermission.NAME, new NCPermission.Factory());
|
propertyRegistry.register(new NCPermission.Factory());
|
||||||
|
|
||||||
factories.set(propertyRegistry, reflectionMap);
|
|
||||||
} catch (NoSuchFieldException | IllegalAccessException e) {
|
|
||||||
Log.w(TAG, "Error registering custom factories", e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -69,7 +69,6 @@ public class ReadFilesystemOperation {
|
|||||||
DavResponse davResponse = new DavResponse();
|
DavResponse davResponse = new DavResponse();
|
||||||
final List<Response> memberElements = new ArrayList<>();
|
final List<Response> memberElements = new ArrayList<>();
|
||||||
final Response[] rootElement = new Response[1];
|
final Response[] rootElement = new Response[1];
|
||||||
final List<BrowserFile> remoteFiles = new ArrayList<>();
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
new DavResource(okHttpClient, HttpUrl.parse(url)).propfind(depth, DavUtils.getAllPropSet(),
|
new DavResource(okHttpClient, HttpUrl.parse(url)).propfind(depth, DavUtils.getAllPropSet(),
|
||||||
@ -94,6 +93,7 @@ public class ReadFilesystemOperation {
|
|||||||
Log.w(TAG, "Error reading remote path");
|
Log.w(TAG, "Error reading remote path");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final List<BrowserFile> remoteFiles = new ArrayList<>(1 + memberElements.size());
|
||||||
remoteFiles.add(BrowserFile.Companion.getModelFromResponse(rootElement[0],
|
remoteFiles.add(BrowserFile.Companion.getModelFromResponse(rootElement[0],
|
||||||
rootElement[0].getHref().toString().substring(basePath.length())));
|
rootElement[0].getHref().toString().substring(basePath.length())));
|
||||||
for (Response memberElement : memberElements) {
|
for (Response memberElement : memberElements) {
|
||||||
|
@ -249,9 +249,7 @@ public class RestModule {
|
|||||||
.method(original.method(), original.body())
|
.method(original.method(), original.body())
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
Response response = chain.proceed(request);
|
return chain.proceed(request);
|
||||||
|
|
||||||
return response;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -89,8 +89,7 @@ public class EventStatus {
|
|||||||
result = result * PRIME + (int) ($userId >>> 32 ^ $userId);
|
result = result * PRIME + (int) ($userId >>> 32 ^ $userId);
|
||||||
final Object $eventType = this.getEventType();
|
final Object $eventType = this.getEventType();
|
||||||
result = result * PRIME + ($eventType == null ? 43 : $eventType.hashCode());
|
result = result * PRIME + ($eventType == null ? 43 : $eventType.hashCode());
|
||||||
result = result * PRIME + (this.isAllGood() ? 79 : 97);
|
return result * PRIME + (this.isAllGood() ? 79 : 97);
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public String toString() {
|
public String toString() {
|
||||||
|
@ -58,8 +58,7 @@ public class MoreMenuClickEvent {
|
|||||||
final int PRIME = 59;
|
final int PRIME = 59;
|
||||||
int result = 1;
|
int result = 1;
|
||||||
final Object $conversation = this.getConversation();
|
final Object $conversation = this.getConversation();
|
||||||
result = result * PRIME + ($conversation == null ? 43 : $conversation.hashCode());
|
return result * PRIME + ($conversation == null ? 43 : $conversation.hashCode());
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public String toString() {
|
public String toString() {
|
||||||
|
@ -56,8 +56,7 @@ public class NetworkEvent {
|
|||||||
final int PRIME = 59;
|
final int PRIME = 59;
|
||||||
int result = 1;
|
int result = 1;
|
||||||
final Object $networkConnectionEvent = this.getNetworkConnectionEvent();
|
final Object $networkConnectionEvent = this.getNetworkConnectionEvent();
|
||||||
result = result * PRIME + ($networkConnectionEvent == null ? 43 : $networkConnectionEvent.hashCode());
|
return result * PRIME + ($networkConnectionEvent == null ? 43 : $networkConnectionEvent.hashCode());
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public String toString() {
|
public String toString() {
|
||||||
|
@ -56,8 +56,7 @@ public class UserMentionClickEvent {
|
|||||||
final int PRIME = 59;
|
final int PRIME = 59;
|
||||||
int result = 1;
|
int result = 1;
|
||||||
final Object $userId = this.getUserId();
|
final Object $userId = this.getUserId();
|
||||||
result = result * PRIME + ($userId == null ? 43 : $userId.hashCode());
|
return result * PRIME + ($userId == null ? 43 : $userId.hashCode());
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public String toString() {
|
public String toString() {
|
||||||
|
@ -75,8 +75,7 @@ public class WebSocketCommunicationEvent {
|
|||||||
final Object $type = this.getType();
|
final Object $type = this.getType();
|
||||||
result = result * PRIME + ($type == null ? 43 : $type.hashCode());
|
result = result * PRIME + ($type == null ? 43 : $type.hashCode());
|
||||||
final Object $hashMap = this.getHashMap();
|
final Object $hashMap = this.getHashMap();
|
||||||
result = result * PRIME + ($hashMap == null ? 43 : $hashMap.hashCode());
|
return result * PRIME + ($hashMap == null ? 43 : $hashMap.hashCode());
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public String toString() {
|
public String toString() {
|
||||||
|
@ -98,8 +98,7 @@ public class ImportAccount {
|
|||||||
final Object $token = this.getToken();
|
final Object $token = this.getToken();
|
||||||
result = result * PRIME + ($token == null ? 43 : $token.hashCode());
|
result = result * PRIME + ($token == null ? 43 : $token.hashCode());
|
||||||
final Object $baseUrl = this.getBaseUrl();
|
final Object $baseUrl = this.getBaseUrl();
|
||||||
result = result * PRIME + ($baseUrl == null ? 43 : $baseUrl.hashCode());
|
return result * PRIME + ($baseUrl == null ? 43 : $baseUrl.hashCode());
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public String toString() {
|
public String toString() {
|
||||||
|
@ -147,7 +147,8 @@ public class MentionAutocompletePresenter extends RecyclerViewPresenter<Mention>
|
|||||||
if (mentionsList.size() == 0) {
|
if (mentionsList.size() == 0) {
|
||||||
adapter.clear();
|
adapter.clear();
|
||||||
} else {
|
} else {
|
||||||
List<AbstractFlexibleItem> internalAbstractFlexibleItemList = new ArrayList<>();
|
List<AbstractFlexibleItem> internalAbstractFlexibleItemList =
|
||||||
|
new ArrayList<>(mentionsList.size());
|
||||||
for (Mention mention : mentionsList) {
|
for (Mention mention : mentionsList) {
|
||||||
internalAbstractFlexibleItemList.add(
|
internalAbstractFlexibleItemList.add(
|
||||||
new MentionAutocompleteItem(
|
new MentionAutocompleteItem(
|
||||||
|
@ -42,9 +42,9 @@ import androidx.core.content.res.ResourcesCompat;
|
|||||||
*/
|
*/
|
||||||
public class StatusDrawable extends Drawable {
|
public class StatusDrawable extends Drawable {
|
||||||
private String text;
|
private String text;
|
||||||
private @DrawableRes int icon = -1;
|
private StatusDrawableType icon = StatusDrawableType.UNDEFINED;
|
||||||
private Paint textPaint;
|
private Paint textPaint;
|
||||||
private int backgroundColor;
|
private final int backgroundColor;
|
||||||
private final float radius;
|
private final float radius;
|
||||||
private Context context;
|
private Context context;
|
||||||
|
|
||||||
@ -54,17 +54,17 @@ public class StatusDrawable extends Drawable {
|
|||||||
|
|
||||||
|
|
||||||
if ("dnd".equals(status)) {
|
if ("dnd".equals(status)) {
|
||||||
icon = R.drawable.ic_user_status_dnd;
|
icon = StatusDrawableType.DND;
|
||||||
this.context = context;
|
this.context = context;
|
||||||
} else if (TextUtils.isEmpty(statusIcon) && status != null) {
|
} else if (TextUtils.isEmpty(statusIcon) && status != null) {
|
||||||
switch (status) {
|
switch (status) {
|
||||||
case "online":
|
case "online":
|
||||||
icon = R.drawable.online_status;
|
icon = StatusDrawableType.ONLINE;
|
||||||
this.context = context;
|
this.context = context;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "away":
|
case "away":
|
||||||
icon = R.drawable.ic_user_status_away;
|
icon = StatusDrawableType.AWAY;
|
||||||
this.context = context;
|
this.context = context;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -95,7 +95,7 @@ public class StatusDrawable extends Drawable {
|
|||||||
canvas.drawText(text, radius, radius - ((textPaint.descent() + textPaint.ascent()) / 2), textPaint);
|
canvas.drawText(text, radius, radius - ((textPaint.descent() + textPaint.ascent()) / 2), textPaint);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (icon != -1) {
|
if (icon != StatusDrawableType.UNDEFINED) {
|
||||||
|
|
||||||
Paint backgroundPaint = new Paint();
|
Paint backgroundPaint = new Paint();
|
||||||
backgroundPaint.setStyle(Paint.Style.FILL);
|
backgroundPaint.setStyle(Paint.Style.FILL);
|
||||||
@ -104,7 +104,7 @@ public class StatusDrawable extends Drawable {
|
|||||||
|
|
||||||
canvas.drawCircle(radius, radius, radius, backgroundPaint);
|
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) {
|
if (drawable != null) {
|
||||||
drawable.setBounds(0,
|
drawable.setBounds(0,
|
||||||
@ -130,4 +130,18 @@ public class StatusDrawable extends Drawable {
|
|||||||
public int getOpacity() {
|
public int getOpacity() {
|
||||||
return PixelFormat.TRANSLUCENT;
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -177,7 +177,6 @@ public class SortingOrderDialogFragment extends DialogFragment implements View.O
|
|||||||
binding.cancel.setOnClickListener(view -> dismiss());
|
binding.cancel.setOnClickListener(view -> dismiss());
|
||||||
|
|
||||||
for (View view : taggedViews) {
|
for (View view : taggedViews) {
|
||||||
Log.i("SortOrder", "view="+view.getTag().toString());
|
|
||||||
view.setOnClickListener(this);
|
view.setOnClickListener(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -62,8 +62,7 @@ public class AuthenticatorService extends Service {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Bundle getAuthToken(AccountAuthenticatorResponse response, Account account, String authTokenType, Bundle options)
|
public Bundle getAuthToken(AccountAuthenticatorResponse response, Account account, String authTokenType, Bundle options) throws NetworkErrorException {
|
||||||
throws NetworkErrorException {
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -73,8 +72,7 @@ public class AuthenticatorService extends Service {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Bundle hasFeatures(AccountAuthenticatorResponse response,
|
public Bundle hasFeatures(AccountAuthenticatorResponse response, Account account, String[] features) {
|
||||||
Account account, String[] features) {
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -82,7 +80,6 @@ public class AuthenticatorService extends Service {
|
|||||||
public Bundle updateCredentials(AccountAuthenticatorResponse response, Account account, String authTokenType, Bundle options) {
|
public Bundle updateCredentials(AccountAuthenticatorResponse response, Account account, String authTokenType, Bundle options) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Authenticator getAuthenticator() {
|
protected Authenticator getAuthenticator() {
|
||||||
@ -95,7 +92,7 @@ public class AuthenticatorService extends Service {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IBinder onBind(Intent intent) {
|
public IBinder onBind(Intent intent) {
|
||||||
if (intent.getAction().equals(AccountManager.ACTION_AUTHENTICATOR_INTENT)) {
|
if (AccountManager.ACTION_AUTHENTICATOR_INTENT.equals(intent.getAction())) {
|
||||||
return getAuthenticator().getIBinder();
|
return getAuthenticator().getIBinder();
|
||||||
} else {
|
} else {
|
||||||
return null;
|
return null;
|
||||||
|
@ -35,14 +35,17 @@ public class DeviceUtils {
|
|||||||
private static final String TAG = "DeviceUtils";
|
private static final String TAG = "DeviceUtils";
|
||||||
|
|
||||||
public static void ignoreSpecialBatteryFeatures() {
|
public static void ignoreSpecialBatteryFeatures() {
|
||||||
if (Build.MANUFACTURER.equalsIgnoreCase("xiaomi") || Build.MANUFACTURER.equalsIgnoreCase("meizu")) {
|
if ("xiaomi".equalsIgnoreCase(Build.MANUFACTURER) || "meizu".equalsIgnoreCase(Build.MANUFACTURER)) {
|
||||||
try {
|
try {
|
||||||
@SuppressLint("PrivateApi") Class<?> appOpsUtilsClass = Class.forName("android.miui.AppOpsUtils");
|
@SuppressLint("PrivateApi") Class<?> appOpsUtilsClass = Class.forName("android.miui.AppOpsUtils");
|
||||||
if (appOpsUtilsClass != null) {
|
if (appOpsUtilsClass != null) {
|
||||||
Method setApplicationAutoStartMethod = appOpsUtilsClass.getMethod("setApplicationAutoStart", Context
|
Method setApplicationAutoStartMethod = appOpsUtilsClass.getMethod("setApplicationAutoStart", Context
|
||||||
.class, String.class, Boolean.TYPE);
|
.class, String.class, Boolean.TYPE);
|
||||||
if (setApplicationAutoStartMethod != null) {
|
if (setApplicationAutoStartMethod != null) {
|
||||||
Context applicationContext = NextcloudTalkApplication.Companion.getSharedApplication().getApplicationContext();
|
Context applicationContext = NextcloudTalkApplication
|
||||||
|
.Companion
|
||||||
|
.getSharedApplication()
|
||||||
|
.getApplicationContext();
|
||||||
setApplicationAutoStartMethod.invoke(appOpsUtilsClass, applicationContext, applicationContext
|
setApplicationAutoStartMethod.invoke(appOpsUtilsClass, applicationContext, applicationContext
|
||||||
.getPackageName(), Boolean.TRUE);
|
.getPackageName(), Boolean.TRUE);
|
||||||
}
|
}
|
||||||
@ -56,10 +59,10 @@ public class DeviceUtils {
|
|||||||
} catch (InvocationTargetException e) {
|
} catch (InvocationTargetException e) {
|
||||||
Log.e(TAG, "InvocationTargetException");
|
Log.e(TAG, "InvocationTargetException");
|
||||||
}
|
}
|
||||||
} else if (Build.MANUFACTURER.equalsIgnoreCase("huawei")) {
|
} else if ("huawei".equalsIgnoreCase(Build.MANUFACTURER)) {
|
||||||
try {
|
try {
|
||||||
@SuppressLint("PrivateApi") Class<?> protectAppControlClass = Class.forName("com.huawei.systemmanager.optimize.process" +
|
@SuppressLint("PrivateApi") Class<?> protectAppControlClass = Class.forName(
|
||||||
".ProtectAppControl");
|
"com.huawei.systemmanager.optimize.process.ProtectAppControl");
|
||||||
if (protectAppControlClass != null) {
|
if (protectAppControlClass != null) {
|
||||||
Context applicationContext = NextcloudTalkApplication.Companion.getSharedApplication().getApplicationContext();
|
Context applicationContext = NextcloudTalkApplication.Companion.getSharedApplication().getApplicationContext();
|
||||||
|
|
||||||
|
@ -369,8 +369,6 @@ public class DisplayUtils {
|
|||||||
decor.setSystemUiVisibility(0);
|
decor.setSystemUiVisibility(0);
|
||||||
}
|
}
|
||||||
window.setStatusBarColor(color);
|
window.setStatusBarColor(color);
|
||||||
} else if (isLightTheme) {
|
|
||||||
window.setStatusBarColor(Color.BLACK);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -380,7 +378,7 @@ public class DisplayUtils {
|
|||||||
* @param color the color
|
* @param color the color
|
||||||
* @return true if primaryColor is lighter than MAX_LIGHTNESS
|
* @return true if primaryColor is lighter than MAX_LIGHTNESS
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("correctness")
|
@SuppressWarnings("CLI_CONSTANT_LIST_INDEX")
|
||||||
public static boolean lightTheme(int color) {
|
public static boolean lightTheme(int color) {
|
||||||
float[] hsl = colorToHSL(color);
|
float[] hsl = colorToHSL(color);
|
||||||
|
|
||||||
@ -455,10 +453,12 @@ public class DisplayUtils {
|
|||||||
avatarId = user.getUsername();
|
avatarId = user.getUsername();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (deleteCache) {
|
if (avatarId != null) {
|
||||||
ImageViewExtensionsKt.replaceAvatar(avatarImageView, user, avatarId, true);
|
if (deleteCache) {
|
||||||
} else {
|
ImageViewExtensionsKt.replaceAvatar(avatarImageView, user, avatarId, true);
|
||||||
ImageViewExtensionsKt.loadAvatar(avatarImageView, user, avatarId, true);
|
} else {
|
||||||
|
ImageViewExtensionsKt.loadAvatar(avatarImageView, user, avatarId, true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -37,43 +37,57 @@ public class MagicCharPolicy implements AutocompletePolicy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public static int[] getQueryRange(Spannable text) {
|
public static TextSpan getQueryRange(Spannable text) {
|
||||||
QuerySpan[] span = text.getSpans(0, text.length(), QuerySpan.class);
|
QuerySpan[] span = text.getSpans(0, text.length(), QuerySpan.class);
|
||||||
if (span == null || span.length == 0) return null;
|
if (span == null || span.length == 0) {
|
||||||
if (span.length > 1) {
|
return null;
|
||||||
// Do absolutely nothing
|
} 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) {
|
if (text.length() == 0) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
int[] span = new int[2];
|
|
||||||
Pattern pattern = Pattern.compile("@+\\S*", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE);
|
Pattern pattern = Pattern.compile("@+\\S*", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE);
|
||||||
Matcher matcher = pattern.matcher(text);
|
Matcher matcher = pattern.matcher(text);
|
||||||
|
|
||||||
while (matcher.find()) {
|
while (matcher.find()) {
|
||||||
if (cursorPos >= matcher.start() && cursorPos <= matcher.end()) {
|
if (cursorPos >= matcher.start() && cursorPos <= matcher.end() &&
|
||||||
span[0] = matcher.start();
|
text.subSequence(matcher.start(), matcher.end()).charAt(0) == character) {
|
||||||
span[1] = matcher.end();
|
return new TextSpan(matcher.start(), matcher.end());
|
||||||
if (text.subSequence(matcher.start(), matcher.end()).charAt(0) == character) {
|
|
||||||
return span;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
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
|
@Override
|
||||||
public boolean shouldShowPopup(Spannable text, int cursorPos) {
|
public boolean shouldShowPopup(Spannable text, int cursorPos) {
|
||||||
int[] show = checkText(text, cursorPos);
|
TextSpan show = checkText(text, cursorPos);
|
||||||
if (show != null) {
|
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 true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
@ -78,7 +78,7 @@ public class DatabaseStorageModule implements StorageModule {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void saveBoolean(String key, boolean value) {
|
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});
|
int apiVersion = ApiUtils.getConversationApiVersion(conversationUser, new int[]{4});
|
||||||
ncApi.notificationCalls(ApiUtils.getCredentials(conversationUser.getUsername(),
|
ncApi.notificationCalls(ApiUtils.getCredentials(conversationUser.getUsername(),
|
||||||
conversationUser.getToken()),
|
conversationUser.getToken()),
|
||||||
@ -112,7 +112,7 @@ public class DatabaseStorageModule implements StorageModule {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!key.equals("conversation_lobby")) {
|
if (!"conversation_lobby".equals(key)) {
|
||||||
arbitraryStorageManager.storeStorageSetting(accountIdentifier,
|
arbitraryStorageManager.storeStorageSetting(accountIdentifier,
|
||||||
key,
|
key,
|
||||||
Boolean.toString(value),
|
Boolean.toString(value),
|
||||||
@ -124,7 +124,7 @@ public class DatabaseStorageModule implements StorageModule {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void saveString(String key, String value) {
|
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});
|
int apiVersion = ApiUtils.getConversationApiVersion(conversationUser, new int[]{4});
|
||||||
|
|
||||||
String trimmedValue = value.replace("expire_", "");
|
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 (CapabilitiesUtilNew.hasSpreedFeatureCapability(conversationUser, "notification-levels")) {
|
||||||
if (!TextUtils.isEmpty(messageNotificationLevel) && !messageNotificationLevel.equals(value)) {
|
if (!TextUtils.isEmpty(messageNotificationLevel) && !messageNotificationLevel.equals(value)) {
|
||||||
int intValue;
|
int intValue;
|
||||||
@ -232,7 +232,7 @@ public class DatabaseStorageModule implements StorageModule {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean getBoolean(String key, boolean defaultVal) {
|
public boolean getBoolean(String key, boolean defaultVal) {
|
||||||
if (key.equals("conversation_lobby")) {
|
if ("conversation_lobby".equals(key)) {
|
||||||
return lobbyValue;
|
return lobbyValue;
|
||||||
} else {
|
} else {
|
||||||
return arbitraryStorageManager
|
return arbitraryStorageManager
|
||||||
@ -244,7 +244,7 @@ public class DatabaseStorageModule implements StorageModule {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getString(String key, String defaultVal) {
|
public String getString(String key, String defaultVal) {
|
||||||
if (key.equals("message_expire_key")) {
|
if ("message_expire_key".equals(key)) {
|
||||||
switch (messageExpiration) {
|
switch (messageExpiration) {
|
||||||
case 2419200:
|
case 2419200:
|
||||||
return "expire_2419200";
|
return "expire_2419200";
|
||||||
@ -259,7 +259,7 @@ public class DatabaseStorageModule implements StorageModule {
|
|||||||
default:
|
default:
|
||||||
return "expire_0";
|
return "expire_0";
|
||||||
}
|
}
|
||||||
} else if (key.equals("message_notification_level")) {
|
} else if ("message_notification_level".equals(key)) {
|
||||||
return messageNotificationLevel;
|
return messageNotificationLevel;
|
||||||
} else {
|
} else {
|
||||||
return arbitraryStorageManager
|
return arbitraryStorageManager
|
||||||
|
@ -87,13 +87,11 @@ public class Spans {
|
|||||||
final Object $id = this.getId();
|
final Object $id = this.getId();
|
||||||
result = result * PRIME + ($id == null ? 43 : $id.hashCode());
|
result = result * PRIME + ($id == null ? 43 : $id.hashCode());
|
||||||
final Object $label = this.getLabel();
|
final Object $label = this.getLabel();
|
||||||
result = result * PRIME + ($label == null ? 43 : $label.hashCode());
|
return result * PRIME + ($label == null ? 43 : $label.hashCode());
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "Spans.MentionChipSpan(id=" + this.getId() + ", label=" + this.getLabel() + ")";
|
return "Spans.MentionChipSpan(id=" + this.getId() + ", label=" + this.getLabel() + ")";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -4,4 +4,5 @@ public class Globals {
|
|||||||
public static final String ROOM_TOKEN = "roomToken";
|
public static final String ROOM_TOKEN = "roomToken";
|
||||||
|
|
||||||
public static final String TARGET_PARTICIPANTS = "participants";
|
public static final String TARGET_PARTICIPANTS = "participants";
|
||||||
|
public static final String TARGET_ROOM = "room";
|
||||||
}
|
}
|
||||||
|
@ -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.ByeWebSocketMessage;
|
||||||
import com.nextcloud.talk.models.json.websocket.CallOverallWebSocketMessage;
|
import com.nextcloud.talk.models.json.websocket.CallOverallWebSocketMessage;
|
||||||
import com.nextcloud.talk.models.json.websocket.ErrorOverallWebSocketMessage;
|
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.EventOverallWebSocketMessage;
|
||||||
import com.nextcloud.talk.models.json.websocket.HelloResponseOverallWebSocketMessage;
|
import com.nextcloud.talk.models.json.websocket.HelloResponseOverallWebSocketMessage;
|
||||||
import com.nextcloud.talk.models.json.websocket.JoinedRoomOverallWebSocketMessage;
|
import com.nextcloud.talk.models.json.websocket.JoinedRoomOverallWebSocketMessage;
|
||||||
@ -54,6 +55,7 @@ import java.util.Map;
|
|||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
import autodagger.AutoInjector;
|
import autodagger.AutoInjector;
|
||||||
import okhttp3.OkHttpClient;
|
import okhttp3.OkHttpClient;
|
||||||
import okhttp3.Request;
|
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.models.json.participants.Participant.ActorType.USERS;
|
||||||
import static com.nextcloud.talk.webrtc.Globals.ROOM_TOKEN;
|
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_PARTICIPANTS;
|
||||||
|
import static com.nextcloud.talk.webrtc.Globals.TARGET_ROOM;
|
||||||
|
|
||||||
@AutoInjector(NextcloudTalkApplication.class)
|
@AutoInjector(NextcloudTalkApplication.class)
|
||||||
public class MagicWebSocketInstance extends WebSocketListener {
|
public class MagicWebSocketInstance extends WebSocketListener {
|
||||||
private static final String TAG = "MagicWebSocketInstance";
|
private static final String TAG = "MagicWebSocketInstance";
|
||||||
|
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
OkHttpClient okHttpClient;
|
OkHttpClient okHttpClient;
|
||||||
|
|
||||||
@ -81,18 +83,17 @@ public class MagicWebSocketInstance extends WebSocketListener {
|
|||||||
@Inject
|
@Inject
|
||||||
Context context;
|
Context context;
|
||||||
|
|
||||||
private User conversationUser;
|
private final User conversationUser;
|
||||||
private String webSocketTicket;
|
private final String webSocketTicket;
|
||||||
private String resumeId;
|
private String resumeId;
|
||||||
private String sessionId;
|
private String sessionId;
|
||||||
private boolean hasMCU;
|
private boolean hasMCU;
|
||||||
private boolean connected;
|
private boolean connected;
|
||||||
private WebSocketConnectionHelper webSocketConnectionHelper;
|
private final WebSocketConnectionHelper webSocketConnectionHelper;
|
||||||
private WebSocket internalWebSocket;
|
private WebSocket internalWebSocket;
|
||||||
private String connectionUrl;
|
private final String connectionUrl;
|
||||||
|
|
||||||
private String currentRoomToken;
|
private String currentRoomToken;
|
||||||
private int restartCount = 0;
|
|
||||||
private boolean reconnecting = false;
|
private boolean reconnecting = false;
|
||||||
|
|
||||||
private HashMap<String, Participant> usersHashMap;
|
private HashMap<String, Participant> usersHashMap;
|
||||||
@ -121,9 +122,13 @@ public class MagicWebSocketInstance extends WebSocketListener {
|
|||||||
private void sendHello() {
|
private void sendHello() {
|
||||||
try {
|
try {
|
||||||
if (TextUtils.isEmpty(resumeId)) {
|
if (TextUtils.isEmpty(resumeId)) {
|
||||||
internalWebSocket.send(LoganSquare.serialize(webSocketConnectionHelper.getAssembledHelloModel(conversationUser, webSocketTicket)));
|
internalWebSocket.send(
|
||||||
|
LoganSquare.serialize(webSocketConnectionHelper
|
||||||
|
.getAssembledHelloModel(conversationUser, webSocketTicket)));
|
||||||
} else {
|
} else {
|
||||||
internalWebSocket.send(LoganSquare.serialize(webSocketConnectionHelper.getAssembledHelloModelForResume(resumeId)));
|
internalWebSocket.send(
|
||||||
|
LoganSquare.serialize(webSocketConnectionHelper
|
||||||
|
.getAssembledHelloModelForResume(resumeId)));
|
||||||
}
|
}
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
Log.e(TAG, "Failed to serialize hello model");
|
Log.e(TAG, "Failed to serialize hello model");
|
||||||
@ -152,142 +157,49 @@ public class MagicWebSocketInstance extends WebSocketListener {
|
|||||||
resumeId = "";
|
resumeId = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
public void restartWebSocket() {
|
public final void restartWebSocket() {
|
||||||
reconnecting = true;
|
reconnecting = true;
|
||||||
|
|
||||||
// TODO when improving logging, keep in mind this issue: https://github.com/nextcloud/talk-android/issues/1013
|
// TODO when improving logging, keep in mind this issue: https://github.com/nextcloud/talk-android/issues/1013
|
||||||
Log.d(TAG, "restartWebSocket: " + connectionUrl);
|
Log.d(TAG, "restartWebSocket: " + connectionUrl);
|
||||||
Request request = new Request.Builder().url(connectionUrl).build();
|
Request request = new Request.Builder().url(connectionUrl).build();
|
||||||
okHttpClient.newWebSocket(request, this);
|
okHttpClient.newWebSocket(request, this);
|
||||||
restartCount++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onMessage(WebSocket webSocket, String text) {
|
public void onMessage(@NonNull WebSocket webSocket, @NonNull String text) {
|
||||||
if (webSocket == internalWebSocket) {
|
if (webSocket == internalWebSocket) {
|
||||||
Log.d(TAG, "Receiving : " + webSocket.toString() + " " + text);
|
Log.d(TAG, "Receiving : " + webSocket + " " + text);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
BaseWebSocketMessage baseWebSocketMessage = LoganSquare.parse(text, BaseWebSocketMessage.class);
|
BaseWebSocketMessage baseWebSocketMessage = LoganSquare.parse(text, BaseWebSocketMessage.class);
|
||||||
String messageType = baseWebSocketMessage.getType();
|
String messageType = baseWebSocketMessage.getType();
|
||||||
switch (messageType) {
|
if (messageType != null) {
|
||||||
case "hello":
|
switch (messageType) {
|
||||||
connected = true;
|
case "hello":
|
||||||
reconnecting = false;
|
processHelloMessage(webSocket, text);
|
||||||
restartCount = 0;
|
break;
|
||||||
String oldResumeId = resumeId;
|
case "error":
|
||||||
HelloResponseOverallWebSocketMessage helloResponseWebSocketMessage = LoganSquare.parse(text, HelloResponseOverallWebSocketMessage.class);
|
processErrorMessage(webSocket, text);
|
||||||
resumeId = helloResponseWebSocketMessage.getHelloResponseWebSocketMessage().getResumeId();
|
break;
|
||||||
sessionId = helloResponseWebSocketMessage.getHelloResponseWebSocketMessage().getSessionId();
|
case "room":
|
||||||
hasMCU = helloResponseWebSocketMessage.getHelloResponseWebSocketMessage().serverHasMCUSupport();
|
processJoinedRoomMessage(text);
|
||||||
|
break;
|
||||||
for (int i = 0; i < messagesQueue.size(); i++) {
|
case "event":
|
||||||
webSocket.send(messagesQueue.get(i));
|
processEventMessage(text);
|
||||||
}
|
break;
|
||||||
|
case "message":
|
||||||
messagesQueue = new ArrayList<>();
|
processMessage(text);
|
||||||
HashMap<String, String> helloHasHap = new HashMap<>();
|
break;
|
||||||
if (!TextUtils.isEmpty(oldResumeId)) {
|
case "bye":
|
||||||
helloHasHap.put("oldResumeId", oldResumeId);
|
connected = false;
|
||||||
} 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");
|
|
||||||
resumeId = "";
|
resumeId = "";
|
||||||
currentRoomToken = "";
|
break;
|
||||||
restartWebSocket();
|
default:
|
||||||
} else if (("hello_expected").equals(errorOverallWebSocketMessage.getErrorWebSocketMessage().getCode())) {
|
break;
|
||||||
restartWebSocket();
|
}
|
||||||
}
|
} else {
|
||||||
|
Log.e(TAG, "Received message with type: null");
|
||||||
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<String, Object> messageHashMap =
|
|
||||||
(Map<String, Object>) eventOverallWebSocketMessage.getEventMap().get("message");
|
|
||||||
if (messageHashMap.containsKey("data")) {
|
|
||||||
Map<String, Object> dataHashMap = (Map<String, Object>) messageHashMap.get(
|
|
||||||
"data");
|
|
||||||
if (dataHashMap.containsKey("chat")) {
|
|
||||||
boolean shouldRefreshChat;
|
|
||||||
Map<String, Object> chatMap = (Map<String, Object>) dataHashMap.get("chat");
|
|
||||||
if (chatMap.containsKey("refresh")) {
|
|
||||||
shouldRefreshChat = (boolean) chatMap.get("refresh");
|
|
||||||
if (shouldRefreshChat) {
|
|
||||||
HashMap<String, String> 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<HashMap<String, Object>> joinEventList = (List<HashMap<String, Object>>) eventOverallWebSocketMessage.getEventMap().get("join");
|
|
||||||
HashMap<String, Object> internalHashMap;
|
|
||||||
Participant participant;
|
|
||||||
for (int i = 0; i < joinEventList.size(); i++) {
|
|
||||||
internalHashMap = joinEventList.get(i);
|
|
||||||
HashMap<String, Object> userMap = (HashMap<String, Object>) 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;
|
|
||||||
}
|
}
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
Log.e(TAG, "Failed to recognize WebSocket message", 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<String, Object> messageHashMap = (Map<String, Object>) eventOverallWebSocketMessage
|
||||||
|
.getEventMap()
|
||||||
|
.get("message");
|
||||||
|
if (messageHashMap != null && messageHashMap.containsKey("data")) {
|
||||||
|
Map<String, Object> dataHashMap = (Map<String, Object>) messageHashMap.get("data");
|
||||||
|
if (dataHashMap != null && dataHashMap.containsKey("chat")) {
|
||||||
|
Map<String, Object> chatMap = (Map<String, Object>) dataHashMap.get("chat");
|
||||||
|
if (chatMap != null && chatMap.containsKey("refresh") && (boolean) chatMap.get("refresh")) {
|
||||||
|
HashMap<String, String> 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<HashMap<String, Object>> joinEventList = (List<HashMap<String, Object>>) eventOverallWebSocketMessage
|
||||||
|
.getEventMap()
|
||||||
|
.get("join");
|
||||||
|
HashMap<String, Object> internalHashMap;
|
||||||
|
Participant participant;
|
||||||
|
for (int i = 0; i < joinEventList.size(); i++) {
|
||||||
|
internalHashMap = joinEventList.get(i);
|
||||||
|
HashMap<String, Object> userMap = (HashMap<String, Object>) 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<String, String> 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() {
|
private void sendRoomJoinedEvent() {
|
||||||
HashMap<String, String> joinRoomHashMap = new HashMap<>();
|
HashMap<String, String> joinRoomHashMap = new HashMap<>();
|
||||||
joinRoomHashMap.put(ROOM_TOKEN, currentRoomToken);
|
joinRoomHashMap.put(ROOM_TOKEN, currentRoomToken);
|
||||||
@ -302,12 +366,12 @@ public class MagicWebSocketInstance extends WebSocketListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onMessage(WebSocket webSocket, ByteString bytes) {
|
public void onMessage(@NonNull WebSocket webSocket, ByteString bytes) {
|
||||||
Log.d(TAG, "Receiving bytes : " + bytes.hex());
|
Log.d(TAG, "Receiving bytes : " + bytes.hex());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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);
|
Log.d(TAG, "Closing : " + code + " / " + reason);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -330,7 +394,8 @@ public class MagicWebSocketInstance extends WebSocketListener {
|
|||||||
Log.d(TAG, " roomToken: " + roomToken);
|
Log.d(TAG, " roomToken: " + roomToken);
|
||||||
Log.d(TAG, " session: " + normalBackendSession);
|
Log.d(TAG, " session: " + normalBackendSession);
|
||||||
try {
|
try {
|
||||||
String message = LoganSquare.serialize(webSocketConnectionHelper.getAssembledJoinOrLeaveRoomModel(roomToken, normalBackendSession));
|
String message = LoganSquare.serialize(
|
||||||
|
webSocketConnectionHelper.getAssembledJoinOrLeaveRoomModel(roomToken, normalBackendSession));
|
||||||
if (!connected || reconnecting) {
|
if (!connected || reconnecting) {
|
||||||
messagesQueue.add(message);
|
messagesQueue.add(message);
|
||||||
} else {
|
} else {
|
||||||
@ -347,7 +412,8 @@ public class MagicWebSocketInstance extends WebSocketListener {
|
|||||||
|
|
||||||
private void sendCallMessage(NCSignalingMessage ncSignalingMessage) {
|
private void sendCallMessage(NCSignalingMessage ncSignalingMessage) {
|
||||||
try {
|
try {
|
||||||
String message = LoganSquare.serialize(webSocketConnectionHelper.getAssembledCallMessageModel(ncSignalingMessage));
|
String message = LoganSquare.serialize(
|
||||||
|
webSocketConnectionHelper.getAssembledCallMessageModel(ncSignalingMessage));
|
||||||
if (!connected || reconnecting) {
|
if (!connected || reconnecting) {
|
||||||
messagesQueue.add(message);
|
messagesQueue.add(message);
|
||||||
} else {
|
} else {
|
||||||
@ -388,7 +454,8 @@ public class MagicWebSocketInstance extends WebSocketListener {
|
|||||||
|
|
||||||
@Subscribe(threadMode = ThreadMode.BACKGROUND)
|
@Subscribe(threadMode = ThreadMode.BACKGROUND)
|
||||||
public void onMessageEvent(NetworkEvent networkEvent) {
|
public void onMessageEvent(NetworkEvent networkEvent) {
|
||||||
if (networkEvent.getNetworkConnectionEvent() == NetworkEvent.NetworkConnectionEvent.NETWORK_CONNECTED && !isConnected()) {
|
if (networkEvent.getNetworkConnectionEvent() == NetworkEvent.NetworkConnectionEvent.NETWORK_CONNECTED &&
|
||||||
|
!isConnected()) {
|
||||||
restartWebSocket();
|
restartWebSocket();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -404,9 +471,9 @@ public class MagicWebSocketInstance extends WebSocketListener {
|
|||||||
/**
|
/**
|
||||||
* Temporary implementation of SignalingMessageReceiver until signaling related code is extracted to a Signaling
|
* Temporary implementation of SignalingMessageReceiver until signaling related code is extracted to a Signaling
|
||||||
* class.
|
* class.
|
||||||
*
|
* <p>
|
||||||
* All listeners are called in the WebSocket reader thread. This thread should be the same as long as the
|
* All listeners are called in the WebSocket reader thread. This thread should be the same as long as the WebSocket
|
||||||
* WebSocket stays connected, but it may change whenever it is connected again.
|
* stays connected, but it may change whenever it is connected again.
|
||||||
*/
|
*/
|
||||||
private static class ExternalSignalingMessageReceiver extends SignalingMessageReceiver {
|
private static class ExternalSignalingMessageReceiver extends SignalingMessageReceiver {
|
||||||
public void process(Map<String, Object> eventMap) {
|
public void process(Map<String, Object> eventMap) {
|
||||||
|
@ -171,7 +171,7 @@ public class PeerConnectionWrapper {
|
|||||||
dataChannel.registerObserver(new MagicDataChannelObserver());
|
dataChannel.registerObserver(new MagicDataChannelObserver());
|
||||||
if (isMCUPublisher) {
|
if (isMCUPublisher) {
|
||||||
peerConnection.createOffer(magicSdpObserver, mediaConstraints);
|
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
|
// If the connection type is "screen" the client sharing the screen will send an
|
||||||
// offer; offers should be requested only for videos.
|
// offer; offers should be requested only for videos.
|
||||||
// "to" property is not actually needed in the "requestoffer" signaling message, but it is used to
|
// "to" property is not actually needed in the "requestoffer" signaling message, but it is used to
|
||||||
@ -360,8 +360,9 @@ public class PeerConnectionWrapper {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onStateChange() {
|
public void onStateChange() {
|
||||||
if (dataChannel != null && dataChannel.state() == DataChannel.State.OPEN &&
|
if (dataChannel != null &&
|
||||||
dataChannel.label().equals("status")) {
|
dataChannel.state() == DataChannel.State.OPEN &&
|
||||||
|
"status".equals(dataChannel.label())) {
|
||||||
sendInitialMediaStatus();
|
sendInitialMediaStatus();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -493,7 +494,7 @@ public class PeerConnectionWrapper {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onDataChannel(DataChannel dataChannel) {
|
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 = dataChannel;
|
||||||
PeerConnectionWrapper.this.dataChannel.registerObserver(new MagicDataChannelObserver());
|
PeerConnectionWrapper.this.dataChannel.registerObserver(new MagicDataChannelObserver());
|
||||||
}
|
}
|
||||||
|
@ -399,7 +399,7 @@ public class WebRtcAudioManager {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void updateAudioDeviceState() {
|
public final void updateAudioDeviceState() {
|
||||||
ThreadUtils.checkIsOnMainThread();
|
ThreadUtils.checkIsOnMainThread();
|
||||||
Log.d(TAG, "--- updateAudioDeviceState: "
|
Log.d(TAG, "--- updateAudioDeviceState: "
|
||||||
+ "wired headset=" + hasWiredHeadset + ", "
|
+ "wired headset=" + hasWiredHeadset + ", "
|
||||||
|
@ -109,8 +109,6 @@ public class WebRtcBluetoothManager {
|
|||||||
return bluetoothState;
|
return bluetoothState;
|
||||||
}
|
}
|
||||||
|
|
||||||
;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Activates components required to detect Bluetooth devices and to enable
|
* Activates components required to detect Bluetooth devices and to enable
|
||||||
* BT SCO (audio is routed via BT SCO) for the headset profile. The end
|
* 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.
|
* Stubs for test mocks.
|
||||||
*/
|
*/
|
||||||
protected AudioManager getAudioManager(Context context) {
|
protected final AudioManager getAudioManager(Context context) {
|
||||||
return (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
|
return (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -502,8 +500,10 @@ public class WebRtcBluetoothManager {
|
|||||||
Log.d(TAG, "onServiceConnected done: BT state=" + bluetoothState);
|
Log.d(TAG, "onServiceConnected done: BT state=" + bluetoothState);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Notifies the client when the proxy object has been disconnected from the service.
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
/** Notifies the client when the proxy object has been disconnected from the service. */
|
|
||||||
public void onServiceDisconnected(int profile) {
|
public void onServiceDisconnected(int profile) {
|
||||||
if (profile != BluetoothProfile.HEADSET || bluetoothState == State.UNINITIALIZED) {
|
if (profile != BluetoothProfile.HEADSET || bluetoothState == State.UNINITIALIZED) {
|
||||||
return;
|
return;
|
||||||
@ -531,7 +531,7 @@ public class WebRtcBluetoothManager {
|
|||||||
// change does not tell us anything about whether we're streaming
|
// change does not tell us anything about whether we're streaming
|
||||||
// audio to BT over SCO. Typically received when user turns on a BT
|
// audio to BT over SCO. Typically received when user turns on a BT
|
||||||
// headset while audio is active using another audio device.
|
// 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 =
|
final int state =
|
||||||
intent.getIntExtra(BluetoothHeadset.EXTRA_STATE, BluetoothHeadset.STATE_DISCONNECTED);
|
intent.getIntExtra(BluetoothHeadset.EXTRA_STATE, BluetoothHeadset.STATE_DISCONNECTED);
|
||||||
Log.d(TAG, "BluetoothHeadsetBroadcastReceiver.onReceive: "
|
Log.d(TAG, "BluetoothHeadsetBroadcastReceiver.onReceive: "
|
||||||
@ -543,8 +543,10 @@ public class WebRtcBluetoothManager {
|
|||||||
scoConnectionAttempts = 0;
|
scoConnectionAttempts = 0;
|
||||||
updateAudioDeviceState();
|
updateAudioDeviceState();
|
||||||
} else if (state == BluetoothHeadset.STATE_CONNECTING) {
|
} else if (state == BluetoothHeadset.STATE_CONNECTING) {
|
||||||
|
Log.d(TAG, "+++ Bluetooth is connecting...");
|
||||||
// No action needed.
|
// No action needed.
|
||||||
} else if (state == BluetoothHeadset.STATE_DISCONNECTING) {
|
} else if (state == BluetoothHeadset.STATE_DISCONNECTING) {
|
||||||
|
Log.d(TAG, "+++ Bluetooth is disconnecting...");
|
||||||
// No action needed.
|
// No action needed.
|
||||||
} else if (state == BluetoothHeadset.STATE_DISCONNECTED) {
|
} else if (state == BluetoothHeadset.STATE_DISCONNECTED) {
|
||||||
// Bluetooth is probably powered off during the call.
|
// 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.
|
// Change in the audio (SCO) connection state of the Headset profile.
|
||||||
// Typically received after call to startScoAudio() has finalized.
|
// 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(
|
final int state = intent.getIntExtra(
|
||||||
BluetoothHeadset.EXTRA_STATE, BluetoothHeadset.STATE_AUDIO_DISCONNECTED);
|
BluetoothHeadset.EXTRA_STATE, BluetoothHeadset.STATE_AUDIO_DISCONNECTED);
|
||||||
Log.d(TAG, "BluetoothHeadsetBroadcastReceiver.onReceive: "
|
Log.d(TAG, "BluetoothHeadsetBroadcastReceiver.onReceive: "
|
||||||
|
@ -60,11 +60,13 @@ public class WebSocketConnectionHelper {
|
|||||||
|
|
||||||
@SuppressLint("LongLogTag")
|
@SuppressLint("LongLogTag")
|
||||||
public static synchronized MagicWebSocketInstance getMagicWebSocketInstanceForUserId(long userId) {
|
public static synchronized MagicWebSocketInstance getMagicWebSocketInstanceForUserId(long userId) {
|
||||||
if (userId != -1 && magicWebSocketInstanceMap.containsKey(userId)) {
|
MagicWebSocketInstance webSocketInstance = magicWebSocketInstanceMap.get(userId);
|
||||||
return 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,
|
public static synchronized MagicWebSocketInstance getExternalSignalingInstanceForServer(String url,
|
||||||
|
Loading…
Reference in New Issue
Block a user