Commit ef43d000 authored by Adam Barth's avatar Adam Barth Committed by GitHub

Ignore some missing plugins. (#8852)

Fixes #8850
parent 9f770ec8
...@@ -166,3 +166,9 @@ class PlatformException implements Exception { ...@@ -166,3 +166,9 @@ class PlatformException implements Exception {
@override @override
String toString() => 'PlatformException($code, $message, $details)'; String toString() => 'PlatformException($code, $message, $details)';
} }
/// Thrown to indicate that a platform interaction failed to find the plugin.
class MissingPluginException implements Exception {
@override
String toString() => 'MissingPluginException';
}
...@@ -121,6 +121,8 @@ class JSONMethodCodec implements MethodCodec { ...@@ -121,6 +121,8 @@ 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');
...@@ -460,8 +462,10 @@ class StandardMethodCodec implements MethodCodec { ...@@ -460,8 +462,10 @@ 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 == null || envelope.lengthInBytes == 0) if (envelope.lengthInBytes == 0)
throw const FormatException('Expected envelope, got nothing'); throw const FormatException('Expected envelope, got nothing');
final ReadBuffer buffer = new ReadBuffer(envelope); final ReadBuffer buffer = new ReadBuffer(envelope);
if (buffer.getUint8() == 0) if (buffer.getUint8() == 0)
......
...@@ -261,3 +261,22 @@ class PlatformMethodChannel { ...@@ -261,3 +261,22 @@ 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;
}
}
}
...@@ -16,13 +16,17 @@ class SystemChannels { ...@@ -16,13 +16,17 @@ class SystemChannels {
); );
/// A JSON [PlatformMethodChannel] for invoking miscellaneous platform methods. /// A JSON [PlatformMethodChannel] for invoking miscellaneous platform methods.
static const PlatformMethodChannel platform = const PlatformMethodChannel( ///
/// Ignores missing plugins.
static const PlatformMethodChannel platform = const OptionalPlatformMethodChannel(
'flutter/platform', 'flutter/platform',
const JSONMethodCodec(), const JSONMethodCodec(),
); );
/// A JSON [PlatformMethodChannel] for handling text input. /// A JSON [PlatformMethodChannel] for handling text input.
static const PlatformMethodChannel textInput = const PlatformMethodChannel( ///
/// Ignores missing plugins.
static const PlatformMethodChannel textInput = const OptionalPlatformMethodChannel(
'flutter/textinput', 'flutter/textinput',
const JSONMethodCodec(), const JSONMethodCodec(),
); );
......
...@@ -2,6 +2,8 @@ ...@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
import 'dart:typed_data';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
...@@ -54,6 +56,21 @@ void main() { ...@@ -54,6 +56,21 @@ void main() {
)])); )]));
}); });
test('setApplicationSwitcherDescription missing plugin', () async {
final List<ByteData> log = <ByteData>[];
PlatformMessages.setMockBinaryMessageHandler('flutter/platform', (ByteData message) {
log.add(message);
return null;
});
await SystemChrome.setApplicationSwitcherDescription(
const ApplicationSwitcherDescription(label: 'Example label', primaryColor: 0xFF00FF00)
);
expect(log, isNotEmpty);
});
test('setEnabledSystemUIOverlays control test', () async { test('setEnabledSystemUIOverlays control test', () async {
final List<MethodCall> log = <MethodCall>[]; final List<MethodCall> log = <MethodCall>[];
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment