Skip to content
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
6 changes: 6 additions & 0 deletions packages/tizen_rpc_port/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
## 0.1.7

* Guard Tizen 10.0+ specific Parcel APIs (`reader`, `dataSize`, and `reserve`) to throw `UnsupportedError` on unsupported versions of Tizen instead of crashing.
* Add integration test cases for the guarded Tizen 10.0+ specific Parcel APIs.
* Update README to mention system requirements for these APIs.

## 0.1.6

* Read byte values as unsigned (0-255) so `Parcel.readByte` is consistent
Expand Down
3 changes: 3 additions & 0 deletions packages/tizen_rpc_port/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,3 +47,6 @@ The following privileges may be added to the client app's `tizen-manifest.xml` f
## Supported devices

This plugin is supported on Tizen devices running Tizen 6.5 or above.

> **Note**
> Some `Parcel` APIs (`reader`, `dataSize`, and `reserve`) are supported only on Tizen 10.0 or above. Calling these APIs on unsupported versions of Tizen will throw an `UnsupportedError`.
Original file line number Diff line number Diff line change
Expand Up @@ -283,4 +283,39 @@ void main() {
expect(proxy.portName, 'TestPort');
});
});

// ---------------------------------------------------------------------------
// Tizen 10.0+ Parcel APIs (reader, dataSize, reserve) with safety guards
// ---------------------------------------------------------------------------

group('Tizen 10.0+ Parcel APIs', () {
testWidgets('reader getter/setter', (WidgetTester _) async {
final Parcel parcel = Parcel();
try {
parcel.reader = 10;
expect(parcel.reader, 10);
} on UnsupportedError catch (e) {
expect(e.message, contains('not supported on this version of Tizen'));
}
});

testWidgets('dataSize getter/setter', (WidgetTester _) async {
final Parcel parcel = Parcel();
try {
parcel.dataSize = 20;
expect(parcel.dataSize, 20);
} on UnsupportedError catch (e) {
expect(e.message, contains('not supported on this version of Tizen'));
}
});

testWidgets('reserve', (WidgetTester _) async {
final Parcel parcel = Parcel();
try {
parcel.reserve(100);
} on UnsupportedError catch (e) {
expect(e.message, contains('not supported on this version of Tizen'));
}
});
});
}
175 changes: 175 additions & 0 deletions packages/tizen_rpc_port/lib/src/parcel.dart
Original file line number Diff line number Diff line change
Expand Up @@ -484,4 +484,179 @@ class Parcel {
return ParcelHeader._fromHandle(pHeader.value);
});
}

/// Gets the reader position of this parcel.
int get reader {
_ensureFunctionsLoaded();
final int Function(rpc_port_parcel_h, Pointer<Uint32>)? func =
_rpcPortParcelGetReader;
if (func == null) {
throw UnsupportedError(
'The reader property is not supported on this version of Tizen.',
);
}
return using((Arena arena) {
final Pointer<Uint32> pValue = arena();
final int ret = func(_handle, pValue);
if (ret != 0) {
throw PlatformException(
code: ret.toString(),
message: tizen.get_error_message(ret).toDartString(),
);
}
return pValue.value;
});
}

/// Sets the reader position of this parcel.
set reader(int value) {
RangeError.checkNotNegative(value, 'value');
_ensureFunctionsLoaded();
final int Function(rpc_port_parcel_h, int)? func = _rpcPortParcelSetReader;
if (func == null) {
throw UnsupportedError(
'The reader property is not supported on this version of Tizen.',
);
}
final int ret = func(_handle, value);
if (ret != 0) {
throw PlatformException(
code: ret.toString(),
message: tizen.get_error_message(ret).toDartString(),
);
}
}
Comment thread
pjh9216 marked this conversation as resolved.

/// Gets the data size of this parcel.
int get dataSize {
_ensureFunctionsLoaded();
final int Function(rpc_port_parcel_h, Pointer<Uint32>)? func =
_rpcPortParcelGetDataSize;
if (func == null) {
throw UnsupportedError(
'The dataSize property is not supported on this version of Tizen.',
);
}
return using((Arena arena) {
final Pointer<Uint32> pValue = arena();
final int ret = func(_handle, pValue);
if (ret != 0) {
throw PlatformException(
code: ret.toString(),
message: tizen.get_error_message(ret).toDartString(),
);
}
return pValue.value;
});
}

