gunschu / jitsi_meet

Initial commit
208 stars 282 forks source link

Picture in Picture(PiP) mode if i open app create new instance #120

Closed imrushi closed 4 years ago

imrushi commented 4 years ago

I have created the meeting app in flutter using the jitsi_meet flutter package in that first I get the inputs from users like room name, display name, etc. After clicking on the button meeting get started when I press the home button it meeting go to PiP mode (Picture in Picture mode). When I am in pip mode I click on my flutter app it creates a new instance of the app and does not continue the meeting or go back to the meeting and the meeting is still running in pip mode. If I click on the pip screen it goes to the meeting but clicking on the app creates a new instance. @tuantvu @Snapworks

jimmyjose-dev commented 4 years ago

I am not sure what you mean... could you share some screenshot to give a better perspective ..

imrushi commented 4 years ago

pip prob

@Snapworks Here is a gif What I want is that when I am in pip mode and click on my app it should take me back to the meeting ( Fullscreen of Pip meet).

jimmyjose-dev commented 4 years ago

Thanks for sharing the GIF, it makes more sense now.

As far as i can see PIP is working fine, what you want to achieve is something that you would have to handle on your own... See my comment and code on PIP callback and you can code your way through there... -> #76

Even without the callback you can you can handle it via keeping a track if the meeting is currently active.. maybe shared preference or something and code based on that condition.

imrushi commented 4 years ago

@Snapworks I have tried the #76 also add listeners still it is not working. I have to add and extra logic or what? (give me an example).

Even without the callback you can handle it via keeping a track if the meeting is currently active... maybe shared preference or something and code based on that condition.

I have added a shared preference and set a boolean but how should I redirect to a meeting on click of an app. If you give an example it will be easy to understand.

ducnmhn commented 4 years ago

Hi @tuantvu @Snapworks

Can we make jitsi_meet run on top of app like PiP ? jitsi_meet flutter can be run not full screen?

Like this video https://www.youtube.com/watch?v=8drCJKa0sGw or https://www.youtube.com/watch?v=dTpZ1BtNy4w

Dose jitsi sdk support that ?

On web, I can use z-index to make iframe jitsi on top of screen

imrushi commented 4 years ago

@Snapworks Which function should I call in a dart to redirect to ongoing meeting screen? And please reply this also

@Snapworks I have tried the #76 also add listeners still it is not working. I have to add and extra logic or what? (give me an example).

Even without the callback you can handle it via keeping a track if the meeting is currently active... maybe shared preference or something and code based on that condition.

I have added a shared preference and set a boolean but how should I redirect to a meeting on click of an app. If you give an example it will be easy to understand.

jimmyjose-dev commented 4 years ago

Hi @tuantvu @Snapworks

Can we make jitsi_meet run on top of app like PiP ? jitsi_meet flutter can be run not full screen?

Like this video https://www.youtube.com/watch?v=8drCJKa0sGw or https://www.youtube.com/watch?v=dTpZ1BtNy4w

Dose jitsi sdk support that ?

On web, I can use z-index to make iframe jitsi on top of screen

@ducnmhn PIP is already supported. You can activate it by Tapping on the dropdown arrow that appear on top left in the jitsimeet viewcontroller... you can see the transition in the GIF shared by @imrushi in the post above you.

jimmyjose-dev commented 4 years ago

@Snapworks Which function should I call in a dart to redirect to ongoing meeting screen? And please reply this also

@Snapworks I have tried the #76 also add listeners still it is not working. I have to add and extra logic or what? (give me an example).

Even without the callback you can handle it via keeping a track if the meeting is currently active... maybe shared preference or something and code based on that condition.

I have added a shared preference and set a boolean but how should I redirect to a meeting on click of an app. If you give an example it will be easy to understand.

@imrushi Can you share what you have tried..

Adding callback will only help in identifying the state changes between PIP in and out.. and alternate way was shared preference if you just want to detect if meeting is active. It wont resize the app frame. You would have to either exit the pip mode or resize the app bounds.

You need to add code to call one of these function programmatically (part of PiPViewCoordinator class)

If interested in callback state of PIP (callback will work only with my code as suggested in #76 )

@objc public func exitPictureInPicture() {
        isInPiP = false
        animateViewChange()
        dragController.stopDragListener()

        // hide PiP UI
        exitPiPButton?.removeFromSuperview()
        exitPiPButton = nil

        // remove gesture
        let exitSelector = #selector(toggleExitPiP)
        tapGestureRecognizer?.removeTarget(self, action: exitSelector)
        tapGestureRecognizer = nil

        delegate?.exitPictureInPicture()
    }

This will take a fixed frame and exit PIP

public func resetBounds(bounds: CGRect) {
        currentBounds = bounds
        exitPictureInPicture()
    }
ducnmhn commented 4 years ago

Hi @tuantvu @Snapworks Can we make jitsi_meet run on top of app like PiP ? jitsi_meet flutter can be run not full screen? Like this video https://www.youtube.com/watch?v=8drCJKa0sGw or https://www.youtube.com/watch?v=dTpZ1BtNy4w Dose jitsi sdk support that ? On web, I can use z-index to make iframe jitsi on top of screen

@ducnmhn PIP is already supported. You can activate it by Tapping on the dropdown arrow that appear on top left in the jitsimeet viewcontroller... you can see the transition in the GIF shared by @imrushi in the post above you.

Thank for your rep @Snapworks But in GIF shared by @imrushi , background went use PIP is screen of phone. Can be screen of app like my video ?

jimmyjose-dev commented 4 years ago

Hi @tuantvu @Snapworks Can we make jitsi_meet run on top of app like PiP ? jitsi_meet flutter can be run not full screen? Like this video https://www.youtube.com/watch?v=8drCJKa0sGw or https://www.youtube.com/watch?v=dTpZ1BtNy4w Dose jitsi sdk support that ? On web, I can use z-index to make iframe jitsi on top of screen

@ducnmhn PIP is already supported. You can activate it by Tapping on the dropdown arrow that appear on top left in the jitsimeet viewcontroller... you can see the transition in the GIF shared by @imrushi in the post above you.

Thank for your rep @Snapworks But in GIF shared by @imrushi , background went use PIP is screen of phone. Can be screen of app like my video ?

Yes.

imrushi commented 4 years ago

@Snapworks As you have said in #76 I have added the same code is there something extra also I have to add because that callback is not working I did exactly the same steps you have shown in #76.

And using shared preferences I have set the boolean flag when the meeting is started its set to true when it goes to pip mode and click on an app I check the app state if the app state is a resume in that I check boolean value. It working fine but I don't know the code to go redirect to the meeting screen or full screen (exit pip & go back to meeting full screen).

And where do I add the above code you have mentioned

imrushi commented 4 years ago

@Snapworks Here is the code

On the meeting join button click code

RaisedButton(
                    onPressed: () {
                      setState(() {
                        saveBoolPreference(true);
                      });
                      _joinMeeting();
                    },
                    child: Text(
                      "Join Meeting",
                      style: TextStyle(color: Colors.white),
                    ),
                    color: Colors.blue,
                  ),

_onConferenceTerminated() in main.dart

void _onConferenceTerminated({message}) {
    debugPrint("_onConferenceTerminated broadcasted with message: $message");
    saveBoolPreference(false);
  }

here are all the listeners

JitsiMeet.addListener(JitsiMeetingListener(
        onConferenceWillJoin: _onConferenceWillJoin,
        onConferenceJoined: _onConferenceJoined,
        onConferenceTerminated: _onConferenceTerminated,
        onPictureInPictureWillEnter: _onPictureInPictureWillEnter,
        onPictureInPictureTerminated: _onPictureInPictureTerminated,
        onError: _onError));

In the LifeCycleManager,dart

bool val;
  Future<SharedPreferences> _prefs = SharedPreferences.getInstance();
  @override
  void didChangeAppLifecycleState(AppLifecycleState state) {
    super.didChangeAppLifecycleState(state);
    print('LifeCycleState= $state');
    if (state == AppLifecycleState.paused) {
      // SystemNavigator.pop();
    }
    if (state == AppLifecycleState.resumed) {
      // send to full screen of meeting
      getShareprefVal();
    }
  }

  getShareprefVal() async {
    bool stateVal = await getBoolPreference();
    setState(() {
      val = stateVal;
      print('SharedPref from lifecycle: $val');
    });
    if (val) {
      //redirect to full screen or meeting
      print('meeting is already going on.');
    }
  }

  Future<bool> getBoolPreference() async {
    SharedPreferences prefs = await _prefs;
    bool op = prefs.getBool('checkmeet');
    return op;
  }

Here is the in LifeCycleManager.dart file where it says the meeting is already going on here I want to redirect or exit pip and take him back to meet. I hope now you can easily understand.

congthang1 commented 4 years ago

Yes when I tap to the arrow at the top of meeting it minimize the window of meeting but the background is black on IOS and Android it is showing the home screen instead of the main app. What I would like to be here is somehow we have the minimize of meeting and we can hav a way to fill out the remain screen with our main app parts, so they can use other functions of the main app normally ;)

jimmyjose-dev commented 4 years ago

@Snapworks Here is the code

On the meeting join button click code

RaisedButton(
                    onPressed: () {
                      setState(() {
                        saveBoolPreference(true);
                      });
                      _joinMeeting();
                    },
                    child: Text(
                      "Join Meeting",
                      style: TextStyle(color: Colors.white),
                    ),
                    color: Colors.blue,
                  ),

_onConferenceTerminated() in main.dart

void _onConferenceTerminated({message}) {
    debugPrint("_onConferenceTerminated broadcasted with message: $message");
    saveBoolPreference(false);
  }

here are all the listeners

JitsiMeet.addListener(JitsiMeetingListener(
        onConferenceWillJoin: _onConferenceWillJoin,
        onConferenceJoined: _onConferenceJoined,
        onConferenceTerminated: _onConferenceTerminated,
        onPictureInPictureWillEnter: _onPictureInPictureWillEnter,
        onPictureInPictureTerminated: _onPictureInPictureTerminated,
        onError: _onError));

In the LifeCycleManager,dart

bool val;
  Future<SharedPreferences> _prefs = SharedPreferences.getInstance();
  @override
  void didChangeAppLifecycleState(AppLifecycleState state) {
    super.didChangeAppLifecycleState(state);
    print('LifeCycleState= $state');
    if (state == AppLifecycleState.paused) {
      // SystemNavigator.pop();
    }
    if (state == AppLifecycleState.resumed) {
      // send to full screen of meeting
      getShareprefVal();
    }
  }

  getShareprefVal() async {
    bool stateVal = await getBoolPreference();
    setState(() {
      val = stateVal;
      print('SharedPref from lifecycle: $val');
    });
    if (val) {
      //redirect to full screen or meeting
      print('meeting is already going on.');
    }
  }

  Future<bool> getBoolPreference() async {
    SharedPreferences prefs = await _prefs;
    bool op = prefs.getBool('checkmeet');
    return op;
  }

Here is the in LifeCycleManager.dart file where it says the meeting is already going on here I want to redirect or exit pip and take him back to meet. I hope now you can easily understand.

@imrushi As I had shared before.. these checks are only to keep track of active meeting or state of PIP.

The code I posted above will work only on iOS as its Swift code ...

public func resetBounds(bounds: CGRect) {
        currentBounds = bounds
        exitPictureInPicture()
    }

iOS and Android deal with PIP differently...

In Android you don't and I guess in some higher version, maybe 'O' you cant exit PIP mode programmatically. But what you can do is either kill and restart it, playaround with the framebounds to make it fullscreen. Its going to be a bit tricky but its possible....

Here is what you might need to do..

For kill and restart .. you can make use of Jitsi meet close function and then start again

For resizing frame.. First in JitsiMeetPluginActivity.kt Write a function exitPictureInPicture that makes PIP activity, makes it fullscreen (you can find it on the web easily, its like 2-3 lines of code).. This function should be callable from dart and for that you can see how we have implemented the CLOSE jitsi meeting method... its pretty straightforward..

Rest you are already handling the state in lifecyclemanager .. you can call the function from there. The transition wont be smooth though.

jimmyjose-dev commented 4 years ago

Yes when I tap to the arrow at the top of meeting it minimize the window of meeting but the background is black on IOS and Android it is showing the home screen instead of the main app. What I would like to be here is somehow we have the minimize of meeting and we can hav a way to fill out the remain screen with our main app parts, so they can use other functions of the main app normally ;)

@congthang1 I tried on Android 10 and it seems to work fine.. which version are you working on ?.

imrushi commented 4 years ago

@Snapworks @tuantvu need help ASAP I want to disable PIP I have added in features flag but it is not disabling it in android. here is code I have added

Map<FeatureFlagEnum, bool> featureFlags = {
        FeatureFlagEnum.WELCOME_PAGE_ENABLED: false,
        FeatureFlagEnum.PIP_ENABLED: false,
      };

      // Here is an example, disabling features for each platform
      if (Platform.isAndroid) {
        // Disable ConnectionService usage on Android to avoid issues (see README)
        featureFlags[FeatureFlagEnum.CALL_INTEGRATION_ENABLED] = false;
        featureFlags[FeatureFlagEnum.PIP_ENABLED] = false;
      } else if (Platform.isIOS) {
        // Disable PIP on iOS as it looks weird
        featureFlags[FeatureFlagEnum.PIP_ENABLED] = false;
      }
jimmyjose-dev commented 4 years ago

What i am gonna suggest is not the recommended way as the code should work but here it goes.. in this library's android.xml file change android:supportsPictureInPicture="true" to false https://github.com/gunschu/jitsi_meet/blob/master/android/src/main/AndroidManifest.xml

I will look at the code over the weekend and take a stab at it.

jimmyjose-dev commented 4 years ago

After making the changes.. delete the existing app from the emulator or device and run again.

imrushi commented 4 years ago

Yes I forgot that it's my fault sorry

jimmyjose-dev commented 4 years ago

No problem brother :)

ducnmhn commented 4 years ago

@Snapworks Thank you for you support

iOS still has problem when use PIP

93438728-537e2380-f8eb-11ea-8f1b-de51da8cfc79

jimmyjose-dev commented 4 years ago

A pure PIP mode like android is currently not supported for device below iOS 14. If you are comfortable with modifying the source code, the black color is hardcoded ... you may change it to .clear or white or any color you prefer. https://github.com/gunschu/jitsi_meet/blob/22bf4eba04d281719211dc5ef8e0bab30082bb7b/ios/Classes/JitsiViewController.swift#L42

iOS 14 has support for PIP but I am not sure if this framework will elevate that without any modification... maybe someone can try and share feedback.

imrushi commented 4 years ago

Hi, @Snapworks I have disabled the pip, and everything working fine but when starting the app for the first time (after installation) when start meeting and minimize the app and click on the app it takes me back to the first page on click of the back button it takes me back to meet. But when I close the app completely and open it again a second time above issue is not anymore occurred what wrong is happening any idea please help. The same thing is happing but without pip as mention

pip prob

@Snapworks Here is a gif What I want is that when I am in pip mode and click on my app it should take me back to the meeting ( Fullscreen of Pip meet).

in this gif only for 1st time (after app install).

imrushi commented 4 years ago

and my meeting timer is also not working

imrushi commented 4 years ago

@Snapworks I found the solution to resume the meeting when we click on the app. here is the code which we have to put in the onResume() state of the app

startActivity(new Intent(this, JitsiMeetActivity.class).addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT));

I have tried this code on the official jitsi_meet android SDK in java it worked how should I implement this in flutter jitsi SDK. and I have tried to implement this using method channels in JitsiMeetPlugin.kt

private fun pipFullScreen(call: MethodCall, result: Result){
        var intent = Intent(activity, JitsiMeetActivity::class.java)
        intent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT)
        activity?.startActivity(intent)
        //startActivity(Intent(this, JitsiMeetActivity::class.java).addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT))
        result.success("Picture in Picture Full Screen onResume")
    }

jitsi_meet.dart

static pipFullScreen() {
    _channel.invokeMethod('pipFullScreen');
}

above instead of activity, I want to pass my local application context to this method. Please help if this issue is get solved then can make PR and it will also help others.

jimmyjose-dev commented 4 years ago

@imrushi Glad that you are making progress.. I am swamped this week, will try to look into it over the weekend(cant promise though).. if you look into my PR or any existing code implementation you might get the hint..

imrushi commented 4 years ago

Hi, @Snapworks Thanks for all your help I solved the issue we have just add some code in android MainActivity.kt in the local flutter project we don't have do any changes in the jitsi_meet plugin repo here is all code which you have to add to your local project.

MainActivity.kt

import android.content.Context
import android.content.Intent
import io.flutter.embedding.android.FlutterActivity
import io.flutter.plugin.common.MethodChannel
import androidx.annotation.NonNull
import com.gunschu.jitsi_meet.JitsiMeetPluginActivity
import io.flutter.embedding.engine.FlutterEngine

class MainActivity: FlutterActivity() {
    private val CHANNEL = "pip/fullscreen"
    override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) {
        super.configureFlutterEngine(flutterEngine)

        MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL).setMethodCallHandler {
            call, result ->
            if (call.method == "fullscreen"){
                var intent = Intent(context, JitsiMeetPluginActivity::class.java)
                intent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT)
                context?.startActivity(intent)
            }
        }
    }
}

Create LifecCycleManager.dart file and add this

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:shared_preferences/shared_preferences.dart';

class LifeCycleManger extends StatefulWidget {
  final Widget child;

  LifeCycleManger({Key key, this.child}) : super(key: key);
  _LifeCycleMangerState createState() => _LifeCycleMangerState();
}

class _LifeCycleMangerState extends State<LifeCycleManger>
    with WidgetsBindingObserver {
  bool val = false;
  Future<SharedPreferences> _prefs = SharedPreferences.getInstance();
  static const platform = const MethodChannel('pip/fullscreen');

  @override
  void initState() {
    super.initState();
    WidgetsBinding.instance.addObserver(this);
    getShareprefVal();
  }

  @override
  void dispose() {
    super.dispose();
    WidgetsBinding.instance.removeObserver(this);
  }

  @override
  void didChangeAppLifecycleState(AppLifecycleState state) {
    super.didChangeAppLifecycleState(state);
    print('LifeCycleState= $state');
    if (state == AppLifecycleState.paused) {
      // SystemNavigator.pop();
    }
    if (state == AppLifecycleState.resumed) {
      // send to full screen of meeting
      getShareprefVal();
    }
  }

  Future<bool> getBoolPreference() async {
    SharedPreferences prefs = await _prefs;
    bool op = prefs.getBool('checkmeet');
    if (op == null) {
      op = false;
    }
    return op;
  }

  getShareprefVal() async {
    bool stateVal = await getBoolPreference();
    setState(() {
      val = stateVal;
      print('SharedPref from lifecycle: $val');
    });
    if (val) {
      //redirect to full screen or meeting
      print('meeting is already going on.');
      await platform.invokeMethod('fullscreen');
    }
  }

  @override
  Widget build(BuildContext context) {
    return widget.child;
  }
}

in Main.dart wrap your app in lifecycle widget

void main() {
  runApp(LifeCycleManger(child: MyApp()));
}

To keep the track of your meeting adds the Following code to your MainPage where your taking inputs for eg Room Name, Email, Displayname, etc..

//add this under all variable declare
Future<SharedPreferences> _prefs = SharedPreferences.getInstance();

//add this under _onError() method
Future<bool> saveBoolPreference(bool check) async {
    SharedPreferences prefs = await _prefs;
    setState(() {
      bool checkmeet = check;
      prefs.setBool('checkmeet', checkmeet);
      print('SharedPref of checkmeet: $checkmeet');
    });
  }

//call saveBoolPreference() method in _onConferenceTerminated & RasiedButton->onPressed()
void _onConferenceTerminated({message}) {
    debugPrint("_onConferenceTerminated broadcasted with message: $message");
    saveBoolPreference(false);
  }

RaisedButton(
    onPressed: () {
        saveBoolPreference();
        _joinMeeting();
    },
    child: Text(
        "Join Meeting",
        style: TextStyle(color: Colors.white),
    ),
    color: Colors.blue,
    );
jimmyjose-dev commented 4 years ago

@imrushi This is great news brother, thanks for being so awesome :) I am pretty sure a lot of research and failure went into this but eventually your persistence paid off but most importantly you took time to share your result with the community, kudos to you 🥇

imrushi commented 4 years ago

@Snapworks Thanks now I am closing this issues as it is solved if have any problem reopen it.

aartiaparekh commented 3 years ago

@Snapworks Thank you for you support

iOS still has problem when use PIP

93438728-537e2380-f8eb-11ea-8f1b-de51da8cfc79

Hi.

You got solution? I am stuck in same flow.

Thanks

jimmyjose-dev commented 3 years ago

@aartiaparekh Mam.. pure android like PIP mode in iOS is beyond this package as it is just an interface for the original sdk which currently doesn't support pure PIP.

If you are still interested in this feature, you would have to fix the reactive native code and recompile the code... i have explained how to add custom framework in my other post.

Another way to go about is to add this as a new feature request in the official jitsi github, when enough people will show interest the jitsi team might add it to the roadmap.

aartiaparekh commented 3 years ago

@ducnmhn

Can you please help me? In ios when I open pip mode background is black, I already set my screen but still its black. I can't solve and its urgent.

KanwalKhan-20 commented 3 years ago

I am using android SDK and after enabling the screen sharing option pip arrow is getting disabled, is there any way to use pip mode during screen sharing?

devprajeet commented 2 years ago

End meeting button click Crash

end meeting button click issue

Log below

View class com.facebook.react.views.text.ReactTextView is an AppCompat widget that can only be used with a Theme.AppCompat theme (or descendant). E/ThemeUtils( 8021): View class com.facebook.react.views.switchview.ReactSwitch is an AppCompat widget that can only be used with a Theme.AppCompat theme (or descendant). E/unknown:ViewManager( 8021): Error while updating prop thumbTintColor E/unknown:ViewManager( 8021): java.lang.reflect.InvocationTargetException E/unknown:ViewManager( 8021): at java.lang.reflect.Method.invoke(Native Method) E/unknown:ViewManager( 8021): at com.facebook.react.uimanager.ViewManagersPropertyCache$PropSetter.updateViewProp(ViewManagersPropertyCache.java:83) E/unknown:ViewManager( 8021): at com.facebook.react.uimanager.ViewManagerPropertyUpdater$FallbackViewManagerSetter.setProperty(ViewManagerPropertyUpdater.java:134) E/unknown:ViewManager( 8021): at com.facebook.react.uimanager.ViewManagerPropertyUpdater.updateProps(ViewManagerPropertyUpdater.java:54) E/unknown:ViewManager( 8021): at com.facebook.react.uimanager.ViewManager.updateProperties(ViewManager.java:48) E/unknown:ViewManager( 8021): at com.facebook.react.uimanager.NativeViewHierarchyManager.createView(NativeViewHierarchyManager.java:278) E/unknown:ViewManager( 8021): at com.facebook.react.uimanager.UIViewOperationQueue$CreateViewOperation.execute(UIViewOperationQueue.java:179) E/unknown:ViewManager( 8021): at com.facebook.react.uimanager.UIViewOperationQueue$DispatchUIFrameCallback.dispatchPendingNonBatchedOperations(UIViewOperationQueue.java:972) E/unknown:ViewManager( 8021): at com.facebook.react.uimanager.UIViewOperationQueue$DispatchUIFrameCallback.doFrameGuarded(UIViewOperationQueue.java:943) E/unknown:ViewManager( 8021): at com.facebook.react.uimanager.GuardedFrameCallback.doFrame(GuardedFrameCallback.java:28) E/unknown:ViewManager( 8021): at com.facebook.react.modules.core.ReactChoreographer$ReactChoreographerDispatcher.doFrame(ReactChoreographer.java:174) E/unknown:ViewManager( 8021): at com.facebook.react.modules.core.ChoreographerCompat$FrameCallback$1.doFrame(ChoreographerCompat.java:84) E/unknown:ViewManager( 8021): at android.view.Choreographer$CallbackRecord.run(Choreographer.java:964) E/unknown:ViewManager( 8021): at android.view.Choreographer.doCallbacks(Choreographer.java:790) E/unknown:ViewManager( 8021): at android.view.Choreographer.doFrame(Choreographer.java:721) E/unknown:ViewManager( 8021): at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:951) E/unknown:ViewManager( 8021): at android.os.Handler.handleCallback(Handler.java:883) E/unknown:ViewManager( 8021): at android.os.Handler.dispatchMessage(Handler.java:100) E/unknown:ViewManager( 8021): at android.os.Looper.loop(Looper.java:214) E/unknown:ViewManager( 8021): at android.app.ActivityThread.main(ActivityThread.java:7356) E/unknown:ViewManager( 8021): at java.lang.reflect.Method.invoke(Native Method) E/unknown:ViewManager( 8021): at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492) E/unknown:ViewManager( 8021): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930) E/unknown:ViewManager( 8021): Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.graphics.drawable.Drawable.setColorFilter(int, android.graphics.PorterDuff$Mode)' on a null object reference E/unknown:ViewManager( 8021): at com.facebook.react.views.switchview.ReactSwitch.setColor(ReactSwitch.java:51) E/unknown:ViewManager( 8021): at com.facebook.react.views.switchview.ReactSwitch.setThumbColor(ReactSwitch.java:60) E/unknown:ViewManager( 8021): at com.facebook.react.views.switchview.ReactSwitchManager.setThumbColor(ReactSwitchManager.java:134) E/unknown:ViewManager( 8021): at com.facebook.react.views.switchview.ReactSwitchManager.setThumbTintColor(ReactSwitchManager.java:129) E/unknown:ViewManager( 8021): ... 23 more D/AndroidRuntime( 8021): Shutting down VM D/com.oney.WebRTCModule.VideoTrackAdapter( 8021): Deleted adapter for 8ebdeb3a-adbe-4558-96f0-43795a238b7e-10 D/com.oney.WebRTCModule.VideoTrackAdapter( 8021): Deleted adapter for mixedlabelvideo0 E/AndroidRuntime( 8021): FATAL EXCEPTION: main E/AndroidRuntime( 8021): Process: com.wtf.member, PID: 8021 E/AndroidRuntime( 8021): com.facebook.react.bridge.JSApplicationIllegalArgumentException: Error while updating property 'thumbTintColor' of a view managed by: AndroidSwitch E/AndroidRuntime( 8021): at com.facebook.react.uimanager.ViewManagersPropertyCache$PropSetter.updateViewProp(ViewManagersPropertyCache.java:98) E/AndroidRuntime( 8021): at com.facebook.react.uimanager.ViewManagerPropertyUpdater$FallbackViewManagerSetter.setProperty(ViewManagerPropertyUpdater.java:134) E/AndroidRuntime( 8021): at com.facebook.react.uimanager.ViewManagerPropertyUpdater.updateProps(ViewManagerPropertyUpdater.java:54) E/AndroidRuntime( 8021): at com.facebook.react.uimanager.ViewManager.updateProperties(ViewManager.java:48) E/AndroidRuntime( 8021): at com.facebook.react.uimanager.NativeViewHierarchyManager.createView(NativeViewHierarchyManager.java:278) E/AndroidRuntime( 8021): at com.facebook.react.uimanager.UIViewOperationQueue$CreateViewOperation.execute(UIViewOperationQueue.java:179) E/AndroidRuntime( 8021): at com.facebook.react.uimanager.UIViewOperationQueue$DispatchUIFrameCallback.dispatchPendingNonBatchedOperations(UIViewOperationQueue.java:972) E/AndroidRuntime( 8021): at com.facebook.react.uimanager.UIViewOperationQueue$DispatchUIFrameCallback.doFrameGuarded(UIViewOperationQueue.java:943) E/AndroidRuntime( 8021): at com.facebook.react.uimanager.GuardedFrameCallback.doFrame(GuardedFrameCallback.java:28) E/AndroidRuntime( 8021): at com.facebook.react.modules.core.ReactChoreographer$ReactChoreographerDispatcher.doFrame(ReactChoreographer.java:174) E/AndroidRuntime( 8021): at com.facebook.react.modules.core.ChoreographerCompat$FrameCallback$1.doFrame(ChoreographerCompat.java:84) E/AndroidRuntime( 8021): at android.view.Choreographer$CallbackRecord.run(Choreographer.java:964) E/AndroidRuntime( 8021): at android.view.Choreographer.doCallbacks(Choreographer.java:790) E/AndroidRuntime( 8021): at android.view.Choreographer.doFrame(Choreographer.java:721) E/AndroidRuntime( 8021): at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:951) E/AndroidRuntime( 8021): at android.os.Handler.handleCallback(Handler.java:883) E/AndroidRuntime( 8021): at android.os.Handler.dispatchMessage(Handler.java:100) E/AndroidRuntime( 8021): at android.os.Looper.loop(Looper.java:214) E/AndroidRuntime( 8021): at android.app.ActivityThread.main(ActivityThread.java:7356) E/AndroidRuntime( 8021): at java.lang.reflect.Method.invoke(Native Method) E/AndroidRuntime( 8021): at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492) E/AndroidRuntime( 8021): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930) E/AndroidRuntime( 8021): Caused by: java.lang.reflect.InvocationTargetException E/AndroidRuntime( 8021): at java.lang.reflect.Method.invoke(Native Method) E/AndroidRuntime( 8021): at com.facebook.react.uimanager.ViewManagersPropertyCache$PropSetter.updateViewProp(ViewManagersPropertyCache.java:83) E/AndroidRuntime( 8021): ... 21 more E/AndroidRuntime( 8021): Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.graphics.drawable.Drawable.setColorFilter(int, android.graphics.PorterDuff$Mode)' on a null object reference E/AndroidRuntime( 8021): at com.facebook.react.views.switchview.ReactSwitch.setColor(ReactSwitch.java:51) E/AndroidRuntime( 8021): at com.facebook.react.views.switchview.ReactSwitch.setThumbColor(ReactSwitch.java:60) E/AndroidRuntime( 8021): at com.facebook.react.views.switchview.ReactSwitchManager.setThumbColor(ReactSwitchManager.java:134) E/AndroidRuntime( 8021): at com.facebook.react.views.switchview.ReactSwitchManager.setThumbTintColor(ReactSwitchManager.java:129) E/AndroidRuntime( 8021): ... 23 more E/JitsiMeetSDK( 8021): JitsiMeetUncaughtExceptionHandler FATAL ERROR E/JitsiMeetSDK( 8021): com.facebook.react.bridge.JSApplicationIllegalArgumentException: Error while updating property 'thumbTintColor' of a view managed by: AndroidSwitch E/JitsiMeetSDK( 8021): at com.facebook.react.uimanager.ViewManagersPropertyCache$PropSetter.updateViewProp(ViewManagersPropertyCache.java:98) E/JitsiMeetSDK( 8021): at com.facebook.react.uimanager.ViewManagerPropertyUpdater$FallbackViewManagerSetter.setProperty(ViewManagerPropertyUpdater.java:134) E/JitsiMeetSDK( 8021): at com.facebook.react.uimanager.ViewManagerPropertyUpdater.updateProps(ViewManagerPropertyUpdater.java:54) E/JitsiMeetSDK( 8021): at com.facebook.react.uimanager.ViewManager.updateProperties(ViewManager.java:48) E/JitsiMeetSDK( 8021): at com.facebook.react.uimanager.NativeViewHierarchyManager.createView(NativeViewHierarchyManager.java:278) E/JitsiMeetSDK( 8021): at com.facebook.react.uimanager.UIViewOperationQueue$CreateViewOperation.execute(UIViewOperationQueue.java:179) E/JitsiMeetSDK( 8021): at com.facebook.react.uimanager.UIViewOperationQueue$DispatchUIFrameCallback.dispatchPendingNonBatchedOperations(UIViewOperationQueue.java:972) E/JitsiMeetSDK( 8021): at com.facebook.react.uimanager.UIViewOperationQueue$DispatchUIFrameCallback.doFrameGuarded(UIViewOperationQueue.java:943) E/JitsiMeetSDK( 8021): at com.facebook.react.uimanager.GuardedFrameCallback.doFrame(GuardedFrameCallback.java:28) E/JitsiMeetSDK( 8021): at com.facebook.react.modules.core.ReactChoreographer$ReactChoreographerDispatcher.doFrame(ReactChoreographer.java:174) E/JitsiMeetSDK( 8021): at com.facebook.react.modules.core.ChoreographerCompat$FrameCallback$1.doFrame(ChoreographerCompat.java:84) E/JitsiMeetSDK( 8021): at android.view.Choreographer$CallbackRecord.run(Choreographer.java:964) E/JitsiMeetSDK( 8021): at android.view.Choreographer.doCallbacks(Choreographer.java:790) E/JitsiMeetSDK( 8021): at android.view.Choreographer.doFrame(Choreographer.java:721) E/JitsiMeetSDK( 8021): at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:951) E/JitsiMeetSDK( 8021): at android.os.Handler.handleCallback(Handler.java:883) E/JitsiMeetSDK( 8021): at android.os.Handler.dispatchMessage(Handler.java:100) E/JitsiMeetSDK( 8021): at android.os.Looper.loop(Looper.java:214) E/JitsiMeetSDK( 8021): at android.app.ActivityThread.main(ActivityThread.java:7356) E/JitsiMeetSDK( 8021): at java.lang.reflect.Method.invoke(Native Method) E/JitsiMeetSDK( 8021): at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492) E/JitsiMeetSDK( 8021): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930) E/JitsiMeetSDK( 8021): Caused by: java.lang.reflect.InvocationTargetException E/JitsiMeetSDK( 8021): at java.lang.reflect.Method.invoke(Native Method) E/JitsiMeetSDK( 8021): at com.facebook.react.uimanager.ViewManagersPropertyCache$PropSetter.updateViewProp(ViewManagersPropertyCache.java:83) E/JitsiMeetSDK( 8021): ... 21 more E/JitsiMeetSDK( 8021): Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.graphics.drawable.Drawable.setColorFilter(int, android.graphics.PorterDuff$Mode)' on a null object reference E/JitsiMeetSDK( 8021): at com.facebook.react.views.switchview.ReactSwitch.setColor(ReactSwitch.java:51) E/JitsiMeetSDK( 8021): at com.facebook.react.views.switchview.ReactSwitch.setThumbColor(ReactSwitch.java:60) E/JitsiMeetSDK( 8021): at com.facebook.react.views.switchview.ReactSwitchManager.setThumbColor(ReactSwitchManager.java:134) E/JitsiMeetSDK( 8021): at com.facebook.react.views.switchview.ReactSwitchManager.setThumbTintColor(ReactSwitchManager.java:129) E/JitsiMeetSDK( 8021): ... 23 more E/JitsiMeetSDK( 8021): E/JitsiMeetSDK( 8021): com.facebook.react.bridge.JSApplicationIllegalArgumentException: Error while updating property 'thumbTintColor' of a view managed by: AndroidSwitch E/JitsiMeetSDK( 8021): at com.facebook.react.uimanager.ViewManagersPropertyCache$PropSetter.updateViewProp(ViewManagersPropertyCache.java:98) E/JitsiMeetSDK( 8021): at com.facebook.react.uimanager.ViewManagerPropertyUpdater$FallbackViewManagerSetter.setProperty(ViewManagerPropertyUpdater.java:134) E/JitsiMeetSDK( 8021): at com.facebook.react.uimanager.ViewManagerPropertyUpdater.updateProps(ViewManagerPropertyUpdater.java:54) E/JitsiMeetSDK( 8021): at com.facebook.react.uimanager.ViewManager.updateProperties(ViewManager.java:48) E/JitsiMeetSDK( 8021): at com.facebook.react.uimanager.NativeViewHierarchyManager.createView(NativeViewHierarchyManager.java:278) E/JitsiMeetSDK( 8021): at com.facebook.react.uimanager.UIViewOperationQueue$CreateViewOperation.execute(UIViewOperationQueue.java:179) E/JitsiMeetSDK( 8021): at com.facebook.react.uimanager.UIViewOperationQueue$DispatchUIFrameCallback.dispatchPendingNonBatchedOperations(UIViewOperationQueue.java:972) E/JitsiMeetSDK( 8021): at com.facebook.react.uimanager.UIViewOperationQueue$DispatchUIFrameCallback.doFrameGuarded(UIViewOpe