Skip to content
This repository was archived by the owner on Feb 22, 2023. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
7c363fd
dart side of implementation
bparrishMines May 11, 2022
2e55266
objc side of callback impl
bparrishMines May 12, 2022
4a12eaa
documentation and a test messenger
bparrishMines May 12, 2022
6bc048b
dart side update
bparrishMines May 16, 2022
4efa9a1
objc side
bparrishMines May 16, 2022
f9d54e2
formatting
bparrishMines May 16, 2022
2f73074
Merge branch 'main' of github.com:flutter/plugins into callbacks
bparrishMines May 16, 2022
ddfde5c
handles
bparrishMines May 17, 2022
96c21ae
some fixes for PR comments
bparrishMines May 18, 2022
f2a3504
new instance manager
bparrishMines May 19, 2022
77da52f
bunch of work
bparrishMines May 19, 2022
e388090
instance manager tests
bparrishMines May 19, 2022
ac3a2de
fix foundation tests
bparrishMines May 19, 2022
696c25c
dart touchups
bparrishMines May 19, 2022
88816c9
finish dart standardization and support earlier versions
bparrishMines May 19, 2022
9d25ab1
fix dart instance manager
bparrishMines May 19, 2022
4d7ebc4
instance manager ish
bparrishMines May 19, 2022
81b201f
most tests passing
bparrishMines May 19, 2022
62581ba
instance manager tests
bparrishMines May 20, 2022
f0d2498
formatting and one last test
bparrishMines May 20, 2022
4bd6d2a
formatting
bparrishMines May 20, 2022
7974d56
naming
bparrishMines May 20, 2022
ad9b4e6
better comment
bparrishMines May 20, 2022
d8b720e
update comment with info about platform/flutter
bparrishMines May 23, 2022
3c98004
fix bug from instance manager identifier
bparrishMines May 24, 2022
368fb30
limits on identifiers
bparrishMines May 25, 2022
a6980c5
use removeReference name instead
bparrishMines May 25, 2022
179f109
maybe an even better name?
bparrishMines May 25, 2022
e966816
use init constructor
bparrishMines May 25, 2022
3897535
version bump
bparrishMines May 25, 2022
312825a
update name
bparrishMines May 25, 2022
36fa0a0
Merge branch 'main' of github.com:flutter/plugins into callbacks
bparrishMines May 25, 2022
2b7a9af
undo changes to webview_flutter
bparrishMines May 25, 2022
86b193a
add api impls
bparrishMines May 25, 2022
61d5f8a
undo changes to create methods
bparrishMines May 25, 2022
29e8ad0
changes and stuff
bparrishMines May 25, 2022
2be09aa
some updates
bparrishMines May 26, 2022
e212aa4
Merge branch 'main' of github.com:flutter/plugins into callbacks
bparrishMines May 26, 2022
ea0fe93
method names
bparrishMines May 26, 2022
9e47dda
more docs, yay
bparrishMines May 26, 2022
8076bed
spelling and docs
bparrishMines May 31, 2022
0fa7a14
pr comments
bparrishMines Jun 2, 2022
797d448
format and issue
bparrishMines Jun 2, 2022
ba8161a
Merge branch 'main' of github.com:flutter/plugins into callbacks
bparrishMines Jun 2, 2022
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
Prev Previous commit
Next Next commit
limits on identifiers
  • Loading branch information
bparrishMines committed May 25, 2022
commit 368fb30ca423429b83a39107306f4a1dd592be1e
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,6 @@
<key>CFBundleVersion</key>
<string>1.0</string>
<key>MinimumOSVersion</key>
<string>9.0</string>
<string>11.0</string>
</dict>
</plist>
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Uncomment this line to define a global platform for your project
# platform :ios, '9.0'
# platform :ios, '11.0'

# CocoaPods analytics sends network stats synchronously affecting flutter build latency.
ENV['COCOAPODS_DISABLE_STATS'] = 'true'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
archiveVersion = 1;
classes = {
};
objectVersion = 46;
objectVersion = 50;
objects = {

/* Begin PBXBuildFile section */
Expand Down Expand Up @@ -274,7 +274,7 @@
isa = PBXProject;
attributes = {
DefaultBuildSystemTypeForWorkspace = Original;
LastUpgradeCheck = 1030;
LastUpgradeCheck = 1300;
ORGANIZATIONNAME = "The Flutter Authors";
TargetAttributes = {
68BDCAE823C3F7CB00D9C032 = {
Expand Down Expand Up @@ -552,7 +552,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
Expand Down Expand Up @@ -602,7 +602,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
TARGETED_DEVICE_FAMILY = "1,2";
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1030"
LastUpgradeVersion = "1300"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,5 +41,7 @@
</array>
<key>UIViewControllerBasedStatusBarAppearance</key>
<false/>
<key>CADisableMinimumFrameDurationOnPhone</key>
<true/>
</dict>
</plist>
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,16 @@ @interface FWFInstanceManager ()
@property NSMapTable<NSObject *, NSNumber *> *identifiers;
@property NSMapTable<NSNumber *, NSObject *> *weakInstances;
@property NSMapTable<NSNumber *, NSObject *> *strongInstances;
@property long nextIdentifier;
@end

@implementation FWFInstanceManager
// Identifiers are locked to a specific range to avoid collisions with objects
// created simultaneously by Dart.
// Host uses identifiers >= 2^16 and Dart is expected to use values n where,
// 0 <= n < 2^16.
long const FWFMinHostCreatedIdentifier = 65536;

- (instancetype)initWithDeallocCallback:(FWFOnDeallocCallback)callback {
self = [self init];
if (self) {
Expand All @@ -59,6 +66,7 @@ - (instancetype)initWithDeallocCallback:(FWFOnDeallocCallback)callback {
_identifiers = [NSMapTable weakToStrongObjectsMapTable];
_weakInstances = [NSMapTable strongToWeakObjectsMapTable];
_strongInstances = [NSMapTable strongToStrongObjectsMapTable];
_nextIdentifier = FWFMinHostCreatedIdentifier;
}
return self;
}
Expand All @@ -75,12 +83,7 @@ - (long)addHostCreatedInstance:(nonnull NSObject *)instance {
NSParameterAssert(instance);
long __block identifier = -1;
dispatch_sync(_lockQueue, ^{
do {
// Identifiers are generated randomly to avoid collisions with objects
// created simultaneously by Flutter.
// Values are >= 2^16 and Flutter is expected to use values < 2^16.
identifier = arc4random_uniform(65536) + 65536;
} while ([self.weakInstances objectForKey:@(identifier)]);
identifier = self.nextIdentifier++;
[self addInstance:instance withIdentifier:identifier];
});
return identifier;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'dart:math';

import 'package:flutter/foundation.dart';

/// An immutable object that can provide functional copies of themselves.
Expand Down Expand Up @@ -37,31 +35,36 @@ mixin Copyable {
/// strong reference is added as a weak reference with the same identifier. This
/// prevents a scenario where the weak referenced instance was released and then
/// later returned by the host platform.
// TODO(bparrishMines): Uncomment code with Finalizers and WeakReferences once
// minimum dart version is bumped to 2.17.
class InstanceManager {
/// Constructs an [InstanceManager].
InstanceManager({required void Function(int) onWeakReferenceRemoved}) {
this.onWeakReferenceRemoved = (int identifier) {
_weakInstances.remove(identifier);
onWeakReferenceRemoved(identifier);
};
_finalizer = Finalizer<int>(this.onWeakReferenceRemoved);
}

// Identifiers are locked to a specific range to avoid collisions with objects
// created simultaneously by the host platform.
// Host uses identifiers >= 2^16 and Dart is expected to use values n where,
// 0 <= n < 2^16.
static const int _maxDartCreatedIdentifier = 65536;

// Expando is used because it doesn't prevent its keys from becoming
// inaccessible. This allows the manager to efficiently retrieve an identifier
// of an instance without holding a strong reference to that instance.
//
// It also doesn't use `==` to search for identifiers, which would lead to an
// infinite loop when comparing an object to its copy. (i.e. which was caused
// by calling instanceManager.getInstanceId() inside of `==` while this was a
// by calling instanceManager.getIdentifier() inside of `==` while this was a
// HashMap).
final Expando<int> _identifiers = Expando<int>();
final Map<int, Copyable> _weakInstances = <int, Copyable>{};
// final Map<int, WeakReference<Copyable>> _weakInstances =
// <int, WeakReference<Copyable>>{};
final Map<int, WeakReference<Copyable>> _weakInstances =
<int, WeakReference<Copyable>>{};
final Map<int, Copyable> _strongInstances = <int, Copyable>{};
// final Finalizer<int> _finalizer;
late final Finalizer<int> _finalizer;
int _nextIdentifier = 0;

/// Called when a weak referenced instance is removed by [removeWeakReference]
/// or becomes inaccessible.
Expand All @@ -75,10 +78,10 @@ class InstanceManager {
/// Throws assertion error if the instance has already been added.
///
/// Returns the randomly generated id of the [instance] added.
int addFlutterCreatedInstance(Copyable instance) {
int addDartCreatedInstance(Copyable instance) {
assert(getIdentifier(instance) == null);

final int identifier = _generateNewIdentifier();
final int identifier = _nextUniqueIdentifier();
_addInstanceWithIdentifier(instance, identifier);
return identifier;
}
Expand All @@ -98,7 +101,7 @@ class InstanceManager {
}

_identifiers[instance] = null;
//_finalizer.detach(instance);
_finalizer.detach(instance);
onWeakReferenceRemoved(identifier);

return identifier;
Expand Down Expand Up @@ -133,17 +136,15 @@ class InstanceManager {
int identifier, {
required bool returnedInstanceMayBeUsed,
}) {
// final Copyable? weakInstance = _weakInstances[identifier]?.target;
final Copyable? weakInstance = _weakInstances[identifier];
final Copyable? weakInstance = _weakInstances[identifier]?.target;

if (weakInstance == null) {
final Copyable? strongInstance = _strongInstances[identifier];
if (strongInstance != null && returnedInstanceMayBeUsed) {
final Copyable copy = strongInstance.copy();
_identifiers[copy] = identifier;
_weakInstances[identifier] = copy;
// _weakInstances[identifier] = WeakReference<Copyable>(copy);
// _finalizer.attach(copy, identifier, detach: copy);
_weakInstances[identifier] = WeakReference<Copyable>(copy);
_finalizer.attach(copy, identifier, detach: copy);
return copy as T;
}
return strongInstance as T?;
Expand Down Expand Up @@ -175,9 +176,8 @@ class InstanceManager {

void _addInstanceWithIdentifier(Copyable instance, int identifier) {
_identifiers[instance] = identifier;
_weakInstances[identifier] = instance;
// _weakInstances[identifier] = WeakReference<Copyable>(instance);
// _finalizer.attach(instance, identifier, detach: instance);
_weakInstances[identifier] = WeakReference<Copyable>(instance);
_finalizer.attach(instance, identifier, detach: instance);

final Copyable copy = instance.copy();
_identifiers[copy] = identifier;
Expand All @@ -192,15 +192,10 @@ class InstanceManager {
_strongInstances.containsKey(identifier);
}

// Identifiers are generated randomly to avoid collisions with objects
// created simultaneously by the host platform.
int _generateNewIdentifier() {
late int identifier;
do {
// Values are less than 2^16 while the host platform is expected to use
// values greater than or equal to 2^16.
identifier = Random().nextInt(65536);
} while (containsIdentifier(identifier));
return identifier;
int _nextUniqueIdentifier() {
while (containsIdentifier(_nextIdentifier)) {
_nextIdentifier = (_nextIdentifier + 1) % _maxDartCreatedIdentifier;
}
return _nextIdentifier;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import 'dart:async';
import 'dart:math';

import 'package:flutter/painting.dart' show Color;
import 'package:flutter/services.dart';

import '../common/instance_manager.dart';
import '../common/web_kit.pigeon.dart';
Expand All @@ -18,10 +17,9 @@ import 'ui_kit.dart';
class UIScrollViewHostApiImpl extends UIScrollViewHostApi {
/// Constructs a [UIScrollViewHostApiImpl].
UIScrollViewHostApiImpl({
BinaryMessenger? binaryMessenger,
super.binaryMessenger,
InstanceManager? instanceManager,
}) : instanceManager = instanceManager ?? NSObject.globalInstanceManager,
super(binaryMessenger: binaryMessenger);
}) : instanceManager = instanceManager ?? NSObject.globalInstanceManager;

/// Maintains instances stored to communicate with Objective-C objects.
final InstanceManager instanceManager;
Expand All @@ -31,7 +29,7 @@ class UIScrollViewHostApiImpl extends UIScrollViewHostApi {
UIScrollView instance,
WKWebView webView,
) {
final int instanceId = instanceManager.addFlutterCreatedInstance(instance);
final int instanceId = instanceManager.addDartCreatedInstance(instance);
return createFromWebView(
instanceId,
instanceManager.getIdentifier(webView)!,
Expand Down Expand Up @@ -77,10 +75,9 @@ class UIScrollViewHostApiImpl extends UIScrollViewHostApi {
class UIViewHostApiImpl extends UIViewHostApi {
/// Constructs a [UIViewHostApiImpl].
UIViewHostApiImpl({
BinaryMessenger? binaryMessenger,
super.binaryMessenger,
InstanceManager? instanceManager,
}) : instanceManager = instanceManager ?? NSObject.globalInstanceManager,
super(binaryMessenger: binaryMessenger);
}) : instanceManager = instanceManager ?? NSObject.globalInstanceManager;

/// Maintains instances stored to communicate with Objective-C objects.
final InstanceManager instanceManager;
Expand Down
Loading