Open dcharkes opened 7 months ago
Discussing with @mosuem we have multiple options that we can pursue with adding new asset types that are connected to existing asset types:
NativeCodeAsset.privacyManifest
Uri?
fieldIntroduce a NativeCodeAsset.privacyManifest
Uri?
field
output.addAssets([
NativeCodeAsset(
package: 'native_add',
name: 'native_add',
linkMode: DynamicLoadingBundled(),
os: OS.current,
architecture: Architecture.current,
file: builtDylibUri,
privacyManifestFile:
(OS.current == OS.macOS || OS.current == OS.iOS) ?
config.packageRoot.resolve('assets/PrivacyInfo.xcprivacy') :
null,
),
]);
BuildConfig.supportedAssetTypes
, but it's not used this way.)NativeCodeAsset
API for other OSes that don't have privacy manifests.PrivacyManifestAsset
with dylib
fieldIntroduce a PrivacyManifestAsset
which implements Asset
and has a field dylib
which points to a NativeCodeAsset
.
(Note the class should not implement/extend DataAsset
because the bytes should not be bundled in Dart/Flutter apps and accessible with data assets at runtime.)
output.addAssets([
NativeCodeAsset(
package: 'native_add',
name: 'native_add',
linkMode: DynamicLoadingBundled(),
os: OS.current,
architecture: Architecture.current,
file: builtDylibUri,
),
if (OS.current == OS.macOS || OS.current == OS.iOS)
PrivacyManifestAsset(
// Asset IDs are mandatory, and required to be unique at the moment.
package: 'native_add',
name: 'native_add/PrivacyInfo.xcprivacy',
// Together with `package` defines the asset ID that this privacy manifest belongs to.
nativeCodeAssetName: 'native_add',
file: config.packageRoot.resolve('assets/PrivacyInfo.xcprivacy'),
),
]);
NativeCodeAsset
, no API pollution.BuildConfig.supportedAssetTypes
.PrivacyManifest
and NativeCodeAsset
s to connect the ones that belong together.PrivacyManifest
needs to repeat the NativeCodeAsset
asset name/id.Asset.metadata
Introduce Asset.metadata
List<Asset>
field. (Name to be discussed)
This avoids the need for a PrivacyManifestAsset.dylib
field as the PrivacyManifestAsset
can be nested in the dylib
output.addAssets([
NativeCodeAsset(
package: 'native_add',
name: 'native_add',
linkMode: DynamicLoadingBundled(),
os: OS.current,
architecture: Architecture.current,
file: builtDylibUri,
metadata: [
if (OS.current == OS.macOS || OS.current == OS.iOS)
PrivacyManifestAsset(
// Asset IDs are mandatory, and required to be unique at the moment.
package: 'native_add',
name: 'native_add/PrivacyInfo.xcprivacy',
file: config.packageRoot.resolve('assets/native_add/PrivacyInfo.xcprivacy'),
),
],
),
]);
BuildConfig.supportedAssetTypes
.Asset.children
is quite generic, it might look like arbitrary children are supported in arbitrary asset types.@mosuem I think I'm leaning towards option 2 now as well.
We could opt to not specify this asset type in package:hook
/package:native_assets_cli
. It would enable us to battle-test the extensibility of the protocol.
However, I would also be weary of introducing a new package for every new asset type. It would create churn specifying all the imports for users. (We can't be putting it in package:hook_flutter
because once we start supporting it in Dart or another embedder it would have to be moved, and moving classes between packages is a real pain, I tried it once.)
cc @HosseinYousefi as well for discussion on how to deal with "assets-that-belong-to-other-assets" or "assets-that-augment-other-assets". ProguardRuleAsset
s augment JarAsset
s later on.
Option2, but in it's own package.
I would try to keep things simple, and have a new asset type for the PrivacyManifestAsset
defined in package:privacy_manifest_asset
, which also exposes helper methods for creating the asset. Then all that has to be done is implement support for PrivacyManifestAsset
in Flutter.
class PrivacyManifestAsset implements Asset{
final Sting nativeCodeAssetId;
...
}
Asset buildPrivacyManifest(NativeCodeAsset library, PrivacyManifestOptions options) { ... }
It would create churn specifying all the imports for users.
What do you mean?
In the most general form, the thing we're building could be a graph, not a tree. So using children
-like API will not scale. So I like option 2 as well.
and moving classes between packages is a real pain
What if hook_flutter
has a dependency on the privacy_manifest_asset
but just exports it. The user will transitively depend on privacy_manifest_asset
and won't have to import another thing. Later on if the same thing is available on dart standalone, hook
itself can export the same class. Would this work?
Note from discussion with @mkustermann
NativeCodeAsset
s. So that leans towards option 1. This not only important for embedders consuming assets, but also for if you're writing a link hook helper package that links native code static libs together.Deprioritizing because the list of required reason APIs is quite small.
When using something like the camera on iOS/MacOS, the dylib needs to be bundled with a privacy manifest about why the permission is needed.
We need some way to communicate a privacy manifest from
build.dart
to Flutter.This could possibly be a new asset type.
We need to check if we need a privacy manifest per dylib or just per Dart package.