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

Ignore some missing plugins. (#8852)

Fixes #8850
parent 9f770ec8
......@@ -42,7 +42,7 @@ class MethodCall {
///
/// Must be a valid value for the [MethodCodec] used.
final dynamic arguments;
@override
bool operator== (dynamic other) {
if (identical(this, other))
......@@ -64,7 +64,7 @@ class MethodCall {
return b is Map && _deepEqualsMap(a, b);
return false;
}
bool _deepEqualsList(List<dynamic> a, List<dynamic> b) {
if (a.length != b.length)
return false;
......@@ -84,7 +84,7 @@ class MethodCall {
}
return true;
}
@override
String toString() => '$runtimeType($method, $arguments)';
}
......@@ -120,7 +120,7 @@ abstract class MethodCodec {
/// Encodes a successful [result] into a binary envelope.
ByteData encodeSuccessEnvelope(dynamic result);
/// Encodes an error result into a binary envelope.
///
/// The specified error [code], human-readable error [message], and error
......@@ -166,3 +166,9 @@ class PlatformException implements Exception {
@override
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 {
@override
dynamic decodeEnvelope(ByteData envelope) {
if (envelope == null)
throw new MissingPluginException();
final dynamic decoded = const JSONMessageCodec().decodeMessage(envelope);
if (decoded is! List)
throw new FormatException('Expected envelope List, got $decoded');
......@@ -460,8 +462,10 @@ class StandardMethodCodec implements MethodCodec {
@override
dynamic decodeEnvelope(ByteData envelope) {
if (envelope == null)
throw new MissingPluginException();
// 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');
final ReadBuffer buffer = new ReadBuffer(envelope);
if (buffer.getUint8() == 0)
......
......@@ -261,3 +261,22 @@ class PlatformMethodChannel {
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 {
);
/// 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',
const JSONMethodCodec(),
);
/// A JSON [PlatformMethodChannel] for handling text input.
static const PlatformMethodChannel textInput = const PlatformMethodChannel(
///
/// Ignores missing plugins.
static const PlatformMethodChannel textInput = const OptionalPlatformMethodChannel(
'flutter/textinput',
const JSONMethodCodec(),
);
......
......@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'dart:typed_data';
import 'package:flutter/services.dart';
import 'package:flutter_test/flutter_test.dart';
......@@ -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 {
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