diff --git a/shell/platform/darwin/BUILD.gn b/shell/platform/darwin/BUILD.gn index f11a8b7aa1cb1..23c8e4055acf7 100644 --- a/shell/platform/darwin/BUILD.gn +++ b/shell/platform/darwin/BUILD.gn @@ -26,20 +26,6 @@ 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", @@ -50,12 +36,13 @@ source_set("flutter_channels_arc") { "common/framework/Source/FlutterStandardCodec_Internal.h", ] - 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", + deps = [ + "//flutter/common", + "//flutter/flow", + "//flutter/fml", + "//flutter/runtime", + "//flutter/shell/common", + "//third_party/skia", ] public_configs = [ "//flutter:config" ] diff --git a/shell/platform/darwin/common/BUILD.gn b/shell/platform/darwin/common/BUILD.gn index 72e3a807f1d85..45a9e3092b2bc 100644 --- a/shell/platform/darwin/common/BUILD.gn +++ b/shell/platform/darwin/common/BUILD.gn @@ -16,7 +16,15 @@ source_set("common") { "command_line.mm", ] - deps = [ "//flutter/fml" ] + deps = [ + "//flutter/common", + "//flutter/flow", + "//flutter/fml", + "//flutter/runtime", + "//flutter/shell/common", + "//third_party/dart/runtime:dart_api", + "//third_party/skia", + ] public_configs = [ "//flutter:config" ] } @@ -30,8 +38,8 @@ config("framework_relative_headers") { # Framework code shared between iOS and macOS. source_set("framework_shared") { - cflags_objc = flutter_cflags_objc_arc - cflags_objcc = flutter_cflags_objcc_arc + cflags_objc = flutter_cflags_objc + cflags_objcc = flutter_cflags_objcc sources = [ "framework/Source/FlutterChannels.mm", diff --git a/shell/platform/darwin/common/framework/Headers/FlutterCodecs.h b/shell/platform/darwin/common/framework/Headers/FlutterCodecs.h index f7117f01ffb7a..3ba5d4e9c2580 100644 --- a/shell/platform/darwin/common/framework/Headers/FlutterCodecs.h +++ b/shell/platform/darwin/common/framework/Headers/FlutterCodecs.h @@ -344,17 +344,17 @@ FLUTTER_DARWIN_EXPORT /** * The type of the encoded values. */ -@property(readonly, nonatomic, assign) FlutterStandardDataType type; +@property(readonly, nonatomic) FlutterStandardDataType type; /** * The number of value items encoded. */ -@property(readonly, nonatomic, assign) UInt32 elementCount; +@property(readonly, nonatomic) UInt32 elementCount; /** * The number of bytes used by the encoding of a single value item. */ -@property(readonly, nonatomic, assign) UInt8 elementSize; +@property(readonly, nonatomic) UInt8 elementSize; @end /** diff --git a/shell/platform/darwin/common/framework/Source/FlutterChannels.mm b/shell/platform/darwin/common/framework/Source/FlutterChannels.mm index f360144d3748f..30b306a301f39 100644 --- a/shell/platform/darwin/common/framework/Source/FlutterChannels.mm +++ b/shell/platform/darwin/common/framework/Source/FlutterChannels.mm @@ -4,8 +4,6 @@ #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"; @@ -53,9 +51,9 @@ + (instancetype)messageChannelWithName:(NSString*)name + (instancetype)messageChannelWithName:(NSString*)name binaryMessenger:(NSObject*)messenger codec:(NSObject*)codec { - return [[FlutterBasicMessageChannel alloc] initWithName:name - binaryMessenger:messenger - codec:codec]; + return [[[FlutterBasicMessageChannel alloc] initWithName:name + binaryMessenger:messenger + codec:codec] autorelease]; } - (instancetype)initWithName:(NSString*)name @@ -71,13 +69,21 @@ - (instancetype)initWithName:(NSString*)name taskQueue:(NSObject*)taskQueue { self = [super init]; NSAssert(self, @"Super init cannot be nil"); - _name = [name copy]; - _messenger = messenger; - _codec = codec; - _taskQueue = taskQueue; + _name = [name retain]; + _messenger = [messenger retain]; + _codec = [codec retain]; + _taskQueue = [taskQueue retain]; 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]]; } @@ -101,10 +107,7 @@ - (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* codec = _codec; FlutterBinaryMessageHandler messageHandler = ^(NSData* message, FlutterBinaryReply callback) { handler([codec decode:message], ^(id reply) { @@ -125,19 +128,26 @@ - (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]; + return [[[FlutterError alloc] initWithCode:code message:message details:details] autorelease]; } - (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 copy]; - _message = [message copy]; - _details = details; + _code = [code retain]; + _message = [message retain]; + _details = [details retain]; return self; } +- (void)dealloc { + [_code release]; + [_message release]; + [_details release]; + [super dealloc]; +} + - (BOOL)isEqual:(id)object { if (self == object) { return YES; @@ -159,18 +169,24 @@ - (NSUInteger)hash { //////////////////////////////////////////////////////////////////////////////// @implementation FlutterMethodCall + (instancetype)methodCallWithMethodName:(NSString*)method arguments:(id)arguments { - return [[FlutterMethodCall alloc] initWithMethodName:method arguments:arguments]; + return [[[FlutterMethodCall alloc] initWithMethodName:method arguments:arguments] autorelease]; } - (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 copy]; - _arguments = arguments; + _method = [method retain]; + _arguments = [arguments retain]; return self; } +- (void)dealloc { + [_method release]; + [_arguments release]; + [super dealloc]; +} + - (BOOL)isEqual:(id)object { if (self == object) { return YES; @@ -208,7 +224,8 @@ + (instancetype)methodChannelWithName:(NSString*)name + (instancetype)methodChannelWithName:(NSString*)name binaryMessenger:(NSObject*)messenger codec:(NSObject*)codec { - return [[FlutterMethodChannel alloc] initWithName:name binaryMessenger:messenger codec:codec]; + return [[[FlutterMethodChannel alloc] initWithName:name binaryMessenger:messenger + codec:codec] autorelease]; } - (instancetype)initWithName:(NSString*)name @@ -223,13 +240,21 @@ - (instancetype)initWithName:(NSString*)name taskQueue:(NSObject*)taskQueue { self = [super init]; NSAssert(self, @"Super init cannot be nil"); - _name = [name copy]; - _messenger = messenger; - _codec = codec; - _taskQueue = taskQueue; + _name = [name retain]; + _messenger = [messenger retain]; + _codec = [codec retain]; + _taskQueue = [taskQueue retain]; 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]; @@ -260,8 +285,6 @@ - (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* codec = _codec; FlutterBinaryMessageHandler messageHandler = ^(NSData* message, FlutterBinaryReply callback) { FlutterMethodCall* call = [codec decodeMethodCall:message]; @@ -305,7 +328,8 @@ + (instancetype)eventChannelWithName:(NSString*)name + (instancetype)eventChannelWithName:(NSString*)name binaryMessenger:(NSObject*)messenger codec:(NSObject*)codec { - return [[FlutterEventChannel alloc] initWithName:name binaryMessenger:messenger codec:codec]; + return [[[FlutterEventChannel alloc] initWithName:name binaryMessenger:messenger + codec:codec] autorelease]; } - (instancetype)initWithName:(NSString*)name @@ -320,13 +344,21 @@ - (instancetype)initWithName:(NSString*)name taskQueue:(NSObject* _Nullable)taskQueue { self = [super init]; NSAssert(self, @"Super init cannot be nil"); - _name = [name copy]; - _messenger = messenger; - _codec = codec; - _taskQueue = taskQueue; + _name = [name retain]; + _messenger = [messenger retain]; + _codec = [codec retain]; + _taskQueue = [taskQueue retain]; return self; } +- (void)dealloc { + [_name release]; + [_codec release]; + [_messenger release]; + [_taskQueue release]; + [super dealloc]; +} + static FlutterBinaryMessengerConnection SetStreamHandlerMessageHandlerOnChannel( NSObject* handler, NSString* name, diff --git a/shell/platform/darwin/common/framework/Source/FlutterChannelsTest.m b/shell/platform/darwin/common/framework/Source/FlutterChannelsTest.m index e2593f535b7e1..a499fbea8f34d 100644 --- a/shell/platform/darwin/common/framework/Source/FlutterChannelsTest.m +++ b/shell/platform/darwin/common/framework/Source/FlutterChannelsTest.m @@ -234,78 +234,6 @@ - (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; diff --git a/shell/platform/darwin/common/framework/Source/FlutterCodecs.mm b/shell/platform/darwin/common/framework/Source/FlutterCodecs.mm index 57ef1eb752a4a..8ea26cc258063 100644 --- a/shell/platform/darwin/common/framework/Source/FlutterCodecs.mm +++ b/shell/platform/darwin/common/framework/Source/FlutterCodecs.mm @@ -6,8 +6,6 @@ #include -FLUTTER_ASSERT_ARC - @implementation FlutterBinaryCodec + (instancetype)sharedInstance { static id _sharedInstance = nil; @@ -50,7 +48,7 @@ - (NSString*)decode:(NSData*)message { if (message == nil) { return nil; } - return [[NSString alloc] initWithData:message encoding:NSUTF8StringEncoding]; + return [[[NSString alloc] initWithData:message encoding:NSUTF8StringEncoding] autorelease]; } @end diff --git a/shell/platform/darwin/common/framework/Source/FlutterStandardCodec.mm b/shell/platform/darwin/common/framework/Source/FlutterStandardCodec.mm index 62e85e66a2440..eeb3ef918b0c3 100644 --- a/shell/platform/darwin/common/framework/Source/FlutterStandardCodec.mm +++ b/shell/platform/darwin/common/framework/Source/FlutterStandardCodec.mm @@ -4,8 +4,6 @@ #import "flutter/shell/platform/darwin/common/framework/Source/FlutterStandardCodec_Internal.h" -FLUTTER_ASSERT_ARC - #pragma mark - Codec for basic message channel @implementation FlutterStandardMessageCodec { @@ -14,23 +12,29 @@ @implementation FlutterStandardMessageCodec { + (instancetype)sharedInstance { static id _sharedInstance = nil; if (!_sharedInstance) { - FlutterStandardReaderWriter* readerWriter = [[FlutterStandardReaderWriter alloc] init]; + FlutterStandardReaderWriter* readerWriter = + [[[FlutterStandardReaderWriter alloc] init] autorelease]; _sharedInstance = [[FlutterStandardMessageCodec alloc] initWithReaderWriter:readerWriter]; } return _sharedInstance; } + (instancetype)codecWithReaderWriter:(FlutterStandardReaderWriter*)readerWriter { - return [[FlutterStandardMessageCodec alloc] initWithReaderWriter:readerWriter]; + return [[[FlutterStandardMessageCodec alloc] initWithReaderWriter:readerWriter] autorelease]; } - (instancetype)initWithReaderWriter:(FlutterStandardReaderWriter*)readerWriter { self = [super init]; NSAssert(self, @"Super init cannot be nil"); - _readerWriter = readerWriter; + _readerWriter = [readerWriter retain]; return self; } +- (void)dealloc { + [_readerWriter release]; + [super dealloc]; +} + - (NSData*)encode:(id)message { if (message == nil) { return nil; @@ -60,23 +64,29 @@ @implementation FlutterStandardMethodCodec { + (instancetype)sharedInstance { static id _sharedInstance = nil; if (!_sharedInstance) { - FlutterStandardReaderWriter* readerWriter = [[FlutterStandardReaderWriter alloc] init]; + FlutterStandardReaderWriter* readerWriter = + [[[FlutterStandardReaderWriter alloc] init] autorelease]; _sharedInstance = [[FlutterStandardMethodCodec alloc] initWithReaderWriter:readerWriter]; } return _sharedInstance; } + (instancetype)codecWithReaderWriter:(FlutterStandardReaderWriter*)readerWriter { - return [[FlutterStandardMethodCodec alloc] initWithReaderWriter:readerWriter]; + return [[[FlutterStandardMethodCodec alloc] initWithReaderWriter:readerWriter] autorelease]; } - (instancetype)initWithReaderWriter:(FlutterStandardReaderWriter*)readerWriter { self = [super init]; NSAssert(self, @"Super init cannot be nil"); - _readerWriter = readerWriter; + _readerWriter = [readerWriter retain]; return self; } +- (void)dealloc { + [_readerWriter release]; + [super dealloc]; +} + - (NSData*)encodeMethodCall:(FlutterMethodCall*)call { NSMutableData* data = [NSMutableData dataWithCapacity:32]; FlutterStandardWriter* writer = [_readerWriter writerWithData:data]; @@ -163,7 +173,7 @@ + (instancetype)typedDataWithFloat64:(NSData*)data { } + (instancetype)typedDataWithData:(NSData*)data type:(FlutterStandardDataType)type { - return [[FlutterStandardTypedData alloc] initWithData:data type:type]; + return [[[FlutterStandardTypedData alloc] initWithData:data type:type] autorelease]; } - (instancetype)initWithData:(NSData*)data type:(FlutterStandardDataType)type { @@ -172,13 +182,18 @@ - (instancetype)initWithData:(NSData*)data type:(FlutterStandardDataType)type { NSAssert(data.length % elementSize == 0, @"Data must contain integral number of elements"); self = [super init]; NSAssert(self, @"Super init cannot be nil"); - _data = [data copy]; + _data = [data retain]; _type = type; _elementSize = elementSize; _elementCount = data.length / elementSize; return self; } +- (void)dealloc { + [_data release]; + [super dealloc]; +} + - (BOOL)isEqual:(id)object { if (self == object) { return YES; @@ -205,10 +220,15 @@ @implementation FlutterStandardWriter { - (instancetype)initWithData:(NSMutableData*)data { self = [super init]; NSAssert(self, @"Super init cannot be nil"); - _data = data; + _data = [data retain]; return self; } +- (void)dealloc { + [_data release]; + [super dealloc]; +} + - (void)writeByte:(UInt8)value { [_data appendBytes:&value length:1]; } @@ -253,7 +273,7 @@ - (void)writeValue:(id)value { if (value == nil || value == [NSNull null]) { [self writeByte:FlutterStandardFieldNil]; } else if ([value isKindOfClass:[NSNumber class]]) { - CFNumberRef number = (__bridge CFNumberRef)value; + CFNumberRef number = (CFNumberRef)value; BOOL success = NO; if (CFGetTypeID(number) == CFBooleanGetTypeID()) { BOOL b = CFBooleanGetValue((CFBooleanRef)number); @@ -328,11 +348,16 @@ @implementation FlutterStandardReader { - (instancetype)initWithData:(NSData*)data { self = [super init]; NSAssert(self, @"Super init cannot be nil"); - _data = [data copy]; + _data = [data retain]; _range = NSMakeRange(0, 0); return self; } +- (void)dealloc { + [_data release]; + [super dealloc]; +} + - (BOOL)hasMore { return _range.location < _data.length; } @@ -373,7 +398,7 @@ - (NSData*)readData:(NSUInteger)length { - (NSString*)readUTF8 { NSData* bytes = [self readData:[self readSize]]; - return [[NSString alloc] initWithData:bytes encoding:NSUTF8StringEncoding]; + return [[[NSString alloc] initWithData:bytes encoding:NSUTF8StringEncoding] autorelease]; } - (void)readAlignment:(UInt8)alignment { @@ -457,10 +482,10 @@ - (nullable id)readValueOfType:(UInt8)type { @implementation FlutterStandardReaderWriter - (FlutterStandardWriter*)writerWithData:(NSMutableData*)data { - return [[FlutterStandardWriter alloc] initWithData:data]; + return [[[FlutterStandardWriter alloc] initWithData:data] autorelease]; } - (FlutterStandardReader*)readerWithData:(NSData*)data { - return [[FlutterStandardReader alloc] initWithData:data]; + return [[[FlutterStandardReader alloc] initWithData:data] autorelease]; } @end diff --git a/shell/platform/darwin/ios/framework/Source/FlutterRestorationPluginTest.mm b/shell/platform/darwin/ios/framework/Source/FlutterRestorationPluginTest.mm index d61a29e0f31fd..36de96d451a8d 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterRestorationPluginTest.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterRestorationPluginTest.mm @@ -80,7 +80,7 @@ - (void)testRestorationEnabledWaitsForData { [restorationPlugin setRestorationData:data]; XCTAssertEqual([capturedResult count], 2u); XCTAssertEqual([capturedResult objectForKey:@"enabled"], @YES); - XCTAssertEqualObjects([[capturedResult objectForKey:@"data"] data], data); + XCTAssertEqual([[capturedResult objectForKey:@"data"] data], data); } - (void)testRestorationDisabledRespondsRightAway { @@ -112,7 +112,7 @@ - (void)testRespondsRightAwayWhenDataIsSet { }]; XCTAssertEqual([capturedResult count], 2u); XCTAssertEqual([capturedResult objectForKey:@"enabled"], @YES); - XCTAssertEqualObjects([[capturedResult objectForKey:@"data"] data], data); + XCTAssertEqual([[capturedResult objectForKey:@"data"] data], data); } - (void)testRespondsWithNoDataWhenRestorationIsCompletedWithoutData { @@ -161,7 +161,7 @@ - (void)testReturnsDataSetByFramework { result:^(id _Nullable result) { XCTAssertNil(result); }]; - XCTAssertEqualObjects([restorationPlugin restorationData], data); + XCTAssertEqual([restorationPlugin restorationData], data); } - (void)testRespondsWithDataSetByFramework { @@ -177,7 +177,7 @@ - (void)testRespondsWithDataSetByFramework { result:^(id _Nullable result) { XCTAssertNil(result); }]; - XCTAssertEqualObjects([restorationPlugin restorationData], data); + XCTAssertEqual([restorationPlugin restorationData], data); __block id capturedResult; methodCall = [FlutterMethodCall methodCallWithMethodName:@"get" arguments:nil]; @@ -187,7 +187,7 @@ - (void)testRespondsWithDataSetByFramework { }]; XCTAssertEqual([capturedResult count], 2u); XCTAssertEqual([capturedResult objectForKey:@"enabled"], @YES); - XCTAssertEqualObjects([[capturedResult objectForKey:@"data"] data], data); + XCTAssertEqual([[capturedResult objectForKey:@"data"] data], data); } - (void)testResetClearsData { @@ -203,7 +203,7 @@ - (void)testResetClearsData { result:^(id _Nullable result) { XCTAssertNil(result); }]; - XCTAssertEqualObjects([restorationPlugin restorationData], data); + XCTAssertEqual([restorationPlugin restorationData], data); [restorationPlugin reset]; XCTAssertNil([restorationPlugin restorationData]);