-
-
Notifications
You must be signed in to change notification settings - Fork 239
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
iOS copy native replay screenshot in-memory to native (#2530)
* iOS copy native replay screenshot in-memory to native * formatting * fix tests on web * chore: changelog * cleanups * fix wasm test * objc syntax error * comment
- Loading branch information
Showing
8 changed files
with
226 additions
and
37 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
import 'dart:ffi'; | ||
import 'dart:typed_data'; | ||
|
||
import 'package:meta/meta.dart'; | ||
import 'package:ffi/ffi.dart' as pkg_ffi; | ||
|
||
@internal | ||
@immutable | ||
class NativeMemory { | ||
final Pointer<Uint8> pointer; | ||
final int length; | ||
|
||
const NativeMemory._(this.pointer, this.length); | ||
|
||
factory NativeMemory.fromUint8List(Uint8List source) { | ||
final length = source.length; | ||
final ptr = pkg_ffi.malloc.allocate<Uint8>(length); | ||
if (length > 0) { | ||
ptr.asTypedList(length).setAll(0, source); | ||
} | ||
return NativeMemory._(ptr, length); | ||
} | ||
|
||
factory NativeMemory.fromJson(Map<dynamic, dynamic> json) { | ||
final length = json['length'] as int; | ||
final ptr = Pointer<Uint8>.fromAddress(json['address'] as int); | ||
return NativeMemory._(ptr, length); | ||
} | ||
|
||
/// Frees the underlying native memory. | ||
/// You must not use this object after freeing. | ||
/// | ||
/// Currently, we only need to do this in tests because there's no native | ||
/// counterpart to free the memory. | ||
@visibleForTesting | ||
void free() => pkg_ffi.malloc.free(pointer); | ||
|
||
Uint8List asTypedList() => pointer.asTypedList(length); | ||
|
||
Map<String, int> toJson() => { | ||
'address': pointer.address, | ||
'length': length, | ||
}; | ||
} | ||
|
||
@internal | ||
extension Uint8ListNativeMemory on Uint8List { | ||
NativeMemory toNativeMemory() => NativeMemory.fromUint8List(this); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
@TestOn('vm') | ||
library flutter_test; | ||
|
||
import 'dart:typed_data'; | ||
|
||
import 'package:flutter_test/flutter_test.dart'; | ||
import 'native_memory_web_mock.dart' | ||
if (dart.library.io) 'package:sentry_flutter/src/native/native_memory.dart'; | ||
|
||
void main() { | ||
final testSrcList = Uint8List.fromList([1, 2, 3]); | ||
|
||
test('empty list', () async { | ||
final sut = NativeMemory.fromUint8List(Uint8List.fromList([])); | ||
expect(sut.length, 0); | ||
expect(sut.pointer.address, greaterThan(0)); | ||
expect(sut.asTypedList(), isEmpty); | ||
sut.free(); | ||
}); | ||
|
||
test('non-empty list', () async { | ||
final sut = NativeMemory.fromUint8List(testSrcList); | ||
expect(sut.length, 3); | ||
expect(sut.pointer.address, greaterThan(0)); | ||
expect(sut.asTypedList(), testSrcList); | ||
sut.free(); | ||
}); | ||
|
||
test('json', () async { | ||
final sut = NativeMemory.fromUint8List(testSrcList); | ||
final json = sut.toJson(); | ||
expect(json['address'], greaterThan(0)); | ||
expect(json['length'], 3); | ||
expect(json.entries, hasLength(2)); | ||
|
||
final sut2 = NativeMemory.fromJson(json); | ||
expect(sut2.toJson(), json); | ||
expect(sut2.asTypedList(), testSrcList); | ||
|
||
expect(sut.pointer, sut2.pointer); | ||
expect(sut.length, sut2.length); | ||
sut2.free(); | ||
}); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
import 'dart:math'; | ||
import 'dart:typed_data'; | ||
|
||
// This is just a mock so `flutter test --platform chrome` works. | ||
// See https://github.com/flutter/flutter/issues/160675 | ||
class NativeMemory { | ||
final Pointer<Uint8> pointer; | ||
final int length; | ||
|
||
const NativeMemory._(this.pointer, this.length); | ||
|
||
factory NativeMemory.fromUint8List(Uint8List source) { | ||
return NativeMemory._(Pointer<Uint8>._store(source), source.length); | ||
} | ||
|
||
factory NativeMemory.fromJson(Map<dynamic, dynamic> json) { | ||
return NativeMemory._( | ||
Pointer<Uint8>._load(json['address'] as int), json['length'] as int); | ||
} | ||
|
||
void free() {} | ||
|
||
Uint8List asTypedList() => _memory[pointer.address]!; | ||
|
||
Map<String, int> toJson() => { | ||
'address': pointer.address, | ||
'length': length, | ||
}; | ||
} | ||
|
||
class Pointer<T> { | ||
final int address; | ||
|
||
const Pointer(this.address); | ||
|
||
factory Pointer._store(Uint8List data) { | ||
final address = Random().nextInt(999999); | ||
_memory[address] = data; | ||
return Pointer(address); | ||
} | ||
|
||
factory Pointer._load(int address) { | ||
return Pointer(address); | ||
} | ||
|
||
/// Equality for Pointers only depends on their address. | ||
@override | ||
bool operator ==(Object other) { | ||
if (other is! Pointer) return false; | ||
return address == other.address; | ||
} | ||
|
||
/// The hash code for a Pointer only depends on its address. | ||
@override | ||
int get hashCode => address.hashCode; | ||
} | ||
|
||
class Uint8 {} | ||
|
||
final _memory = <int, Uint8List>{}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters