Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reland "Migrate darwin common "framework_shared" target to ARC #37049" #37883

Merged
merged 1 commit into from
Dec 15, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 20 additions & 7 deletions shell/platform/darwin/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,20 @@ source_set("flutter_channels") {
sources = [
"common/buffer_conversions.h",
"common/buffer_conversions.mm",
]

deps = [ "//flutter/fml" ]

public_deps = [ ":flutter_channels_arc" ]

public_configs = [ "//flutter:config" ]
}

source_set("flutter_channels_arc") {
cflags_objc = flutter_cflags_objc_arc
cflags_objcc = flutter_cflags_objcc_arc

sources = [
"common/framework/Headers/FlutterBinaryMessenger.h",
"common/framework/Headers/FlutterChannels.h",
"common/framework/Headers/FlutterCodecs.h",
Expand All @@ -36,13 +50,12 @@ source_set("flutter_channels") {
"common/framework/Source/FlutterStandardCodec_Internal.h",
]

deps = [
"//flutter/common",
"//flutter/flow",
"//flutter/fml",
"//flutter/runtime",
"//flutter/shell/common",
"//third_party/skia",
public = [
"common/framework/Headers/FlutterBinaryMessenger.h",
"common/framework/Headers/FlutterChannels.h",
"common/framework/Headers/FlutterCodecs.h",
"common/framework/Headers/FlutterMacros.h",
"common/framework/Source/FlutterStandardCodec_Internal.h",
]

public_configs = [ "//flutter:config" ]
Expand Down
14 changes: 3 additions & 11 deletions shell/platform/darwin/common/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,7 @@ source_set("common") {
"command_line.mm",
]

deps = [
"//flutter/common",
"//flutter/flow",
"//flutter/fml",
"//flutter/runtime",
"//flutter/shell/common",
"//third_party/dart/runtime:dart_api",
"//third_party/skia",
]
deps = [ "//flutter/fml" ]

public_configs = [ "//flutter:config" ]
}
Expand All @@ -38,8 +30,8 @@ config("framework_relative_headers") {

# Framework code shared between iOS and macOS.
source_set("framework_shared") {
cflags_objc = flutter_cflags_objc
cflags_objcc = flutter_cflags_objcc
cflags_objc = flutter_cflags_objc_arc
cflags_objcc = flutter_cflags_objcc_arc

sources = [
"framework/Source/FlutterChannels.mm",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -344,17 +344,17 @@ FLUTTER_DARWIN_EXPORT
/**
* The type of the encoded values.
*/
@property(readonly, nonatomic) FlutterStandardDataType type;
@property(readonly, nonatomic, assign) FlutterStandardDataType type;

/**
* The number of value items encoded.
*/
@property(readonly, nonatomic) UInt32 elementCount;
@property(readonly, nonatomic, assign) UInt32 elementCount;

/**
* The number of bytes used by the encoding of a single value item.
*/
@property(readonly, nonatomic) UInt8 elementSize;
@property(readonly, nonatomic, assign) UInt8 elementSize;
@end

/**
Expand Down
94 changes: 31 additions & 63 deletions shell/platform/darwin/common/framework/Source/FlutterChannels.mm
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

#import "flutter/shell/platform/darwin/common/framework/Headers/FlutterChannels.h"

FLUTTER_ASSERT_ARC

#pragma mark - Basic message channel

static NSString* const kFlutterChannelBuffersChannel = @"dev.flutter/channel-buffers";
Expand Down Expand Up @@ -51,9 +53,9 @@ + (instancetype)messageChannelWithName:(NSString*)name
+ (instancetype)messageChannelWithName:(NSString*)name
binaryMessenger:(NSObject<FlutterBinaryMessenger>*)messenger
codec:(NSObject<FlutterMessageCodec>*)codec {
return [[[FlutterBasicMessageChannel alloc] initWithName:name
binaryMessenger:messenger
codec:codec] autorelease];
return [[FlutterBasicMessageChannel alloc] initWithName:name
binaryMessenger:messenger
codec:codec];
}

- (instancetype)initWithName:(NSString*)name
Expand All @@ -69,21 +71,13 @@ - (instancetype)initWithName:(NSString*)name
taskQueue:(NSObject<FlutterTaskQueue>*)taskQueue {
self = [super init];
NSAssert(self, @"Super init cannot be nil");
_name = [name retain];
_messenger = [messenger retain];
_codec = [codec retain];
_taskQueue = [taskQueue retain];
_name = [name copy];
_messenger = messenger;
_codec = codec;
_taskQueue = taskQueue;
return self;
}

- (void)dealloc {
[_name release];
[_messenger release];
[_codec release];
[_taskQueue release];
[super dealloc];
}

- (void)sendMessage:(id)message {
[_messenger sendOnChannel:_name message:[_codec encode:message]];
}
Expand All @@ -107,7 +101,10 @@ - (void)setMessageHandler:(FlutterMessageHandler)handler {
}
return;
}

// Grab reference to avoid retain on self.
// `self` might be released before the block, so the block needs to retain the codec to
// make sure it is not released with `self`
NSObject<FlutterMessageCodec>* codec = _codec;
FlutterBinaryMessageHandler messageHandler = ^(NSData* message, FlutterBinaryReply callback) {
handler([codec decode:message], ^(id reply) {
Expand All @@ -128,26 +125,19 @@ - (void)resizeChannelBuffer:(NSInteger)newSize {
////////////////////////////////////////////////////////////////////////////////
@implementation FlutterError
+ (instancetype)errorWithCode:(NSString*)code message:(NSString*)message details:(id)details {
return [[[FlutterError alloc] initWithCode:code message:message details:details] autorelease];
return [[FlutterError alloc] initWithCode:code message:message details:details];
}

- (instancetype)initWithCode:(NSString*)code message:(NSString*)message details:(id)details {
NSAssert(code, @"Code cannot be nil");
self = [super init];
NSAssert(self, @"Super init cannot be nil");
_code = [code retain];
_message = [message retain];
_details = [details retain];
_code = [code copy];
_message = [message copy];
_details = details;
return self;
}

- (void)dealloc {
[_code release];
[_message release];
[_details release];
[super dealloc];
}

- (BOOL)isEqual:(id)object {
if (self == object) {
return YES;
Expand All @@ -169,24 +159,18 @@ - (NSUInteger)hash {
////////////////////////////////////////////////////////////////////////////////
@implementation FlutterMethodCall
+ (instancetype)methodCallWithMethodName:(NSString*)method arguments:(id)arguments {
return [[[FlutterMethodCall alloc] initWithMethodName:method arguments:arguments] autorelease];
return [[FlutterMethodCall alloc] initWithMethodName:method arguments:arguments];
}

- (instancetype)initWithMethodName:(NSString*)method arguments:(id)arguments {
NSAssert(method, @"Method name cannot be nil");
self = [super init];
NSAssert(self, @"Super init cannot be nil");
_method = [method retain];
_arguments = [arguments retain];
_method = [method copy];
_arguments = arguments;
return self;
}

- (void)dealloc {
[_method release];
[_arguments release];
[super dealloc];
}

- (BOOL)isEqual:(id)object {
if (self == object) {
return YES;
Expand Down Expand Up @@ -224,8 +208,7 @@ + (instancetype)methodChannelWithName:(NSString*)name
+ (instancetype)methodChannelWithName:(NSString*)name
binaryMessenger:(NSObject<FlutterBinaryMessenger>*)messenger
codec:(NSObject<FlutterMethodCodec>*)codec {
return [[[FlutterMethodChannel alloc] initWithName:name binaryMessenger:messenger
codec:codec] autorelease];
return [[FlutterMethodChannel alloc] initWithName:name binaryMessenger:messenger codec:codec];
}

- (instancetype)initWithName:(NSString*)name
Expand All @@ -240,21 +223,13 @@ - (instancetype)initWithName:(NSString*)name
taskQueue:(NSObject<FlutterTaskQueue>*)taskQueue {
self = [super init];
NSAssert(self, @"Super init cannot be nil");
_name = [name retain];
_messenger = [messenger retain];
_codec = [codec retain];
_taskQueue = [taskQueue retain];
_name = [name copy];
_messenger = messenger;
_codec = codec;
_taskQueue = taskQueue;
return self;
}

- (void)dealloc {
[_name release];
[_messenger release];
[_codec release];
[_taskQueue release];
[super dealloc];
}

- (void)invokeMethod:(NSString*)method arguments:(id)arguments {
FlutterMethodCall* methodCall = [FlutterMethodCall methodCallWithMethodName:method
arguments:arguments];
Expand Down Expand Up @@ -285,6 +260,8 @@ - (void)setMethodCallHandler:(FlutterMethodCallHandler)handler {
return;
}
// Make sure the block captures the codec, not self.
// `self` might be released before the block, so the block needs to retain the codec to
// make sure it is not released with `self`
NSObject<FlutterMethodCodec>* codec = _codec;
FlutterBinaryMessageHandler messageHandler = ^(NSData* message, FlutterBinaryReply callback) {
FlutterMethodCall* call = [codec decodeMethodCall:message];
Expand Down Expand Up @@ -328,8 +305,7 @@ + (instancetype)eventChannelWithName:(NSString*)name
+ (instancetype)eventChannelWithName:(NSString*)name
binaryMessenger:(NSObject<FlutterBinaryMessenger>*)messenger
codec:(NSObject<FlutterMethodCodec>*)codec {
return [[[FlutterEventChannel alloc] initWithName:name binaryMessenger:messenger
codec:codec] autorelease];
return [[FlutterEventChannel alloc] initWithName:name binaryMessenger:messenger codec:codec];
}

- (instancetype)initWithName:(NSString*)name
Expand All @@ -344,21 +320,13 @@ - (instancetype)initWithName:(NSString*)name
taskQueue:(NSObject<FlutterTaskQueue>* _Nullable)taskQueue {
self = [super init];
NSAssert(self, @"Super init cannot be nil");
_name = [name retain];
_messenger = [messenger retain];
_codec = [codec retain];
_taskQueue = [taskQueue retain];
_name = [name copy];
_messenger = messenger;
_codec = codec;
_taskQueue = taskQueue;
return self;
}

- (void)dealloc {
[_name release];
[_codec release];
[_messenger release];
[_taskQueue release];
[super dealloc];
}

static FlutterBinaryMessengerConnection SetStreamHandlerMessageHandlerOnChannel(
NSObject<FlutterStreamHandler>* handler,
NSString* name,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,78 @@ - (void)testBasicMessageChannelTaskQueue {
OCMVerify([binaryMessenger cleanUpConnection:connection]);
}

- (void)testBasicMessageChannelInvokeHandlerAfterChannelReleased {
NSString* channelName = @"foo";
__block NSString* handlerMessage;
__block FlutterBinaryMessageHandler messageHandler;
@autoreleasepool {
FlutterBinaryMessengerConnection connection = 123;
id binaryMessenger = OCMProtocolMock(@protocol(FlutterBinaryMessenger));
id codec = OCMProtocolMock(@protocol(FlutterMessageCodec));
id taskQueue = OCMClassMock([NSObject class]);
FlutterBasicMessageChannel* channel =
[[FlutterBasicMessageChannel alloc] initWithName:channelName
binaryMessenger:binaryMessenger
codec:codec
taskQueue:taskQueue];

FlutterMessageHandler handler = ^(id _Nullable message, FlutterReply callback) {
handlerMessage = message;
};
OCMStub([binaryMessenger
setMessageHandlerOnChannel:channelName
binaryMessageHandler:[OCMArg checkWithBlock:^BOOL(
FlutterBinaryMessageHandler handler) {
messageHandler = handler;
return YES;
}]
taskQueue:taskQueue])
.andReturn(connection);
OCMStub([codec decode:[OCMArg any]]).andReturn(@"decoded message");
[channel setMessageHandler:handler];
}
// Channel is released, messageHandler should still retain the codec. The codec
// internally makes a `decode` call and updates the `handlerMessage` to "decoded message".
messageHandler([NSData data], ^(NSData* data){
});
XCTAssertEqualObjects(handlerMessage, @"decoded message");
}

- (void)testMethodChannelInvokeHandlerAfterChannelReleased {
NSString* channelName = @"foo";
FlutterBinaryMessengerConnection connection = 123;
__block FlutterMethodCall* decodedMethodCall;
__block FlutterBinaryMessageHandler messageHandler;
@autoreleasepool {
id binaryMessenger = OCMProtocolMock(@protocol(FlutterBinaryMessenger));
id codec = OCMProtocolMock(@protocol(FlutterMethodCodec));
id taskQueue = OCMClassMock([NSObject class]);
FlutterMethodChannel* channel = [[FlutterMethodChannel alloc] initWithName:channelName
binaryMessenger:binaryMessenger
codec:codec
taskQueue:taskQueue];
FlutterMethodCallHandler handler = ^(FlutterMethodCall* call, FlutterResult result) {
decodedMethodCall = call;
};
OCMStub([binaryMessenger
setMessageHandlerOnChannel:channelName
binaryMessageHandler:[OCMArg checkWithBlock:^BOOL(
FlutterBinaryMessageHandler handler) {
messageHandler = handler;
return YES;
}]
taskQueue:taskQueue])
.andReturn(connection);
OCMStub([codec decodeMethodCall:[OCMArg any]])
.andReturn([FlutterMethodCall methodCallWithMethodName:@"decoded method call"
arguments:nil]);
[channel setMethodCallHandler:handler];
}
messageHandler([NSData data], ^(NSData* data){
});
XCTAssertEqualObjects(decodedMethodCall.method, @"decoded method call");
}

- (void)testMethodChannelTaskQueue {
NSString* channelName = @"foo";
FlutterBinaryMessengerConnection connection = 123;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@

#include <cstring>

FLUTTER_ASSERT_ARC

@implementation FlutterBinaryCodec
+ (instancetype)sharedInstance {
static id _sharedInstance = nil;
Expand Down Expand Up @@ -48,7 +50,7 @@ - (NSString*)decode:(NSData*)message {
if (message == nil) {
return nil;
}
return [[[NSString alloc] initWithData:message encoding:NSUTF8StringEncoding] autorelease];
return [[NSString alloc] initWithData:message encoding:NSUTF8StringEncoding];
}
@end

Expand Down
Loading