Skip to content

Commit b0e52e5

Browse files
authored
Add ConnectionCollection and Swift test (flutter#167962)
This rewrites the ConnectionCollection C++ class and its test to Swift. This ensures we're successfully able to write/run XCTests written in Swift. It also adds new tests for ConnectionCollection: * Verifies connection IDs are > 0. * Verifies connection IDs are unique. * Verifies the IDs of error connections are as specified. ## Pre-launch Checklist - [X] I read the [Contributor Guide] and followed the process outlined there for submitting PRs. - [X] I read the [Tree Hygiene] wiki page, which explains my responsibilities. - [X] I read and followed the [Flutter Style Guide], including [Features we expect every widget to implement]. - [X] I signed the [CLA]. - [X] I listed at least one issue that this PR fixes in the description above. - [X] I updated/added relevant documentation (doc comments with `///`). - [X] I added new tests to check the change I am making, or this PR is [test-exempt]. - [X] I followed the [breaking change policy] and added [Data Driven Fixes] where supported. - [X] All existing and new tests are passing. If you need help, consider asking for advice on the #hackers-new channel on [Discord]. <!-- Links --> [Contributor Guide]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#overview [Tree Hygiene]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md [test-exempt]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#tests [Flutter Style Guide]: https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md [Features we expect every widget to implement]: https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md#features-we-expect-every-widget-to-implement [CLA]: https://cla.developers.google.com/ [flutter/tests]: https://github.com/flutter/tests [breaking change policy]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#handling-breaking-changes [Discord]: https://github.com/flutter/flutter/blob/main/docs/contributing/Chat.md [Data Driven Fixes]: https://github.com/flutter/flutter/blob/main/docs/contributing/Data-driven-Fixes.md
1 parent e7e4fa5 commit b0e52e5

File tree

8 files changed

+98
-123
lines changed

8 files changed

+98
-123
lines changed

engine/src/flutter/ci/licenses_golden/licenses_flutter

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -52755,6 +52755,8 @@ ORIGIN: ../../../flutter/shell/platform/darwin/ios/framework/Headers/FlutterPlat
5275552755
ORIGIN: ../../../flutter/shell/platform/darwin/ios/framework/Headers/FlutterPlugin.h + ../../../flutter/LICENSE
5275652756
ORIGIN: ../../../flutter/shell/platform/darwin/ios/framework/Headers/FlutterPluginAppLifeCycleDelegate.h + ../../../flutter/LICENSE
5275752757
ORIGIN: ../../../flutter/shell/platform/darwin/ios/framework/Headers/FlutterViewController.h + ../../../flutter/LICENSE
52758+
ORIGIN: ../../../flutter/shell/platform/darwin/ios/framework/Source/ConnectionCollection.swift + ../../../flutter/LICENSE
52759+
ORIGIN: ../../../flutter/shell/platform/darwin/ios/framework/Source/ConnectionCollectionTest.swift + ../../../flutter/LICENSE
5275852760
ORIGIN: ../../../flutter/shell/platform/darwin/ios/framework/Source/FakeUIPressProxy.swift + ../../../flutter/LICENSE
5275952761
ORIGIN: ../../../flutter/shell/platform/darwin/ios/framework/Source/FlutterAppDelegate.mm + ../../../flutter/LICENSE
5276052762
ORIGIN: ../../../flutter/shell/platform/darwin/ios/framework/Source/FlutterAppDelegateTest.mm + ../../../flutter/LICENSE
@@ -52855,9 +52857,6 @@ ORIGIN: ../../../flutter/shell/platform/darwin/ios/framework/Source/accessibilit
5285552857
ORIGIN: ../../../flutter/shell/platform/darwin/ios/framework/Source/accessibility_bridge_ios.h + ../../../flutter/LICENSE
5285652858
ORIGIN: ../../../flutter/shell/platform/darwin/ios/framework/Source/accessibility_bridge_test.mm + ../../../flutter/LICENSE
5285752859
ORIGIN: ../../../flutter/shell/platform/darwin/ios/framework/Source/availability_version_check_test.mm + ../../../flutter/LICENSE
52858-
ORIGIN: ../../../flutter/shell/platform/darwin/ios/framework/Source/connection_collection.h + ../../../flutter/LICENSE
52859-
ORIGIN: ../../../flutter/shell/platform/darwin/ios/framework/Source/connection_collection.mm + ../../../flutter/LICENSE
52860-
ORIGIN: ../../../flutter/shell/platform/darwin/ios/framework/Source/connection_collection_test.mm + ../../../flutter/LICENSE
5286152860
ORIGIN: ../../../flutter/shell/platform/darwin/ios/framework/Source/overlay_layer_pool.h + ../../../flutter/LICENSE
5286252861
ORIGIN: ../../../flutter/shell/platform/darwin/ios/framework/Source/overlay_layer_pool.mm + ../../../flutter/LICENSE
5286352862
ORIGIN: ../../../flutter/shell/platform/darwin/ios/framework/Source/platform_message_response_darwin.h + ../../../flutter/LICENSE
@@ -55766,6 +55765,8 @@ FILE: ../../../flutter/shell/platform/darwin/ios/framework/Headers/FlutterPlugin
5576655765
FILE: ../../../flutter/shell/platform/darwin/ios/framework/Headers/FlutterViewController.h
5576755766
FILE: ../../../flutter/shell/platform/darwin/ios/framework/Info.plist
5576855767
FILE: ../../../flutter/shell/platform/darwin/ios/framework/PrivacyInfo.xcprivacy
55768+
FILE: ../../../flutter/shell/platform/darwin/ios/framework/Source/ConnectionCollection.swift
55769+
FILE: ../../../flutter/shell/platform/darwin/ios/framework/Source/ConnectionCollectionTest.swift
5576955770
FILE: ../../../flutter/shell/platform/darwin/ios/framework/Source/FakeUIPressProxy.swift
5577055771
FILE: ../../../flutter/shell/platform/darwin/ios/framework/Source/FlutterAppDelegate.mm
5577155772
FILE: ../../../flutter/shell/platform/darwin/ios/framework/Source/FlutterAppDelegateTest.mm
@@ -55866,9 +55867,6 @@ FILE: ../../../flutter/shell/platform/darwin/ios/framework/Source/accessibility_
5586655867
FILE: ../../../flutter/shell/platform/darwin/ios/framework/Source/accessibility_bridge_ios.h
5586755868
FILE: ../../../flutter/shell/platform/darwin/ios/framework/Source/accessibility_bridge_test.mm
5586855869
FILE: ../../../flutter/shell/platform/darwin/ios/framework/Source/availability_version_check_test.mm
55869-
FILE: ../../../flutter/shell/platform/darwin/ios/framework/Source/connection_collection.h
55870-
FILE: ../../../flutter/shell/platform/darwin/ios/framework/Source/connection_collection.mm
55871-
FILE: ../../../flutter/shell/platform/darwin/ios/framework/Source/connection_collection_test.mm
5587255870
FILE: ../../../flutter/shell/platform/darwin/ios/framework/Source/overlay_layer_pool.h
5587355871
FILE: ../../../flutter/shell/platform/darwin/ios/framework/Source/overlay_layer_pool.mm
5587455872
FILE: ../../../flutter/shell/platform/darwin/ios/framework/Source/platform_message_response_darwin.h

engine/src/flutter/shell/platform/darwin/ios/BUILD.gn

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,10 @@ source_set("InternalFlutterSwift") {
6868
visibility = [ ":*" ]
6969
configs += [ ":config_ios" ]
7070

71-
sources = [ "framework/Source/UIPressProxy.swift" ]
71+
sources = [
72+
"framework/Source/ConnectionCollection.swift",
73+
"framework/Source/UIPressProxy.swift",
74+
]
7275
}
7376

7477
source_set("flutter_framework_source") {
@@ -149,8 +152,6 @@ source_set("flutter_framework_source") {
149152
"framework/Source/UIViewController+FlutterScreenAndSceneIfLoaded.mm",
150153
"framework/Source/accessibility_bridge.h",
151154
"framework/Source/accessibility_bridge.mm",
152-
"framework/Source/connection_collection.h",
153-
"framework/Source/connection_collection.mm",
154155
"framework/Source/overlay_layer_pool.h",
155156
"framework/Source/overlay_layer_pool.mm",
156157
"framework/Source/platform_message_response_darwin.h",
@@ -224,7 +225,10 @@ if (enable_ios_unittests) {
224225
testonly = true
225226
visibility = [ ":*" ]
226227
configs += [ ":config_ios_test" ]
227-
sources = [ "framework/Source/FakeUIPressProxy.swift" ]
228+
sources = [
229+
"framework/Source/ConnectionCollectionTest.swift",
230+
"framework/Source/FakeUIPressProxy.swift",
231+
]
228232
frameworks = [ "XCTest.framework" ]
229233
deps = [ ":InternalFlutterSwift" ]
230234
}
@@ -278,7 +282,6 @@ if (enable_ios_unittests) {
278282
"framework/Source/VsyncWaiterIosTest.mm",
279283
"framework/Source/accessibility_bridge_test.mm",
280284
"framework/Source/availability_version_check_test.mm",
281-
"framework/Source/connection_collection_test.mm",
282285
"ios_context_noop_unittests.mm",
283286
"ios_surface_noop_unittests.mm",
284287
"platform_message_handler_ios_test.mm",
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
// Copyright 2013 The Flutter Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
import Foundation
6+
7+
/// A collection of active channel connections, tracked by unique IDs.
8+
///
9+
/// ConnectionIDs are guaranteed to be positive Int64s.
10+
///
11+
/// This class is not thread-safe. All accesses should happen from the
12+
/// platform thread.
13+
@objc(FlutterConnectionCollection)
14+
public class ConnectionCollection: NSObject {
15+
public typealias ConnectionID = Int64
16+
17+
// The connection ID of the most recently used connection, or 0 if none.
18+
private var counter: ConnectionID = 0
19+
20+
// Active connections map of channel name to connection ID.
21+
private var connections: [String: ConnectionID] = [:]
22+
23+
/// Acquires a new connection for the specified channel.
24+
@objc public func acquireConnection(forChannel channel: String) -> ConnectionID {
25+
counter += 1
26+
connections[channel] = counter
27+
return counter
28+
}
29+
30+
/// Cleans up an active connection.
31+
///
32+
/// Returns the name of the associated channel if successful, otherwise the
33+
/// empty string.
34+
@objc public func cleanupConnection(withID connectionID: ConnectionID) -> String {
35+
guard
36+
connectionID > 0,
37+
let entry = connections.first(where: { $0.value == connectionID })
38+
else { return "" }
39+
40+
connections[entry.key] = nil
41+
return entry.key
42+
}
43+
44+
/// Creates an error connection from an error code.
45+
@objc public static func makeErrorConnection(errorCode: Int64) -> ConnectionID {
46+
return abs(errorCode)
47+
}
48+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
// Copyright 2013 The Flutter Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
import InternalFlutterSwift
6+
import XCTest
7+
8+
class ConnectionCollectionTest: XCTestCase {
9+
func testAcquireAndRelease() {
10+
let connections = ConnectionCollection()
11+
let connectionID = connections.acquireConnection(forChannel: "foo")
12+
XCTAssertGreaterThan(connectionID, 0)
13+
XCTAssertEqual("foo", connections.cleanupConnection(withID: connectionID))
14+
XCTAssertEqual("", connections.cleanupConnection(withID: connectionID))
15+
}
16+
17+
func testUniqueIDs() {
18+
let connections = ConnectionCollection()
19+
let firstConnectionID = connections.acquireConnection(forChannel: "foo")
20+
let secondConnectionID = connections.acquireConnection(forChannel: "bar")
21+
XCTAssertNotEqual(firstConnectionID, secondConnectionID)
22+
XCTAssertEqual("foo", connections.cleanupConnection(withID: firstConnectionID))
23+
XCTAssertEqual("bar", connections.cleanupConnection(withID: secondConnectionID))
24+
}
25+
26+
func testErrorConnectionWithNegativeCode() {
27+
XCTAssertEqual(55, ConnectionCollection.makeErrorConnection(errorCode: 55))
28+
XCTAssertEqual(55, ConnectionCollection.makeErrorConnection(errorCode: -55))
29+
}
30+
}

engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include "flutter/shell/common/variable_refresh_rate_display.h"
2323
#import "flutter/shell/platform/darwin/common/command_line.h"
2424
#import "flutter/shell/platform/darwin/common/framework/Source/FlutterBinaryMessengerRelay.h"
25+
#import "flutter/shell/platform/darwin/ios/InternalFlutterSwift/InternalFlutterSwift.h"
2526
#import "flutter/shell/platform/darwin/ios/framework/Source/FlutterDartProject_Internal.h"
2627
#import "flutter/shell/platform/darwin/ios/framework/Source/FlutterDartVMServicePublisher.h"
2728
#import "flutter/shell/platform/darwin/ios/framework/Source/FlutterIndirectScribbleDelegate.h"
@@ -34,7 +35,6 @@
3435
#import "flutter/shell/platform/darwin/ios/framework/Source/FlutterUndoManagerPlugin.h"
3536
#import "flutter/shell/platform/darwin/ios/framework/Source/FlutterViewController_Internal.h"
3637
#import "flutter/shell/platform/darwin/ios/framework/Source/UIViewController+FlutterScreenAndSceneIfLoaded.h"
37-
#import "flutter/shell/platform/darwin/ios/framework/Source/connection_collection.h"
3838
#import "flutter/shell/platform/darwin/ios/framework/Source/platform_message_response_darwin.h"
3939
#import "flutter/shell/platform/darwin/ios/framework/Source/profiler_metrics_ios.h"
4040
#import "flutter/shell/platform/darwin/ios/framework/Source/vsync_waiter_ios.h"
@@ -117,6 +117,7 @@ @interface FlutterEngine () <FlutterIndirectScribbleDelegate,
117117
@property(nonatomic, copy) NSString* initialRoute;
118118
@property(nonatomic, strong) id<NSObject> flutterViewControllerWillDeallocObserver;
119119
@property(nonatomic, strong) FlutterDartVMServicePublisher* publisher;
120+
@property(nonatomic, strong) FlutterConnectionCollection* connections;
120121
@property(nonatomic, assign) int64_t nextTextureId;
121122

122123
#pragma mark - Channel properties
@@ -158,7 +159,6 @@ @implementation FlutterEngine {
158159

159160
FlutterBinaryMessengerRelay* _binaryMessenger;
160161
FlutterTextureRegistryRelay* _textureRegistry;
161-
std::unique_ptr<flutter::ConnectionCollection> _connections;
162162
}
163163

164164
- (int64_t)engineIdentifier {
@@ -220,7 +220,7 @@ - (instancetype)initWithName:(NSString*)labelPrefix
220220
[self recreatePlatformViewsController];
221221
_binaryMessenger = [[FlutterBinaryMessengerRelay alloc] initWithParent:self];
222222
_textureRegistry = [[FlutterTextureRegistryRelay alloc] initWithParent:self];
223-
_connections.reset(new flutter::ConnectionCollection());
223+
_connections = [[FlutterConnectionCollection alloc] init];
224224

225225
NSNotificationCenter* center = [NSNotificationCenter defaultCenter];
226226
[center addObserver:self
@@ -1256,19 +1256,19 @@ - (FlutterBinaryMessengerConnection)setMessageHandlerOnChannel:(NSString*)channe
12561256
if (_shell && _shell->IsSetup()) {
12571257
self.platformView->GetPlatformMessageHandlerIos()->SetMessageHandler(channel.UTF8String,
12581258
handler, taskQueue);
1259-
return _connections->AquireConnection(channel.UTF8String);
1259+
return [self.connections acquireConnectionForChannel:channel];
12601260
} else {
12611261
NSAssert(!handler, @"Setting a message handler before the FlutterEngine has been run.");
12621262
// Setting a handler to nil for a channel that has not yet been set up is a no-op.
1263-
return flutter::ConnectionCollection::MakeErrorConnection(-1);
1263+
return [FlutterConnectionCollection makeErrorConnectionWithErrorCode:-1L];
12641264
}
12651265
}
12661266

12671267
- (void)cleanUpConnection:(FlutterBinaryMessengerConnection)connection {
12681268
if (_shell && _shell->IsSetup()) {
1269-
std::string channel = _connections->CleanupConnection(connection);
1270-
if (!channel.empty()) {
1271-
self.platformView->GetPlatformMessageHandlerIos()->SetMessageHandler(channel.c_str(), nil,
1269+
NSString* channel = [self.connections cleanupConnectionWithID:connection];
1270+
if (channel.length > 0) {
1271+
self.platformView->GetPlatformMessageHandlerIos()->SetMessageHandler(channel.UTF8String, nil,
12721272
nil);
12731273
}
12741274
}

engine/src/flutter/shell/platform/darwin/ios/framework/Source/connection_collection.h

Lines changed: 0 additions & 36 deletions
This file was deleted.

engine/src/flutter/shell/platform/darwin/ios/framework/Source/connection_collection.mm

Lines changed: 0 additions & 46 deletions
This file was deleted.

engine/src/flutter/shell/platform/darwin/ios/framework/Source/connection_collection_test.mm

Lines changed: 0 additions & 22 deletions
This file was deleted.

0 commit comments

Comments
 (0)