/// Sets the data size of this parcel.
set dataSize(int value) {
RangeError.checkNotNegative(value, 'value');
_ensureFunctionsLoaded();
final int Function(rpc_port_parcel_h, int)? func =
_rpcPortParcelSetDataSize;
if (func == null) {
throw UnsupportedError(
'The dataSize property is not supported on this version of Tizen.',
);
}
final int ret = func(_handle, value);
if (ret != 0) {
throw PlatformException(
code: ret.toString(),
message: tizen.get_error_message(ret).toDartString(),
);
}
}
Comment thread
pjh9216 marked this conversation as resolved.

/// Reserves the capacity of this parcel.
void reserve(int size) {
RangeError.checkNotNegative(size, 'size');
_ensureFunctionsLoaded();
final int Function(rpc_port_parcel_h, int)? func = _rpcPortParcelReserve;
if (func == null) {
throw UnsupportedError(
'The reserve method is not supported on this version of Tizen.',
);
}
final int ret = func(_handle, size);
if (ret != 0) {
throw PlatformException(
code: ret.toString(),
message: tizen.get_error_message(ret).toDartString(),
);
}
}
Comment thread
pjh9216 marked this conversation as resolved.
}

DynamicLibrary? _libRpcPort;
bool _libRpcPortLoaded = false;

DynamicLibrary? _getLibRpcPort() {
if (!_libRpcPortLoaded) {
try {
_libRpcPort = DynamicLibrary.open('librpc-port.so.1');
} catch (_) {
_libRpcPort = null;
}
_libRpcPortLoaded = true;
}
return _libRpcPort;
}

int Function(rpc_port_parcel_h, Pointer<Uint32>)? _rpcPortParcelGetReader;
int Function(rpc_port_parcel_h, int)? _rpcPortParcelSetReader;
int Function(rpc_port_parcel_h, Pointer<Uint32>)? _rpcPortParcelGetDataSize;
int Function(rpc_port_parcel_h, int)? _rpcPortParcelSetDataSize;
int Function(rpc_port_parcel_h, int)? _rpcPortParcelReserve;

bool _functionsLoaded = false;

void _ensureFunctionsLoaded() {
if (_functionsLoaded) {
return;
}
_functionsLoaded = true;
final DynamicLibrary? lib = _getLibRpcPort();
if (lib == null) {
return;
}
try {
_rpcPortParcelGetReader = lib
.lookup<
NativeFunction<Int32 Function(rpc_port_parcel_h, Pointer<Uint32>)>>(
'rpc_port_parcel_get_reader',
)
.asFunction();
} catch (_) {}
try {
_rpcPortParcelSetReader = lib
.lookup<NativeFunction<Int32 Function(rpc_port_parcel_h, Uint32)>>(
'rpc_port_parcel_set_reader',
)
.asFunction();
} catch (_) {}
try {
_rpcPortParcelGetDataSize = lib
.lookup<
NativeFunction<Int32 Function(rpc_port_parcel_h, Pointer<Uint32>)>>(
'rpc_port_parcel_get_data_size',
)
.asFunction();
} catch (_) {}
try {
_rpcPortParcelSetDataSize = lib
.lookup<NativeFunction<Int32 Function(rpc_port_parcel_h, Uint32)>>(
'rpc_port_parcel_set_data_size',
)
.asFunction();
} catch (_) {}
try {
_rpcPortParcelReserve = lib
.lookup<NativeFunction<Int32 Function(rpc_port_parcel_h, Uint32)>>(
'rpc_port_parcel_reserve',
)
.asFunction();
} catch (_) {}
}
2 changes: 1 addition & 1 deletion packages/tizen_rpc_port/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ name: tizen_rpc_port
description: Tizen RPC Port APIs. Used to make remote procedure calls between Tizen apps.
homepage: https://github.com/flutter-tizen/plugins
repository: https://github.com/flutter-tizen/plugins/tree/master/packages/tizen_rpc_port
version: 0.1.6
version: 0.1.7

environment:
sdk: ">=3.1.0 <4.0.0"
Expand Down
Loading