W/System.err: java.lang.NullPointerException
W/System.err: at com.nextcloud.talk.controllers.ChatController.determinePreviousMessageIds(ChatController.kt:2498)
W/System.err: at com.nextcloud.talk.controllers.ChatController.processMessagesNotFromTheFuture(ChatController.kt:2463)
W/System.err: at com.nextcloud.talk.controllers.ChatController.processMessages(ChatController.kt:2355)
W/System.err: at com.nextcloud.talk.controllers.ChatController.processMessagesResponse(ChatController.kt:2314)
W/System.err: at com.nextcloud.talk.controllers.ChatController.access$processMessagesResponse(ChatController.kt:219)
W/System.err: at com.nextcloud.talk.controllers.ChatController$pullChatMessages$3.onNext(ChatController.kt:2260)
W/System.err: at com.nextcloud.talk.controllers.ChatController$pullChatMessages$3.onNext(ChatController.kt:2248)
W/System.err: at io.reactivex.internal.operators.observable.ObservableObserveOn$ObserveOnObserver.drainNormal(ObservableObserveOn.java:201)
W/System.err: at io.reactivex.internal.operators.observable.ObservableObserveOn$ObserveOnObserver.run(ObservableObserveOn.java:255)
W/System.err: at io.reactivex.android.schedulers.HandlerScheduler$ScheduledRunnable.run(HandlerScheduler.java:124)
W/System.err: at android.os.Handler.handleCallback(Handler.java:883)
W/System.err: at android.os.Handler.dispatchMessage(Handler.java:100)
W/System.err: at android.os.Looper.loop(Looper.java:224)
W/System.err: at android.app.ActivityThread.main(ActivityThread.java:7590)
W/System.err: at java.lang.reflect.Method.invoke(Native Method)
W/System.err: at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:539)
W/System.err: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:950)
Signed-off-by: Marcel Hibbe <dev@mhibbe.de>
instead popToRoot, which should be the ConversationsListController for most cases.
Exception java.lang.IllegalArgumentException: fromIndex(0) > toIndex(-1)
at java.util.ArrayList.subListRangeCheck (ArrayList.java:1018)
at java.util.ArrayList.subList (ArrayList.java:1008)
at com.nextcloud.talk.controllers.ConversationInfoController.popTwoLastControllers (ConversationInfoController.kt:628)
at com.nextcloud.talk.controllers.ConversationInfoController.leaveConversation (ConversationInfoController.kt:552)
at com.nextcloud.talk.controllers.ConversationInfoController.onAttach$lambda$1 (ConversationInfoController.kt:181)
at com.nextcloud.talk.controllers.ConversationInfoController.$r8$lambda$VRoZoNH5wtuepilLynILWSZOZYA
at com.nextcloud.talk.controllers.ConversationInfoController$$ExternalSyntheticLambda8.onClick
at com.yarolegovich.mp.util.CompositeClickListener.onClick (CompositeClickListener.java:22)
at android.view.View.performClick (View.java:7455)
at android.view.View.performClickInternal (View.java:7428)
at android.view.View.access$3600 (View.java:813)
at android.view.View$PerformClick.run (View.java:28495)
at android.os.Handler.handleCallback (Handler.java:938)
at android.os.Handler.dispatchMessage (Handler.java:99)
at android.os.Looper.loop (Looper.java:223)
at android.app.ActivityThread.main (ActivityThread.java:7700)
at java.lang.reflect.Method.invoke
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run (RuntimeInit.java:612)
at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:997)
Signed-off-by: Marcel Hibbe <dev@mhibbe.de>
this commit tries to avoid the IllegalStateException in stacktrace below.
I'm not sure how this happened. It came from LockedController#unlock (--> binding?.unlockContainer?.setOnClickListener) which should only be visible when somehow it's "failed" to show the keyguard lockscreen. And somehow for this case the router backstack must have been empty.
Instead to dismiss the current controller, popToRoot() should avoid trying to pop the last remaining controller.
Exception java.lang.IllegalStateException: Trying to pop the current controller when there are none on the backstack.
at com.bluelinelabs.conductor.Router.popCurrentController (Router.java:118)
at com.nextcloud.talk.controllers.LockedController.checkIfWeAreSecure (LockedController.kt:147)
at com.nextcloud.talk.controllers.LockedController.unlock (LockedController.kt:90)
at com.nextcloud.talk.controllers.LockedController.onViewBound$lambda$0 (LockedController.kt:64)
at com.nextcloud.talk.controllers.LockedController.$r8$lambda$sNoJ_x5yMnHnIHeqt2umoDILkpk
at com.nextcloud.talk.controllers.LockedController$$ExternalSyntheticLambda0.onClick
at android.view.View.performClick (View.java:7745)
at android.view.View.performClickInternal (View.java:7722)
at android.view.View.access$3700 (View.java:854)
at android.view.View$PerformClick.run (View.java:29111)
at android.os.Handler.handleCallback (Handler.java:938)
at android.os.Handler.dispatchMessage (Handler.java:99)
at android.os.Looper.loopOnce (Looper.java:210)
at android.os.Looper.loop (Looper.java:299)
at android.app.ActivityThread.main (ActivityThread.java:8319)
at java.lang.reflect.Method.invoke
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run (RuntimeInit.java:556)
at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:1038)
Signed-off-by: Marcel Hibbe <dev@mhibbe.de>
Exception java.lang.NullPointerException:
at com.nextcloud.talk.controllers.ChatController$onViewBound$11.onTouch (ChatController.kt:858)
at android.view.View.dispatchTouchEvent (View.java:15072)
at android.view.ViewGroup.dispatchTransformedTouchEvent (ViewGroup.java:3923)
at android.view.ViewGroup.dispatchTouchEvent (ViewGroup.java:3597)
at android.view.ViewGroup.dispatchTransformedTouchEvent (ViewGroup.java:3923)
at android.view.ViewGroup.dispatchTouchEvent (ViewGroup.java:3597)
at android.view.ViewGroup.dispatchTransformedTouchEvent (ViewGroup.java:3923)
at android.view.ViewGroup.dispatchTouchEvent (ViewGroup.java:3597)
at android.view.ViewGroup.dispatchTransformedTouchEvent (ViewGroup.java:3923)
at android.view.ViewGroup.dispatchTouchEvent (ViewGroup.java:3597)
at android.view.ViewGroup.dispatchTransformedTouchEvent (ViewGroup.java:3923)
at android.view.ViewGroup.dispatchTouchEvent (ViewGroup.java:3597)
at android.view.ViewGroup.dispatchTransformedTouchEvent (ViewGroup.java:3923)
at android.view.ViewGroup.dispatchTouchEvent (ViewGroup.java:3597)
at android.view.ViewGroup.dispatchTransformedTouchEvent (ViewGroup.java:3923)
at android.view.ViewGroup.dispatchTouchEvent (ViewGroup.java:3597)
at android.view.ViewGroup.dispatchTransformedTouchEvent (ViewGroup.java:3923)
at android.view.ViewGroup.dispatchTouchEvent (ViewGroup.java:3597)
at android.view.ViewGroup.dispatchTransformedTouchEvent (ViewGroup.java:3923)
at android.view.ViewGroup.dispatchTouchEvent (ViewGroup.java:3597)
at android.view.ViewGroup.dispatchTransformedTouchEvent (ViewGroup.java:3923)
at android.view.ViewGroup.dispatchTouchEvent (ViewGroup.java:3597)
at android.view.ViewGroup.dispatchTransformedTouchEvent (ViewGroup.java:3923)
at android.view.ViewGroup.dispatchTouchEvent (ViewGroup.java:3597)
at com.android.internal.policy.DecorView.superDispatchTouchEvent (DecorView.java:1016)
at com.android.internal.policy.PhoneWindow.superDispatchTouchEvent (PhoneWindow.java:1962)
at android.app.Activity.dispatchTouchEvent (Activity.java:4265)
at androidx.appcompat.view.WindowCallbackWrapper.dispatchTouchEvent (WindowCallbackWrapper.java:70)
at com.android.internal.policy.DecorView.dispatchTouchEvent (DecorView.java:974)
at android.view.View.dispatchPointerEvent (View.java:15335)
at android.view.ViewRootImpl$ViewPostImeInputStage.processPointerEvent (ViewRootImpl.java:7820)
at android.view.ViewRootImpl$ViewPostImeInputStage.onProcess (ViewRootImpl.java:7593)
at android.view.ViewRootImpl$InputStage.deliver (ViewRootImpl.java:6927)
at android.view.ViewRootImpl$InputStage.onDeliverToNext (ViewRootImpl.java:6984)
at android.view.ViewRootImpl$InputStage.forward (ViewRootImpl.java:6950)
at android.view.ViewRootImpl$AsyncInputStage.forward (ViewRootImpl.java:7148)
at android.view.ViewRootImpl$InputStage.apply (ViewRootImpl.java:6958)
at android.view.ViewRootImpl$AsyncInputStage.apply (ViewRootImpl.java:7205)
at android.view.ViewRootImpl$InputStage.deliver (ViewRootImpl.java:6931)
at android.view.ViewRootImpl$InputStage.onDeliverToNext (ViewRootImpl.java:6984)
at android.view.ViewRootImpl$InputStage.forward (ViewRootImpl.java:6950)
at android.view.ViewRootImpl$InputStage.apply (ViewRootImpl.java:6958)
at android.view.ViewRootImpl$InputStage.deliver (ViewRootImpl.java:6931)
at android.view.ViewRootImpl.deliverInputEvent (ViewRootImpl.java:10422)
at android.view.ViewRootImpl.doProcessInputEvents (ViewRootImpl.java:10270)
at android.view.ViewRootImpl.enqueueInputEvent (ViewRootImpl.java:10226)
at android.view.ViewRootImpl$WindowInputEventReceiver.onInputEvent (ViewRootImpl.java:10554)
at android.view.InputEventReceiver.dispatchInputEvent (InputEventReceiver.java:259)
at android.os.MessageQueue.nativePollOnce
at android.os.MessageQueue.next (MessageQueue.java:335)
at android.os.Looper.loopOnce (Looper.java:186)
at android.os.Looper.loop (Looper.java:313)
at android.app.ActivityThread.main (ActivityThread.java:8751)
at java.lang.reflect.Method.invoke
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run (RuntimeInit.java:571)
at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:1135)
Signed-off-by: Marcel Hibbe <dev@mhibbe.de>
Exception java.lang.RuntimeException:
at android.app.ActivityThread.performDestroyActivity (ActivityThread.java:6032)
at android.app.ActivityThread.handleDestroyActivity (ActivityThread.java:6077)
at android.app.servertransaction.DestroyActivityItem.execute (DestroyActivityItem.java:47)
at android.app.servertransaction.ActivityTransactionItem.execute (ActivityTransactionItem.java:45)
at android.app.servertransaction.TransactionExecutor.executeLifecycleState (TransactionExecutor.java:176)
at android.app.servertransaction.TransactionExecutor.execute (TransactionExecutor.java:97)
at android.app.ActivityThread$H.handleMessage (ActivityThread.java:2443)
at android.os.Handler.dispatchMessage (Handler.java:106)
at android.os.Looper.loopOnce (Looper.java:226)
at android.os.Looper.loop (Looper.java:313)
at android.app.ActivityThread.main (ActivityThread.java:8751)
at java.lang.reflect.Method.invoke
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run (RuntimeInit.java:571)
at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:1135)
Caused by java.lang.NullPointerException:
at com.nextcloud.talk.activities.CallActivity.onDestroy (CallActivity.java:1244)
at android.app.Activity.performDestroy (Activity.java:8571)
at android.app.Instrumentation.callActivityOnDestroy (Instrumentation.java:1364)
at android.app.ActivityThread.performDestroyActivity (ActivityThread.java:6019)
Signed-off-by: Marcel Hibbe <dev@mhibbe.de>
Note the slight difference in naming between the signaling message
("raiseHand", the action) and the stored data ("RaisedHand", the record
of the action).
Signed-off-by: Daniel Calviño Sánchez <danxuliu@gmail.com>
with this fix it's also not necessary to check for HPB in the app. The "recording" value from capabilities is set accordingly on server side.
Signed-off-by: Marcel Hibbe <dev@mhibbe.de>
RecordingStartedState is set when the signaling message is received. There is no need to set this by CallStartRecordingObserver. Otherwise the toast "The call is being recorded" would have been shown twice when starting the recording.
Signed-off-by: Marcel Hibbe <dev@mhibbe.de>
first it was tried with sampling rate 44100 but this showed an error on safari when try to playback.
by direct comparison to 44100, 22050 has lower quality but it's totally okay compared to the quality before when no sampling rate was set. I'm not sure why it failed on safari, because the iOS app also uses 44100.
see https://github.com/nextcloud/talk-android/pull/2714
Signed-off-by: Marcel Hibbe <dev@mhibbe.de>
this could happen very rarely when clicking very fast to accept the call before the conversation was set.
Exception java.lang.NullPointerException:
at com.nextcloud.talk.activities.CallNotificationActivity.proceedToCall (CallNotificationActivity.kt:156)
at com.nextcloud.talk.activities.CallNotificationActivity.initClickListeners$lambda$0 (CallNotificationActivity.kt:126)
at com.nextcloud.talk.activities.CallNotificationActivity.$r8$lambda$0cnB_UmYcTD4PyxIBSZCZs1m_6s
at com.nextcloud.talk.activities.CallNotificationActivity$$ExternalSyntheticLambda0.onClick
at android.view.View.performClick (View.java:6612)
at android.view.View.performClickInternal (View.java:6581)
at android.view.View.access$3100 (View.java:785)
at android.view.View$PerformClick.run (View.java:25904)
at android.os.Handler.handleCallback (Handler.java:873)
at android.os.Handler.dispatchMessage (Handler.java:99)
at android.os.Looper.loop (Looper.java:280)
at android.app.ActivityThread.main (ActivityThread.java:6706)
at java.lang.reflect.Method.invoke
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run (RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:858)
Signed-off-by: Marcel Hibbe <dev@mhibbe.de>
Exception java.lang.NullPointerException:
at com.nextcloud.talk.activities.CallActivity.hangupNetworkCalls (CallActivity.java:1749)
at com.nextcloud.talk.activities.CallActivity.hangup (CallActivity.java:1741)
at com.nextcloud.talk.activities.CallActivity.lambda$initClickListeners$8$com-nextcloud-talk-activities-CallActivity (CallActivity.java:465)
at com.nextcloud.talk.activities.CallActivity$$ExternalSyntheticLambda16.onClick
at android.view.View.performClick (View.java:7792)
at android.view.View.performClickInternal (View.java:7769)
at android.view.View.access$3800 (View.java:910)
at android.view.View$PerformClick.run (View.java:30218)
at android.os.Handler.handleCallback (Handler.java:938)
at android.os.Handler.dispatchMessage (Handler.java:99)
at android.os.Looper.loopOnce (Looper.java:226)
at android.os.Looper.loop (Looper.java:313)
at android.app.ActivityThread.main (ActivityThread.java:8751)
at java.lang.reflect.Method.invoke
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run (RuntimeInit.java:571)
at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:1135)
Signed-off-by: Marcel Hibbe <dev@mhibbe.de>
When the HPB is not used and a PeerConnectionWrapper is created it
always sent an offer if the local session ID is higher than the remote
session ID. However, in the case of screen shares the participant
sharing the screen always sends an offer, no matter the session ID.
Therefore, when that offer was received the new PeerConnectionWrapper
object sent a new offer, which in turn created an extra connection in
the browser.
Although the screen share connection happens to work the underlying
behaviour was wrong, so now no offer is sent for received screen share
connections and it is always waited until the offer is sent by the other
participant.
Signed-off-by: Daniel Calviño Sánchez <danxuliu@gmail.com>
logic for setting the placeholder was moved to getPayloadForImageLoader.
This is a better solution than in commit
9557bec9 where the onBind method had to be called in between other code.
This is still not the best solution because getPayloadForImageLoader now contains more logic than it should (which is also not only responsible for the placeholder). Anyway as this is a hotfix it's the best solution for the moment.
Signed-off-by: Marcel Hibbe <dev@mhibbe.de>
follow up to commit 7464e6994b673d2b575903a76752bf39bed9d622
the problem was that the "super" methods also contain logic to show/hide the avatar. So this result must be overwritten again after calling the super method.
Signed-off-by: Marcel Hibbe <dev@mhibbe.de>
without this fix, "getPayloadForImageLoader" was called before the placeholder was set (so it was null until getPayloadForImageLoader was called again after ~30seconds.). This is fixed by calling the super method at the end of "onBind".
min height was set to avoid very tiny previews (like for the placeholders)
Signed-off-by: Marcel Hibbe <dev@mhibbe.de>
since null checks are done for the nullable bindings by PR #2694, the try-catch blocks arent necessary anymore.
Signed-off-by: Marcel Hibbe <dev@mhibbe.de>
it seems async calls are not cancelled reliable so it was decided to always check for null bindings to avoid NPEs
Signed-off-by: Marcel Hibbe <dev@mhibbe.de>
The peer connections will be of either "video" or "screen" type, so they
can be simply removed based on the session id and an explicit type.
Signed-off-by: Daniel Calviño Sánchez <danxuliu@gmail.com>
Instead of trying to create a video peer connection for any joined
participant now only a call participant is created for any joined
participant, and a video peer connection is created only for those
participants that are publishing audio or video.
If a call participants does not have a video peer connection the call
participant is now seen as "connected" from the UI, as there is no need
to show a progress bar for that participant.
Signed-off-by: Daniel Calviño Sánchez <danxuliu@gmail.com>
As CallParticipantList starts listening on the signaling messages as
soon as it is created it needs to be created and destroyed right before
entering and exiting a call. Otherwise it could receive messages on
other states (for example, while the "connection timeout" message is
shown) and thus once the local participant joined the event would not
include the other participants already in the call as joined (although
they would be anyway reported as unchanged).
Signed-off-by: Daniel Calviño Sánchez <danxuliu@gmail.com>
For now only the same signaling messages that were already handled are
still handled; in the future it could be extended to handle other
messages, like the one sent by the external signaling server when a
participant leaves the room (in some cases no participants update
message is sent if the participant leaves the call and room at the same
time, which causes the participants to still be seen as in call until a
new update is received).
Signed-off-by: Daniel Calviño Sánchez <danxuliu@gmail.com>
The observers were created for any peer connection, but after recent
changes they ignored all changes but those from the self peer
connection. Therefore it is enough to just add an explicit listener on
that peer connection rather than on all of them.
Signed-off-by: Daniel Calviño Sánchez <danxuliu@gmail.com>
The connection state changes to "closed" only when the connection is
closed. However, closing a connection does not fire any event (not even
the "iceConnectionStateChanged" event), so the event handler can be
removed as it will never be executed.
Signed-off-by: Daniel Calviño Sánchez <danxuliu@gmail.com>
The ParticipantDisplayItems were created and destroyed based on the peer
connections. Now a ParticipantDisplayItem of "video" type is associated
to a call participant, while an additional item is created and destroyed
depending on the state of the screen peer connection of the call
participant.
Signed-off-by: Daniel Calviño Sánchez <danxuliu@gmail.com>
The listeners for call participant messages and for the call participant
nick provided by offers / answers were created and destroyed based on
the peer connections, although they were implicitly associated to a call
participant. Now they are explicitly created and destroyed based on its
associated call participant.
Signed-off-by: Daniel Calviño Sánchez <danxuliu@gmail.com>
CallParticipant provides a read-only CallParticipantModel and internally
handles the data channel and peer connection events that modify the
model. Nevertheless, the CallParticipant requires certain properties to
be externally set, like the userId or the peer connections.
Signed-off-by: Daniel Calviño Sánchez <danxuliu@gmail.com>
Instead of explicitly setting the values on the ParticipantDisplayItems
now the values are set on the CallParticipantModels, and the items are
automatically updated from their model when they change.
Different items are still used for the audio/video and screen shares of
the same participant, so the type is used to select from which
properties of the model is the item updated.
As the model may be updated from background threads it is explicitly
observed by the items from the main thread using a Handler shared by all
the items.
Signed-off-by: Daniel Calviño Sánchez <danxuliu@gmail.com>
Clients that modify the model would define the variables using the
mutable subclass, while clients that only need to access the model are
expected to use the read-only base class.
The read-only class provides an observer; as it is expected that the
model will be modified from background threads but observed from the
main thread the observer can be registered along a handler to be
notified on its thread, independently of on which thread the values were
set.
Currently there does not seem to be a need to observe each value on its
own, so the observer is notified in a coarse way when any value changes.
Signed-off-by: Daniel Calviño Sánchez <danxuliu@gmail.com>
Instead of explicitly calling "notifyDataSetChanged" after setting
values on a ParticipantDisplayItem now the adapter observes all its
items and calls "notifyDataSetChanged" automatically when any of them
changes.
Although this adds some boilerplate code it will make possible to update
the ParticipantDisplayItems and automatically propagate the changes to
the adapter when a model changes, rather than having to explicitly do it
from the CallActivity.
Signed-off-by: Daniel Calviño Sánchez <danxuliu@gmail.com>
Generic final attributes first, followed by object specific final
attributes and then other object attributes.
Signed-off-by: Daniel Calviño Sánchez <danxuliu@gmail.com>
Note that the session ID, user ID and the stream type attributes are
still kept, as they can be useful to identify the instance when
debugging.
Signed-off-by: Daniel Calviño Sánchez <danxuliu@gmail.com>
Rather than just providing a coarse "connected" or "not connected" value
now the views receive the raw ICE connection state. Combined with other
properties this will make possible to show a finer grained status (like
done in the WebUI), although for now just "connected" or "not connected"
is still shown as before.
Signed-off-by: Daniel Calviño Sánchez <danxuliu@gmail.com>