Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Sign in
Toggle navigation
F
Front-End
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
abdullh.alsoleman
Front-End
Commits
471c97df
Commit
471c97df
authored
Mar 30, 2017
by
Mikkel Nygaard Ravn
Committed by
GitHub
Mar 30, 2017
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Platform channel API cleanup (#9048)
parent
0e43e581
Changes
7
Show whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
131 additions
and
55 deletions
+131
-55
MainActivity.java
...c/main/java/com/example/platformchannel/MainActivity.java
+4
-1
AppDelegate.m
examples/platform_channel/ios/Runner/AppDelegate.m
+3
-7
message_codec.dart
packages/flutter/lib/src/services/message_codec.dart
+19
-3
message_codecs.dart
packages/flutter/lib/src/services/message_codecs.dart
+0
-4
platform_channel.dart
packages/flutter/lib/src/services/platform_channel.dart
+74
-33
text_input.dart
packages/flutter/lib/src/services/text_input.dart
+2
-0
platform_channel_test.dart
packages/flutter/test/services/platform_channel_test.dart
+29
-7
No files found.
examples/platform_channel/android/app/src/main/java/com/example/platformchannel/MainActivity.java
View file @
471c97df
...
@@ -37,9 +37,12 @@ public class MainActivity extends FlutterActivity {
...
@@ -37,9 +37,12 @@ public class MainActivity extends FlutterActivity {
}
else
{
}
else
{
response
.
error
(
"UNAVAILABLE"
,
"Battery level not available."
,
null
);
response
.
error
(
"UNAVAILABLE"
,
"Battery level not available."
,
null
);
}
}
}
else
{
response
.
notImplemented
();
}
}
}
}
}
}
);
);
}
}
private
int
getBatteryLevel
()
{
private
int
getBatteryLevel
()
{
...
...
examples/platform_channel/ios/Runner/AppDelegate.m
View file @
471c97df
...
@@ -13,8 +13,7 @@
...
@@ -13,8 +13,7 @@
(
FlutterViewController
*
)
self
.
window
.
rootViewController
;
(
FlutterViewController
*
)
self
.
window
.
rootViewController
;
FlutterMethodChannel
*
batteryChannel
=
[
FlutterMethodChannel
FlutterMethodChannel
*
batteryChannel
=
[
FlutterMethodChannel
methodChannelWithName
:
@"battery"
methodChannelWithName
:
@"battery"
binaryMessenger
:
controller
binaryMessenger
:
controller
];
codec:
[
FlutterStandardMethodCodec
sharedInstance
]];
[
batteryChannel
setMethodCallHandler
:
^
(
FlutterMethodCall
*
call
,
[
batteryChannel
setMethodCallHandler
:
^
(
FlutterMethodCall
*
call
,
FlutterResultReceiver
result
)
{
FlutterResultReceiver
result
)
{
if
([
@"getBatteryLevel"
isEqualToString
:
call
.
method
])
{
if
([
@"getBatteryLevel"
isEqualToString
:
call
.
method
])
{
...
@@ -25,15 +24,12 @@
...
@@ -25,15 +24,12 @@
message
:
@"Battery info unavailable"
message
:
@"Battery info unavailable"
details:
nil
]);
details:
nil
]);
}
else
{
}
else
{
result
(
[
NSNumber
numberWithInt
:(
int
)(
device
.
batteryLevel
*
100
)]
);
result
(
@
((
int
)(
device
.
batteryLevel
*
100
))
);
}
}
}
else
{
}
else
{
result
([
FlutterError
errorWithCode
:
@"UNKNOWN_METHOD"
result
(
FlutterMethodNotImplemented
);
message
:
@"Unknown battery method called"
details:
nil
]);
}
}
}];
}];
return
YES
;
return
YES
;
}
}
@end
@end
packages/flutter/lib/src/services/message_codec.dart
View file @
471c97df
...
@@ -105,6 +105,8 @@ class MethodCall {
...
@@ -105,6 +105,8 @@ class MethodCall {
///
///
/// * [PlatformMethodChannel], which use [MethodCodec]s for communication
/// * [PlatformMethodChannel], which use [MethodCodec]s for communication
/// between Flutter and platform plugins.
/// between Flutter and platform plugins.
/// * [PlatformEventChannel], which use [MethodCodec]s for communication
/// between Flutter and platform plugins.
abstract
class
MethodCodec
{
abstract
class
MethodCodec
{
/// Encodes the specified [methodCall] in binary.
/// Encodes the specified [methodCall] in binary.
ByteData
encodeMethodCall
(
MethodCall
methodCall
);
ByteData
encodeMethodCall
(
MethodCall
methodCall
);
...
@@ -139,7 +141,7 @@ abstract class MethodCodec {
...
@@ -139,7 +141,7 @@ abstract class MethodCodec {
/// * [PlatformMethodChannel.invokeMethod], which completes the returned future
/// * [PlatformMethodChannel.invokeMethod], which completes the returned future
/// with a [PlatformException], if invoking the platform plugin method
/// with a [PlatformException], if invoking the platform plugin method
/// results in an error envelope.
/// results in an error envelope.
/// * [Platform
Method
Channel.receiveBroadcastStream], which emits
/// * [Platform
Event
Channel.receiveBroadcastStream], which emits
/// [PlatformException]s as error events, whenever an event received from the
/// [PlatformException]s as error events, whenever an event received from the
/// platform plugin is wrapped in an error envelope.
/// platform plugin is wrapped in an error envelope.
class
PlatformException
implements
Exception
{
class
PlatformException
implements
Exception
{
...
@@ -167,8 +169,22 @@ class PlatformException implements Exception {
...
@@ -167,8 +169,22 @@ class PlatformException implements Exception {
String
toString
()
=>
'PlatformException(
$code
,
$message
,
$details
)'
;
String
toString
()
=>
'PlatformException(
$code
,
$message
,
$details
)'
;
}
}
/// Thrown to indicate that a platform interaction failed to find the plugin.
/// Thrown to indicate that a platform interaction failed to find a handling
/// plugin.
///
/// See also:
///
/// * [PlatformMethodChannel.invokeMethod], which completes the returned future
/// with a [MissingPluginException], if no plugin handler for the method call
/// was found.
class
MissingPluginException
implements
Exception
{
class
MissingPluginException
implements
Exception
{
/// Creates a [MissingPluginException] with an optional human-readable
/// error message.
MissingPluginException
([
this
.
message
]);
/// A human-readable error message, possibly `null`.
final
String
message
;
@override
@override
String
toString
()
=>
'MissingPluginException'
;
String
toString
()
=>
'MissingPluginException
(
$message
)
'
;
}
}
packages/flutter/lib/src/services/message_codecs.dart
View file @
471c97df
...
@@ -120,8 +120,6 @@ class JSONMethodCodec implements MethodCodec {
...
@@ -120,8 +120,6 @@ class JSONMethodCodec implements MethodCodec {
@override
@override
dynamic
decodeEnvelope
(
ByteData
envelope
)
{
dynamic
decodeEnvelope
(
ByteData
envelope
)
{
if
(
envelope
==
null
)
throw
new
MissingPluginException
();
final
dynamic
decoded
=
const
JSONMessageCodec
().
decodeMessage
(
envelope
);
final
dynamic
decoded
=
const
JSONMessageCodec
().
decodeMessage
(
envelope
);
if
(
decoded
is
!
List
)
if
(
decoded
is
!
List
)
throw
new
FormatException
(
'Expected envelope List, got
$decoded
'
);
throw
new
FormatException
(
'Expected envelope List, got
$decoded
'
);
...
@@ -461,8 +459,6 @@ class StandardMethodCodec implements MethodCodec {
...
@@ -461,8 +459,6 @@ class StandardMethodCodec implements MethodCodec {
@override
@override
dynamic
decodeEnvelope
(
ByteData
envelope
)
{
dynamic
decodeEnvelope
(
ByteData
envelope
)
{
if
(
envelope
==
null
)
throw
new
MissingPluginException
();
// First byte is zero in success case, and non-zero otherwise.
// First byte is zero in success case, and non-zero otherwise.
if
(
envelope
.
lengthInBytes
==
0
)
if
(
envelope
.
lengthInBytes
==
0
)
throw
const
FormatException
(
'Expected envelope, got nothing'
);
throw
const
FormatException
(
'Expected envelope, got nothing'
);
...
...
packages/flutter/lib/src/services/platform_channel.dart
View file @
471c97df
...
@@ -90,7 +90,7 @@ class PlatformMessageChannel<T> {
...
@@ -90,7 +90,7 @@ class PlatformMessageChannel<T> {
}
}
/// A named channel for communicating with platform plugins using asynchronous
/// A named channel for communicating with platform plugins using asynchronous
/// method calls
and event streams
.
/// method calls.
///
///
/// Method calls are encoded into binary before being sent, and binary results
/// Method calls are encoded into binary before being sent, and binary results
/// received are decoded into Dart values. The [MethodCodec] used must be
/// received are decoded into Dart values. The [MethodCodec] used must be
...
@@ -125,12 +125,16 @@ class PlatformMethodChannel {
...
@@ -125,12 +125,16 @@ class PlatformMethodChannel {
/// * a result (possibly `null`), on successful invocation;
/// * a result (possibly `null`), on successful invocation;
/// * a [PlatformException], if the invocation failed in the platform plugin;
/// * a [PlatformException], if the invocation failed in the platform plugin;
/// * a [FormatException], if encoding or decoding failed.
/// * a [FormatException], if encoding or decoding failed.
/// * a [MissingPluginException], if the method has not been implemented.
Future
<
dynamic
>
invokeMethod
(
String
method
,
[
dynamic
arguments
])
async
{
Future
<
dynamic
>
invokeMethod
(
String
method
,
[
dynamic
arguments
])
async
{
assert
(
method
!=
null
);
assert
(
method
!=
null
);
return
codec
.
decodeEnvelope
(
await
PlatformMessages
.
sendBinary
(
final
dynamic
result
=
await
PlatformMessages
.
sendBinary
(
name
,
name
,
codec
.
encodeMethodCall
(
new
MethodCall
(
method
,
arguments
)),
codec
.
encodeMethodCall
(
new
MethodCall
(
method
,
arguments
)),
));
);
if
(
result
==
null
)
throw
new
MissingPluginException
(
"No implementation found for method
$method
on channel
$name
"
);
return
codec
.
decodeEnvelope
(
result
);
}
}
/// Sets a callback for receiving method calls on this channel.
/// Sets a callback for receiving method calls on this channel.
...
@@ -143,7 +147,9 @@ class PlatformMethodChannel {
...
@@ -143,7 +147,9 @@ class PlatformMethodChannel {
/// is sent back to the platform plugin caller wrapped in a success envelope
/// is sent back to the platform plugin caller wrapped in a success envelope
/// as defined by the [codec] of this channel. If the future completes with
/// as defined by the [codec] of this channel. If the future completes with
/// a [PlatformException], the fields of that exception will be used to
/// a [PlatformException], the fields of that exception will be used to
/// populate an error envelope which is sent back instead.
/// populate an error envelope which is sent back instead. If the future
/// completes with a [MissingPluginException], an empty reply is sent
/// similarly to what happens if no method call handler has been set.
void
setMethodCallHandler
(
Future
<
dynamic
>
handler
(
MethodCall
call
))
{
void
setMethodCallHandler
(
Future
<
dynamic
>
handler
(
MethodCall
call
))
{
if
(
handler
==
null
)
{
if
(
handler
==
null
)
{
PlatformMessages
.
setBinaryMessageHandler
(
name
,
null
);
PlatformMessages
.
setBinaryMessageHandler
(
name
,
null
);
...
@@ -158,6 +164,8 @@ class PlatformMethodChannel {
...
@@ -158,6 +164,8 @@ class PlatformMethodChannel {
}
on
PlatformException
catch
(
e
)
{
}
on
PlatformException
catch
(
e
)
{
return
codec
.
encodeErrorEnvelope
(
return
codec
.
encodeErrorEnvelope
(
code:
e
.
code
,
message:
e
.
message
,
details:
e
.
details
);
code:
e
.
code
,
message:
e
.
message
,
details:
e
.
details
);
}
on
MissingPluginException
{
return
null
;
}
}
},
},
);
);
...
@@ -170,9 +178,10 @@ class PlatformMethodChannel {
...
@@ -170,9 +178,10 @@ class PlatformMethodChannel {
/// this channel, if any. To remove the mock handler, pass `null` as the
/// this channel, if any. To remove the mock handler, pass `null` as the
/// `handler` argument.
/// `handler` argument.
///
///
/// If the future returned by the handler completes with a result, that value
/// Later calls to [invokeMethod] will result in a successful result,
/// is used as the result of the method invocation. If the future completes
/// a [PlatformException] or a [MissingPluginException], determined by how
/// with a [PlatformException], that will be thrown instead.
/// the future returned by the mock callback completes. The [codec] of this
/// channel is used to encode and decode values and errors.
///
///
/// This is intended for testing. Method calls intercepted in this manner are
/// This is intended for testing. Method calls intercepted in this manner are
/// not sent to platform plugins.
/// not sent to platform plugins.
...
@@ -190,11 +199,61 @@ class PlatformMethodChannel {
...
@@ -190,11 +199,61 @@ class PlatformMethodChannel {
}
on
PlatformException
catch
(
e
)
{
}
on
PlatformException
catch
(
e
)
{
return
codec
.
encodeErrorEnvelope
(
return
codec
.
encodeErrorEnvelope
(
code:
e
.
code
,
message:
e
.
message
,
details:
e
.
details
);
code:
e
.
code
,
message:
e
.
message
,
details:
e
.
details
);
}
on
MissingPluginException
{
return
null
;
}
}
},
},
);
);
}
}
}
}
}
/// A [PlatformMethodChannel] that ignores missing platform plugins.
///
/// When [invokeMethod] fails to find the platform plugin, it returns null
/// instead of throwing an exception.
class
OptionalPlatformMethodChannel
extends
PlatformMethodChannel
{
/// Creates a [PlatformMethodChannel] that ignores missing platform plugins.
const
OptionalPlatformMethodChannel
(
String
name
,
[
MethodCodec
codec
=
const
StandardMethodCodec
()])
:
super
(
name
,
codec
);
@override
Future
<
dynamic
>
invokeMethod
(
String
method
,
[
dynamic
arguments
])
async
{
try
{
return
await
super
.
invokeMethod
(
method
,
arguments
);
}
on
MissingPluginException
{
return
null
;
}
}
}
/// A named channel for communicating with platform plugins using event streams.
///
/// Stream setup requests are encoded into binary before being sent,
/// and binary events received are decoded into Dart values. The [MethodCodec]
/// used must be compatible with the one used by the platform plugin. This can
/// be achieved by creating a FlutterEventChannel counterpart of this channel on
/// the platform side. The Dart type of events sent and received is `dynamic`,
/// but only values supported by the specified [MethodCodec] can be used.
///
/// The identity of the channel is given by its name, so other uses of that name
/// with may interfere with this channel's communication.
///
/// See: <https://flutter.io/platform-channels/>
class
PlatformEventChannel
{
/// Creates a [PlatformEventChannel] with the specified [name].
///
/// The [codec] used will be [StandardMethodCodec], unless otherwise
/// specified.
///
/// Neither [name] nor [codec] may be `null`.
const
PlatformEventChannel
(
this
.
name
,
[
this
.
codec
=
const
StandardMethodCodec
()]);
/// The logical channel on which communication happens, not `null`.
final
String
name
;
/// The message codec used by this channel, not `null`.
final
MethodCodec
codec
;
/// Sets up a broadcast stream for receiving events on this channel.
/// Sets up a broadcast stream for receiving events on this channel.
///
///
...
@@ -206,15 +265,15 @@ class PlatformMethodChannel {
...
@@ -206,15 +265,15 @@ class PlatformMethodChannel {
/// received from the platform plugin;
/// received from the platform plugin;
/// * an error event containing a [FormatException] for each event received
/// * an error event containing a [FormatException] for each event received
/// where decoding fails;
/// where decoding fails;
/// * an error event containing a [PlatformException]
or [FormatException]
/// * an error event containing a [PlatformException]
,
///
whenever stream setup fails (stream setup is done only when listener
///
[MissingPluginException], or [FormatException] whenever stream setup fails
/// count changes from 0 to 1).
///
(stream setup is done only when listener
count changes from 0 to 1).
///
///
/// Notes for platform plugin implementers:
/// Notes for platform plugin implementers:
///
///
/// Plugins must expose methods named `listen` and `cancel` suitable for
/// Plugins must expose methods named `listen` and `cancel` suitable for
/// invocations by [
invokeMethod]. Both methods are invoked with the specified
/// invocations by [
PlatformMethodChannel.invokeMethod]. Both methods are
/// [arguments].
///
invoked with the specified
[arguments].
///
///
/// Following the semantics of broadcast streams, `listen` will be called as
/// Following the semantics of broadcast streams, `listen` will be called as
/// the first listener registers with the returned stream, and `cancel` when
/// the first listener registers with the returned stream, and `cancel` when
...
@@ -222,6 +281,7 @@ class PlatformMethodChannel {
...
@@ -222,6 +281,7 @@ class PlatformMethodChannel {
/// indefinitely. Platform plugins should consume no stream-related resources
/// indefinitely. Platform plugins should consume no stream-related resources
/// while listener count is zero.
/// while listener count is zero.
Stream
<
dynamic
>
receiveBroadcastStream
([
dynamic
arguments
])
{
Stream
<
dynamic
>
receiveBroadcastStream
([
dynamic
arguments
])
{
final
PlatformMethodChannel
methodChannel
=
new
PlatformMethodChannel
(
name
,
codec
);
StreamController
<
dynamic
>
controller
;
StreamController
<
dynamic
>
controller
;
controller
=
new
StreamController
<
dynamic
>.
broadcast
(
controller
=
new
StreamController
<
dynamic
>.
broadcast
(
onListen:
()
async
{
onListen:
()
async
{
...
@@ -239,7 +299,7 @@ class PlatformMethodChannel {
...
@@ -239,7 +299,7 @@ class PlatformMethodChannel {
}
}
);
);
try
{
try
{
await
invokeMethod
(
'listen'
,
arguments
);
await
methodChannel
.
invokeMethod
(
'listen'
,
arguments
);
}
catch
(
e
)
{
}
catch
(
e
)
{
PlatformMessages
.
setBinaryMessageHandler
(
name
,
null
);
PlatformMessages
.
setBinaryMessageHandler
(
name
,
null
);
controller
.
addError
(
e
);
controller
.
addError
(
e
);
...
@@ -247,7 +307,7 @@ class PlatformMethodChannel {
...
@@ -247,7 +307,7 @@ class PlatformMethodChannel {
},
onCancel:
()
async
{
},
onCancel:
()
async
{
PlatformMessages
.
setBinaryMessageHandler
(
name
,
null
);
PlatformMessages
.
setBinaryMessageHandler
(
name
,
null
);
try
{
try
{
await
invokeMethod
(
'cancel'
,
arguments
);
await
methodChannel
.
invokeMethod
(
'cancel'
,
arguments
);
}
catch
(
exception
,
stack
)
{
}
catch
(
exception
,
stack
)
{
FlutterError
.
reportError
(
new
FlutterErrorDetails
(
FlutterError
.
reportError
(
new
FlutterErrorDetails
(
exception:
exception
,
exception:
exception
,
...
@@ -261,22 +321,3 @@ class PlatformMethodChannel {
...
@@ -261,22 +321,3 @@ class PlatformMethodChannel {
return
controller
.
stream
;
return
controller
.
stream
;
}
}
}
}
/// A [PlatformMethodChannel] that ignores missing platform plugins.
///
/// When [invokeMethod] fails to find the platform plugin, it returns null
/// instead of throwing an exception.
class
OptionalPlatformMethodChannel
extends
PlatformMethodChannel
{
/// Creates a [PlatformMethodChannel] that ignores missing platform plugins.
const
OptionalPlatformMethodChannel
(
String
name
,
[
MethodCodec
codec
=
const
StandardMethodCodec
()])
:
super
(
name
,
codec
);
@override
Future
<
dynamic
>
invokeMethod
(
String
method
,
[
dynamic
arguments
])
async
{
try
{
return
await
super
.
invokeMethod
(
method
,
arguments
);
}
on
MissingPluginException
{
return
null
;
}
}
}
packages/flutter/lib/src/services/text_input.dart
View file @
471c97df
...
@@ -261,6 +261,8 @@ class _TextInputClientHandler {
...
@@ -261,6 +261,8 @@ class _TextInputClientHandler {
case
'TextInputClient.performAction'
:
case
'TextInputClient.performAction'
:
_currentConnection
.
_client
.
performAction
(
_toTextInputAction
(
args
[
1
]));
_currentConnection
.
_client
.
performAction
(
_toTextInputAction
(
args
[
1
]));
break
;
break
;
default
:
throw
new
MissingPluginException
();
}
}
}
}
...
...
packages/flutter/test/services/platform_channel_test.dart
View file @
471c97df
...
@@ -37,10 +37,10 @@ void main() {
...
@@ -37,10 +37,10 @@ void main() {
group
(
'PlatformMethodChannel'
,
()
{
group
(
'PlatformMethodChannel'
,
()
{
const
MessageCodec
<
dynamic
>
jsonMessage
=
const
JSONMessageCodec
();
const
MessageCodec
<
dynamic
>
jsonMessage
=
const
JSONMessageCodec
();
const
MethodCodec
jsonMethod
=
const
JSONMethodCodec
();
const
MethodCodec
jsonMethod
=
const
JSONMethodCodec
();
const
PlatformMethodChannel
channel
=
const
PlatformMethodChannel
(
'ch'
,
jsonMethod
);
const
PlatformMethodChannel
channel
=
const
PlatformMethodChannel
(
'ch
7
'
,
jsonMethod
);
test
(
'can invoke method and get result'
,
()
async
{
test
(
'can invoke method and get result'
,
()
async
{
PlatformMessages
.
setMockBinaryMessageHandler
(
PlatformMessages
.
setMockBinaryMessageHandler
(
'ch'
,
'ch
7
'
,
(
ByteData
message
)
async
{
(
ByteData
message
)
async
{
final
Map
<
dynamic
,
dynamic
>
methodCall
=
jsonMessage
.
decodeMessage
(
message
);
final
Map
<
dynamic
,
dynamic
>
methodCall
=
jsonMessage
.
decodeMessage
(
message
);
if
(
methodCall
[
'method'
]
==
'sayHello'
)
if
(
methodCall
[
'method'
]
==
'sayHello'
)
...
@@ -54,11 +54,11 @@ void main() {
...
@@ -54,11 +54,11 @@ void main() {
});
});
test
(
'can invoke method and get error'
,
()
async
{
test
(
'can invoke method and get error'
,
()
async
{
PlatformMessages
.
setMockBinaryMessageHandler
(
PlatformMessages
.
setMockBinaryMessageHandler
(
'ch'
,
'ch
7
'
,
(
ByteData
message
)
async
{
(
ByteData
message
)
async
{
return
jsonMessage
.
encodeMessage
(<
dynamic
>[
return
jsonMessage
.
encodeMessage
(<
dynamic
>[
'
unknown
'
,
'
bad
'
,
'
Method not understoo
d'
,
'
Something happene
d'
,
<
String
,
dynamic
>{
'a'
:
42
,
'b'
:
3.14
},
<
String
,
dynamic
>{
'a'
:
42
,
'b'
:
3.14
},
]);
]);
},
},
...
@@ -67,11 +67,33 @@ void main() {
...
@@ -67,11 +67,33 @@ void main() {
await
channel
.
invokeMethod
(
'sayHello'
,
'hello'
);
await
channel
.
invokeMethod
(
'sayHello'
,
'hello'
);
fail
(
'Exception expected'
);
fail
(
'Exception expected'
);
}
on
PlatformException
catch
(
e
)
{
}
on
PlatformException
catch
(
e
)
{
expect
(
e
.
code
,
equals
(
'
unknown
'
));
expect
(
e
.
code
,
equals
(
'
bad
'
));
expect
(
e
.
message
,
equals
(
'
Method not understoo
d'
));
expect
(
e
.
message
,
equals
(
'
Something happene
d'
));
expect
(
e
.
details
,
equals
(<
String
,
dynamic
>{
'a'
:
42
,
'b'
:
3.14
}));
expect
(
e
.
details
,
equals
(<
String
,
dynamic
>{
'a'
:
42
,
'b'
:
3.14
}));
}
catch
(
e
)
{
fail
(
'PlatformException expected'
);
}
});
test
(
'can invoke unimplemented method'
,
()
async
{
PlatformMessages
.
setMockBinaryMessageHandler
(
'ch7'
,
(
ByteData
message
)
async
=>
null
,
);
try
{
await
channel
.
invokeMethod
(
'sayHello'
,
'hello'
);
fail
(
'Exception expected'
);
}
on
MissingPluginException
catch
(
e
)
{
expect
(
e
.
message
,
contains
(
'sayHello'
));
expect
(
e
.
message
,
contains
(
'ch7'
));
}
catch
(
e
)
{
fail
(
'MissingPluginException expected'
);
}
}
});
});
});
group
(
'PlatformEventChannel'
,
()
{
const
MessageCodec
<
dynamic
>
jsonMessage
=
const
JSONMessageCodec
();
const
MethodCodec
jsonMethod
=
const
JSONMethodCodec
();
const
PlatformEventChannel
channel
=
const
PlatformEventChannel
(
'ch'
,
jsonMethod
);
test
(
'can receive event stream'
,
()
async
{
test
(
'can receive event stream'
,
()
async
{
void
emitEvent
(
dynamic
event
)
{
void
emitEvent
(
dynamic
event
)
{
PlatformMessages
.
handlePlatformMessage
(
PlatformMessages
.
handlePlatformMessage
(
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment