From 9e10c120bc1bef97cd2bbbc1b3dc2d498c85d4db Mon Sep 17 00:00:00 2001 From: gianlucaparadise Date: Mon, 11 Nov 2019 22:52:04 +0100 Subject: [PATCH] SessionManager state implementation; Little methods refactor; --- .../FlutterCastFrameworkPlugin.kt | 92 ++++++++++++++++++- example/lib/main.dart | 23 ++++- lib/MethodNames.dart | 14 +++ lib/cast/CastContext.dart | 14 ++- lib/cast/SessionManager.dart | 51 ++++++++++ lib/cast/widgets/CastIcon.dart | 2 +- lib/flutter_cast_framework.dart | 23 +++-- 7 files changed, 201 insertions(+), 18 deletions(-) create mode 100644 lib/MethodNames.dart create mode 100644 lib/cast/SessionManager.dart diff --git a/android/src/main/kotlin/com/gianlucaparadise/flutter_cast_framework/FlutterCastFrameworkPlugin.kt b/android/src/main/kotlin/com/gianlucaparadise/flutter_cast_framework/FlutterCastFrameworkPlugin.kt index 519d107..7e1cbd5 100644 --- a/android/src/main/kotlin/com/gianlucaparadise/flutter_cast_framework/FlutterCastFrameworkPlugin.kt +++ b/android/src/main/kotlin/com/gianlucaparadise/flutter_cast_framework/FlutterCastFrameworkPlugin.kt @@ -8,6 +8,9 @@ import androidx.lifecycle.ProcessLifecycleOwner import androidx.mediarouter.app.MediaRouteChooserDialog import androidx.mediarouter.app.MediaRouteControllerDialog import com.google.android.gms.cast.framework.CastContext +import com.google.android.gms.cast.framework.CastSession +import com.google.android.gms.cast.framework.SessionManager +import com.google.android.gms.cast.framework.SessionManagerListener import io.flutter.plugin.common.MethodCall import io.flutter.plugin.common.MethodChannel import io.flutter.plugin.common.MethodChannel.MethodCallHandler @@ -25,23 +28,59 @@ class FlutterCastFrameworkPlugin(private val registrar: Registrar, private val c } } + private object MethodNames { + const val onCastStateChanged = "CastContext.onCastStateChanged" + const val showCastDialog = "showCastDialog" + + // region SessionManager + const val onSessionStarting = "SessionManager.onSessionStarting" + const val onSessionStarted = "SessionManager.onSessionStarted" + const val onSessionStartFailed = "SessionManager.onSessionStartFailed" + const val onSessionEnding = "SessionManager.onSessionEnding" + const val onSessionEnded = "SessionManager.onSessionEnded" + const val onSessionResuming = "SessionManager.onSessionResuming" + const val onSessionResumed = "SessionManager.onSessionResumed" + const val onSessionResumeFailed = "SessionManager.onSessionResumeFailed" + const val onSessionSuspended = "SessionManager.onSessionSuspended" + // end-region + } + init { ProcessLifecycleOwner.get().lifecycle.addObserver(this) CastContext.getSharedInstance(registrar.activeContext()).addCastStateListener { i -> Log.d(TAG, "Cast state changed: $i") - channel.invokeMethod("onCastStateChanged", i) + channel.invokeMethod(MethodNames.onCastStateChanged, i) } } + private lateinit var mSessionManager: SessionManager + private val mSessionManagerListener = CastSessionManagerListener() + + @OnLifecycleEvent(Lifecycle.Event.ON_CREATE) + fun onCreate() { + Log.d(TAG, "App: ON_CREATE") + mSessionManager = CastContext.getSharedInstance(registrar.activeContext()).sessionManager + } + @OnLifecycleEvent(Lifecycle.Event.ON_RESUME) fun onResume() { Log.d(TAG, "App: ON_RESUME") + mSessionManager.addSessionManagerListener(mSessionManagerListener, CastSession::class.java) + } + + @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE) + fun onPause() { + Log.d(TAG, "App: ON_PAUSE") + mSessionManager.removeSessionManagerListener( + mSessionManagerListener, + CastSession::class.java + ) } override fun onMethodCall(call: MethodCall, result: Result) { when (call.method) { - "showCastDialog" -> showCastDialog() + MethodNames.showCastDialog -> showCastDialog() else -> result.notImplemented() } } @@ -72,4 +111,53 @@ class FlutterCastFrameworkPlugin(private val registrar: Registrar, private val c " Check https://developers.google.com/cast/docs/android_sender/integrate#androidtheme", ex) } } + + private inner class CastSessionManagerListener : SessionManagerListener { + private var TAG = "SessionManagerListenerImpl" + + override fun onSessionSuspended(session: CastSession?, p1: Int) { + Log.d(TAG, "onSessionSuspended") + channel.invokeMethod(MethodNames.onSessionSuspended, null) + } + + override fun onSessionStarting(session: CastSession?) { + Log.d(TAG, "onSessionStarting") + channel.invokeMethod(MethodNames.onSessionStarting, null) + } + + override fun onSessionResuming(session: CastSession?, p1: String?) { + Log.d(TAG, "onSessionResuming") + channel.invokeMethod(MethodNames.onSessionResuming, null) + } + + override fun onSessionEnding(session: CastSession?) { + Log.d(TAG, "onSessionEnding") + channel.invokeMethod(MethodNames.onSessionEnding, null) + } + + override fun onSessionStartFailed(session: CastSession?, p1: Int) { + Log.d(TAG, "onSessionStartFailed") + channel.invokeMethod(MethodNames.onSessionStartFailed, null) + } + + override fun onSessionResumeFailed(session: CastSession?, p1: Int) { + Log.d(TAG, "onSessionResumeFailed") + channel.invokeMethod(MethodNames.onSessionResumeFailed, null) + } + + override fun onSessionStarted(session: CastSession, sessionId: String) { + Log.d(TAG, "onSessionStarted") + channel.invokeMethod(MethodNames.onSessionStarted, null) + } + + override fun onSessionResumed(session: CastSession, wasSuspended: Boolean) { + Log.d(TAG, "onSessionResumed") + channel.invokeMethod(MethodNames.onSessionResumed, null) + } + + override fun onSessionEnded(session: CastSession, error: Int) { + Log.d(TAG, "onSessionEnded") + channel.invokeMethod(MethodNames.onSessionEnded, null) + } + } } diff --git a/example/lib/main.dart b/example/lib/main.dart index 4e62545..fc7868d 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -1,5 +1,6 @@ import 'package:flutter/material.dart'; import 'package:flutter_cast_framework/cast/CastContext.dart'; +import 'package:flutter_cast_framework/cast/SessionManager.dart'; import 'package:flutter_cast_framework/cast/widgets/CastButton.dart'; import 'package:flutter_cast_framework/flutter_cast_framework.dart'; @@ -11,12 +12,14 @@ class MyApp extends StatefulWidget { } class _MyAppState extends State { - CastState _castState; + CastState _castState = CastState.idle; + SessionState _sessionState = SessionState.idle; @override void initState() { super.initState(); FlutterCastFramework.castContext.state.addListener(_onCastStateChanged); + FlutterCastFramework.castContext.sessionManager.state.addListener(_onSessionStateChanged); } void _onCastStateChanged() { @@ -26,6 +29,13 @@ class _MyAppState extends State { }); } + void _onSessionStateChanged() { + debugPrint("Session state changed from example"); + setState(() { + _sessionState = FlutterCastFramework.castContext.sessionManager.state.value; + }); + } + @override Widget build(BuildContext context) { return MaterialApp( @@ -34,9 +44,14 @@ class _MyAppState extends State { title: const Text('Cast plugin example app'), ), body: Center( - child: Column( - children: [Text('Cast State: $_castState'), CastButton()], - )), + child: Column( + children: [ + CastButton(), + Text('Cast State: $_castState'), + Text('Cast State: $_sessionState'), + ], + ), + ), ), ); } diff --git a/lib/MethodNames.dart b/lib/MethodNames.dart new file mode 100644 index 0000000..b44230c --- /dev/null +++ b/lib/MethodNames.dart @@ -0,0 +1,14 @@ +class PlatformMethodNames { + static const onCastStateChanged = "CastContext.onCastStateChanged"; + static const showCastDialog = "showCastDialog"; + + static const onSessionStarting = "SessionManager.onSessionStarting"; + static const onSessionStarted = "SessionManager.onSessionStarted"; + static const onSessionStartFailed = "SessionManager.onSessionStartFailed"; + static const onSessionEnding = "SessionManager.onSessionEnding"; + static const onSessionEnded = "SessionManager.onSessionEnded"; + static const onSessionResuming = "SessionManager.onSessionResuming"; + static const onSessionResumed = "SessionManager.onSessionResumed"; + static const onSessionResumeFailed = "SessionManager.onSessionResumeFailed"; + static const onSessionSuspended = "SessionManager.onSessionSuspended"; +} \ No newline at end of file diff --git a/lib/cast/CastContext.dart b/lib/cast/CastContext.dart index a81f7ad..29d0d2d 100644 --- a/lib/cast/CastContext.dart +++ b/lib/cast/CastContext.dart @@ -1,6 +1,7 @@ import 'package:flutter/foundation.dart'; import 'package:flutter/services.dart'; -import 'package:flutter_cast_framework/flutter_cast_framework.dart'; +import 'package:flutter_cast_framework/MethodNames.dart'; +import 'package:flutter_cast_framework/cast/SessionManager.dart'; class CastContext { final ValueNotifier state = ValueNotifier(CastState.unavailable); @@ -9,12 +10,19 @@ class CastContext { CastContext(this._channel); void showCastChooserDialog() { - _channel.invokeMethod(MethodNames.showCastDialog); + _channel.invokeMethod(PlatformMethodNames.showCastDialog); } + + void onCastStateChanged(dynamic arguments) { + int castState = arguments; + state.value = CastState.values[castState]; + } + + SessionManager sessionManager = SessionManager(); } enum CastState { - default_state, // 0 + idle, // 0 unavailable, // 1 unconnected, // 2 connecting, // 3 diff --git a/lib/cast/SessionManager.dart b/lib/cast/SessionManager.dart new file mode 100644 index 0000000..999a74e --- /dev/null +++ b/lib/cast/SessionManager.dart @@ -0,0 +1,51 @@ +import 'package:flutter/foundation.dart'; +import 'package:flutter_cast_framework/MethodNames.dart'; + +class SessionManager { + final ValueNotifier state = ValueNotifier(SessionState.idle); + + void onSessionStateChanged(String method, dynamic arguments) { + switch (method) { + case PlatformMethodNames.onSessionStarting: + state.value = SessionState.session_starting; + break; + case PlatformMethodNames.onSessionStarted: + state.value = SessionState.session_started; + break; + case PlatformMethodNames.onSessionStartFailed: + state.value = SessionState.session_start_failed; + break; + case PlatformMethodNames.onSessionEnding: + state.value = SessionState.session_ending; + break; + case PlatformMethodNames.onSessionEnded: + state.value = SessionState.session_ended; + break; + case PlatformMethodNames.onSessionResuming: + state.value = SessionState.session_resuming; + break; + case PlatformMethodNames.onSessionResumed: + state.value = SessionState.session_resumed; + break; + case PlatformMethodNames.onSessionResumeFailed: + state.value = SessionState.session_resume_failed; + break; + case PlatformMethodNames.onSessionSuspended: + state.value = SessionState.session_suspended; + break; + } + } +} + +enum SessionState { + idle, + session_starting, + session_started, + session_start_failed, + session_ending, + session_ended, + session_resuming, + session_resumed, + session_resume_failed, + session_suspended, +} diff --git a/lib/cast/widgets/CastIcon.dart b/lib/cast/widgets/CastIcon.dart index 7486871..cc6116f 100644 --- a/lib/cast/widgets/CastIcon.dart +++ b/lib/cast/widgets/CastIcon.dart @@ -53,7 +53,7 @@ class _CastIconState extends State with TickerProviderStateMixin { case CastState.connected: return _getButton("assets/ic_cast_connected_24dp.svg"); - case CastState.default_state: + case CastState.idle: default: debugPrint("State not handled: $_castState"); return _getEmpty(); diff --git a/lib/flutter_cast_framework.dart b/lib/flutter_cast_framework.dart index 82115b7..0252bb2 100644 --- a/lib/flutter_cast_framework.dart +++ b/lib/flutter_cast_framework.dart @@ -1,12 +1,8 @@ import 'package:flutter/foundation.dart'; import 'package:flutter/services.dart'; +import 'package:flutter_cast_framework/MethodNames.dart'; import 'package:flutter_cast_framework/cast/CastContext.dart'; -class MethodNames { - static const onCastStateChanged = "onCastStateChanged"; - static const showCastDialog = "showCastDialog"; -} - class FlutterCastFramework { static const MethodChannel _channel = const MethodChannel('flutter_cast_framework'); @@ -20,9 +16,20 @@ class FlutterCastFramework { debugPrint("Method call on flutter: $method $arguments"); switch (method) { - case MethodNames.onCastStateChanged: - int castState = arguments; - castContext.state.value = CastState.values[castState]; + case PlatformMethodNames.onCastStateChanged: + castContext.onCastStateChanged(arguments); + break; + + case PlatformMethodNames.onSessionStarting: + case PlatformMethodNames.onSessionStarted: + case PlatformMethodNames.onSessionStartFailed: + case PlatformMethodNames.onSessionEnding: + case PlatformMethodNames.onSessionEnded: + case PlatformMethodNames.onSessionResuming: + case PlatformMethodNames.onSessionResumed: + case PlatformMethodNames.onSessionResumeFailed: + case PlatformMethodNames.onSessionSuspended: + castContext.sessionManager.onSessionStateChanged(method, arguments); break; default: