Skip to content

Commit

Permalink
Flutter channels for iOS (flutter#3470)
Browse files Browse the repository at this point in the history
Flutter channels now also supported on iOS. Use FlutterMessageChannel or FlutterMethodChannel with binary/string/json/standard codecs.
  • Loading branch information
mravn-google authored Mar 13, 2017
1 parent 65fcbf7 commit b97103b
Show file tree
Hide file tree
Showing 25 changed files with 1,431 additions and 150 deletions.
5 changes: 5 additions & 0 deletions BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,11 @@ group("flutter") {

# If on the host, compile all unittests targets.
if (current_toolchain == host_toolchain) {
if (is_mac) {
deps += [
"//flutter/shell/platform/darwin:flutter_channels_unittests",
]
}
deps += [
"//flutter/sky/engine/wtf:wtf_unittests",
"//flutter/synchronization:synchronization_unittests",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import java.io.ByteArrayOutputStream;
import java.math.BigInteger;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.HashMap;
Expand Down Expand Up @@ -58,13 +59,15 @@ public Object decodeMessage(ByteBuffer message) {
if (message == null || !message.hasRemaining()) {
return null;
}
message.order(ByteOrder.nativeOrder());
final Object value = readValue(message);
if (message.hasRemaining()) {
throw new IllegalArgumentException("Message corrupted");
}
return value;
}

private static final boolean LITTLE_ENDIAN = ByteOrder.nativeOrder() == ByteOrder.LITTLE_ENDIAN;
private static final Charset UTF8 = Charset.forName("UTF8");
private static final byte NULL = 0;
private static final byte TRUE = 1;
Expand All @@ -87,30 +90,57 @@ private static void writeSize(ByteArrayOutputStream stream, int value) {
stream.write(value);
} else if (value <= 0xffff) {
stream.write(254);
stream.write(value >>> 8);
stream.write(value);
writeChar(stream, value);
} else {
stream.write(255);
writeInt(stream, value);
}
}

private static void writeChar(ByteArrayOutputStream stream, int value) {
if (LITTLE_ENDIAN) {
stream.write(value);
stream.write(value >>> 8);
} else {
stream.write(value >>> 8);
stream.write(value);
}
}

private static void writeInt(ByteArrayOutputStream stream, int value) {
stream.write(value >>> 24);
stream.write(value >>> 16);
stream.write(value >>> 8);
stream.write(value);
if (LITTLE_ENDIAN) {
stream.write(value);
stream.write(value >>> 8);
stream.write(value >>> 16);
stream.write(value >>> 24);
} else {
stream.write(value >>> 24);
stream.write(value >>> 16);
stream.write(value >>> 8);
stream.write(value);
}
}

private static void writeLong(ByteArrayOutputStream stream, long value) {
stream.write((byte) (value >>> 56));
stream.write((byte) (value >>> 48));
stream.write((byte) (value >>> 40));
stream.write((byte) (value >>> 32));
stream.write((byte) (value >>> 24));
stream.write((byte) (value >>> 16));
stream.write((byte) (value >>> 8));
stream.write((byte) value);
if (LITTLE_ENDIAN) {
stream.write((byte) value);
stream.write((byte) (value >>> 8));
stream.write((byte) (value >>> 16));
stream.write((byte) (value >>> 24));
stream.write((byte) (value >>> 32));
stream.write((byte) (value >>> 40));
stream.write((byte) (value >>> 48));
stream.write((byte) (value >>> 56));
} else {
stream.write((byte) (value >>> 56));
stream.write((byte) (value >>> 48));
stream.write((byte) (value >>> 40));
stream.write((byte) (value >>> 32));
stream.write((byte) (value >>> 24));
stream.write((byte) (value >>> 16));
stream.write((byte) (value >>> 8));
stream.write((byte) value);
}
}

private static void writeDouble(ByteArrayOutputStream stream, double value) {
Expand Down Expand Up @@ -213,13 +243,9 @@ private static int readSize(ByteBuffer buffer) {
if (value < 254) {
return value;
} else if (value == 254) {
return ((buffer.get() & 0xff) << 8)
| ((buffer.get() & 0xff));
return buffer.getChar();
} else {
return ((buffer.get() & 0xff) << 24)
| ((buffer.get() & 0xff) << 16)
| ((buffer.get() & 0xff) << 8)
| ((buffer.get() & 0xff));
return buffer.getInt();
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

import io.flutter.plugin.common.StandardMessageCodec.ExposedByteArrayOutputStream;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;

/**
* A {@link MethodCodec} using the Flutter standard binary encoding.
Expand All @@ -26,6 +27,7 @@ private StandardMethodCodec() {

@Override
public MethodCall decodeMethodCall(ByteBuffer methodCall) {
methodCall.order(ByteOrder.nativeOrder());
final Object method = StandardMessageCodec.readValue(methodCall);
final Object arguments = StandardMessageCodec.readValue(methodCall);
if (method instanceof String) {
Expand Down
49 changes: 49 additions & 0 deletions shell/platform/darwin/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,52 @@ group("darwin") {
assert(false, "Unknown darwin platform type.")
}
}

source_set("flutter_channels") {
set_sources_assignment_filter([])
sources = [
"ios/framework/Headers/FlutterBinaryMessenger.h",
"ios/framework/Headers/FlutterChannels.h",
"ios/framework/Headers/FlutterCodecs.h",
"ios/framework/Source/FlutterChannels.mm",
"ios/framework/Source/FlutterCodecs.mm",
"ios/framework/Source/FlutterStandardCodec_Internal.h",
"ios/framework/Source/FlutterStandardCodec.mm",
"common/buffer_conversions.h",
"common/buffer_conversions.mm",
]
set_sources_assignment_filter(sources_assignment_filter)

deps = [
"//base",
"//base:i18n",
"//dart/runtime:libdart",
"//flutter/common",
"//flutter/flow",
"//flutter/fml",
"//flutter/runtime",
"//flutter/shell/common",
"//flutter/shell/gpu",
"//flutter/shell/testing",
"//flutter/sky/engine/wtf",
"//lib/ftl",
"//third_party/skia",
]
}


executable("flutter_channels_unittests") {
testonly = true

set_sources_assignment_filter([])
sources = [
"ios/framework/Source/flutter_codecs_unittest.mm",
"ios/framework/Source/flutter_standard_codec_unittest.mm",
]
set_sources_assignment_filter(sources_assignment_filter)

deps = [
":flutter_channels",
"//flutter/testing",
]
}
4 changes: 2 additions & 2 deletions shell/platform/darwin/common/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ source_set("common") {
"platform_mac.mm",
"process_info_mac.cc",
"process_info_mac.h",
"string_conversions.h",
"string_conversions.mm",
"buffer_conversions.h",
"buffer_conversions.mm",
]
set_sources_assignment_filter(sources_assignment_filter)

Expand Down
20 changes: 20 additions & 0 deletions shell/platform/darwin/common/buffer_conversions.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef FLUTTER_SHELL_PLATFORM_DARWIN_COMMON_BUFFER_CONVERSIONS_H_
#define FLUTTER_SHELL_PLATFORM_DARWIN_COMMON_BUFFER_CONVERSIONS_H_

#include <Foundation/Foundation.h>

#include <vector>

namespace shell {

std::vector<uint8_t> GetVectorFromNSData(NSData* data);

NSData* GetNSDataFromVector(const std::vector<uint8_t>& buffer);

} // namespace shell

#endif // FLUTTER_SHELL_PLATFORM_DARWIN_COMMON_BUFFER_CONVERSIONS_H_
20 changes: 20 additions & 0 deletions shell/platform/darwin/common/buffer_conversions.mm
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "flutter/shell/platform/darwin/common/buffer_conversions.h"

namespace shell {

std::vector<uint8_t> GetVectorFromNSData(NSData* data) {
if (!data.length)
return std::vector<uint8_t>();
const uint8_t* bytes = reinterpret_cast<const uint8_t*>(data.bytes);
return std::vector<uint8_t>(bytes, bytes + data.length);
}

NSData* GetNSDataFromVector(const std::vector<uint8_t>& buffer) {
return [NSData dataWithBytes:buffer.data() length:buffer.size()];
}

} // namespace shell
20 changes: 0 additions & 20 deletions shell/platform/darwin/common/string_conversions.h

This file was deleted.

25 changes: 0 additions & 25 deletions shell/platform/darwin/common/string_conversions.mm

This file was deleted.

10 changes: 10 additions & 0 deletions shell/platform/darwin/ios/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -18,19 +18,26 @@ shared_library("flutter_framework_dylib") {
"framework/Headers/Flutter.h",
"framework/Headers/FlutterAppDelegate.h",
"framework/Headers/FlutterAsyncMessageListener.h",
"framework/Headers/FlutterChannels.h",
"framework/Headers/FlutterCodecs.h",
"framework/Headers/FlutterBinaryMessenger.h",
"framework/Headers/FlutterDartProject.h",
"framework/Headers/FlutterJSONMessageListener.h",
"framework/Headers/FlutterMacros.h",
"framework/Headers/FlutterMessageListener.h",
"framework/Headers/FlutterViewController.h",
"framework/Source/FlutterAppDelegate.mm",
"framework/Source/FlutterChannels.mm",
"framework/Source/FlutterCodecs.mm",
"framework/Source/FlutterDartProject.mm",
"framework/Source/FlutterDartProject_Internal.h",
"framework/Source/FlutterDartSource.h",
"framework/Source/FlutterDartSource.mm",
"framework/Source/FlutterJSONMessageListener.mm",
"framework/Source/FlutterPlatformPlugin.h",
"framework/Source/FlutterPlatformPlugin.mm",
"framework/Source/FlutterStandardCodec_Internal.h",
"framework/Source/FlutterStandardCodec.mm",
"framework/Source/FlutterTextInputDelegate.h",
"framework/Source/FlutterTextInputPlugin.h",
"framework/Source/FlutterTextInputPlugin.mm",
Expand Down Expand Up @@ -152,6 +159,9 @@ copy("framework_headers") {
"framework/Headers/Flutter.h",
"framework/Headers/FlutterAppDelegate.h",
"framework/Headers/FlutterAsyncMessageListener.h",
"framework/Headers/FlutterBinaryMessenger.h",
"framework/Headers/FlutterChannels.h",
"framework/Headers/FlutterCodecs.h",
"framework/Headers/FlutterDartProject.h",
"framework/Headers/FlutterJSONMessageListener.h",
"framework/Headers/FlutterMacros.h",
Expand Down
3 changes: 3 additions & 0 deletions shell/platform/darwin/ios/framework/Headers/Flutter.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@

#include "FlutterAppDelegate.h"
#include "FlutterAsyncMessageListener.h"
#include "FlutterBinaryMessenger.h"
#include "FlutterChannels.h"
#include "FlutterCodecs.h"
#include "FlutterDartProject.h"
#include "FlutterJSONMessageListener.h"
#include "FlutterMacros.h"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef FLUTTER_FLUTTERBINARYMESSAGES_H_
#define FLUTTER_FLUTTERBINARYMESSAGES_H_

#import <Foundation/Foundation.h>

#include "FlutterMacros.h"

typedef void (^FlutterBinaryReplyHandler)(NSData* reply);
typedef void (^FlutterBinaryMessageHandler)(
NSData* message,
FlutterBinaryReplyHandler replyHandler);

FLUTTER_EXPORT
@protocol FlutterBinaryMessenger<NSObject>
- (void)sendBinaryMessage:(NSData*)message channelName:(NSString*)channelName;

- (void)sendBinaryMessage:(NSData*)message
channelName:(NSString*)channelName
binaryReplyHandler:(FlutterBinaryReplyHandler)handler;

- (void)setBinaryMessageHandlerOnChannel:(NSString*)channelName
binaryMessageHandler:(FlutterBinaryMessageHandler)handler;
@end

#endif // FLUTTER_FLUTTERBINARYMESSAGES_H_
Loading

0 comments on commit b97103b

Please sign in to comment.