diff --git a/.gitignore b/.gitignore index 5dee144..f85ac72 100644 --- a/.gitignore +++ b/.gitignore @@ -2,8 +2,10 @@ .gclient .gclient_entries .gclient_previous_* +.gcs_entries .cipd/ buildtools/ +engine/ sdk/ # Root scratch output. diff --git a/dart-sdk-new b/dart-sdk-new index 08139af..57b27a7 160000 --- a/dart-sdk-new +++ b/dart-sdk-new @@ -1 +1 @@ -Subproject commit 08139af589d0d32fbdec64b127c075ea3427cde8 +Subproject commit 57b27a7b44a9112c7cb3a1cb3c73636fc149bd16 diff --git a/depot_tools b/depot_tools index 90f5d4d..a8c9ac9 160000 --- a/depot_tools +++ b/depot_tools @@ -1 +1 @@ -Subproject commit 90f5d4d14de66a5aae4a55b554ad4565111169af +Subproject commit a8c9ac983296908f8d662cb23ad6b8a0cae890b2 diff --git a/docs/PLATFORM_TESTING.md b/docs/PLATFORM_TESTING.md index b8944f6..95fb522 100644 --- a/docs/PLATFORM_TESTING.md +++ b/docs/PLATFORM_TESTING.md @@ -1,4 +1,4 @@ -# Linux And macOS Platform Testing +# Linux, macOS, and iOS Platform Testing The first complete runtime proof was built on Windows. The next platform pass should verify the same source layout on Linux and macOS, then use macOS to @@ -51,6 +51,14 @@ Useful environment variables: | `FLUTTER_BIN=/path/to/flutter` | Override the Flutter executable. | | `GO_BIN=/path/to/go` | Override the Go executable. | | `RUN_IOS_SMOKE=1` | On macOS, run a no-codesign iOS build smoke check when Flutter/Xcode are available. | +| `INCLUDE_ENGINE_DEPS=1` | On macOS, write the Flutter engine `.gclient` and include iOS, Android, and web/emsdk dependencies. | +| `AOT_PATCH_BUILD_DIR=/path/to/build` | Override the Dart SDK AOT patch build used by the license/flavor verifier. | +| `IOS_ENGINE_DIR=/path/to/ios_release` | Override the iOS engine build checked by `verify_ios_interpreter_route.sh`. | +| `HOST_ENGINE_DIR=/path/to/host_release_arm64` | Override the host engine build checked by `verify_ios_interpreter_route.sh`. | +| `IOS_APP_BUNDLE=/path/to/Runner.app` | Optionally verify that a reviewed app bundle does not contain a seeded patch payload. | +| `IOS_IPA=/path/to/App.ipa` | Optionally verify the `Payload/*.app` inside an IPA instead of a raw app bundle. | +| `IOS_PATCH_ARTIFACT=/path/to/dlc.vmcode` | Optionally verify that the patch artifact is an encrypted iOS arm64 interpreter full-snapshot artifact. | +| `APP_STORE_STRICT=1` | Fail the iOS route check when App Store-inappropriate signing state, such as `get-task-allow=true`, is present. | ## Expected Checks @@ -63,19 +71,235 @@ The bootstrap scripts run: 5. Shorebird CLI focused tests for self-hosted `base_url` behavior 6. open AOT patch tool tests 7. self-hosted server Go tests -8. license/flavor AOT verification when `dart-sdk-new/out/ReleaseX64AotPatch/args.gn` - already exists +8. license/flavor AOT verification when an AOT patch SDK build already exists. + The verifier checks `AOT_PATCH_BUILD_DIR` first, then common local outputs + such as `dart-sdk-new/xcodebuild/ReleaseARM64`, + `dart-sdk-new/out/ReleaseARM64AotPatch`, and + `dart-sdk-new/out/ReleaseX64AotPatch`. +9. iOS interpreter route verification when local `ios_release` and + `host_release_arm64` engine args exist. This checks that + `DART_DYNAMIC_MODULES` is off, the no-DDM interpreter route is on for both + the device engine and host snapshotter, and the native AOT patch path is off + for iOS. ## iOS Preparation Notes -The macOS script writes: +The macOS script writes this minimal root `.gclient` by default: ```python target_os = ["mac", "ios"] ``` -That prepares gclient for iOS dependencies. The actual iOS runtime test should -still be run later on macOS after the Flutter engine/Dart SDK patch build is -available. The AOT patching design remains iOS-compatible only if patch loading -uses mapped snapshot data/instructions and does not rely on JIT, the KBC -interpreter, or writable executable memory. +Set `INCLUDE_ENGINE_DEPS=1` to also write `flutter/.gclient` and include +Android plus web/emsdk engine dependencies: + +```python +target_os = ["mac", "ios", "android"] +``` + +The native AOT `.vmcode` path is useful for development-device validation, but +it is not the iOS App Store candidate route because it maps downloaded native +snapshot text as executable memory. The iOS interpreter route keeps +`DART_DYNAMIC_MODULES` disabled and uses the Dart SDK's no-DDM interpreter patch +runtime mode instead of loading native AOT code directly. Real App Store or +TestFlight acceptance still has to be proven through Apple's review flow. + +Use this gate before producing an App Store/TestFlight archive: + +```sh +IOS_APP_BUNDLE=testapps/license_flavor_patch_test/build/ios/iphoneos/Runner.app \ + IOS_PATCH_ARTIFACT=/path/to/shorebird_updater/patches/1/dlc.vmcode \ + APP_STORE_STRICT=1 \ + ./scripts/verify_ios_interpreter_route.sh +``` + +For an exported IPA, use: + +```sh +IOS_IPA=/path/to/App.ipa APP_STORE_STRICT=1 \ + ./scripts/verify_ios_interpreter_route.sh +``` + +The app-bundle/IPA check is intentionally limited to review hygiene and +executable-memory risk indicators: a submitted app should not include a +pre-seeded `shorebird_updater` directory or `dlc.vmcode` payload, should not +request JIT or unsigned-executable-memory entitlements, and should not have +`get-task-allow=true` in strict mode. When `IOS_PATCH_ARTIFACT` is set, the gate +also rejects Mach-O and ELF patch files and requires the encrypted open artifact +metadata to declare `runtime_mode=dart-bytecode-interpreter`, `target_os=ios`, +`target_arch=arm64`, and `payload_kind=full-snapshot`. Real patches should +arrive through the updater after the reviewed app is installed. + +## iOS Device Results + +On June 24, 2026, a physical iPad Pro 13-inch (M4), iOS 26.5, successfully ran +the license/flavor patch test in release mode with the local `ios_release` +engine and `host_release_arm64` host engine. + +The working development proof used a free baseline app installed on device and a +pro AOT Mach-O patch seeded into: + +```text +Library/Application Support/shorebird/shorebird_updater/patches/1/dlc.vmcode +``` + +The patch payload must be signed with a valid Apple development/distribution +identity. An ad-hoc signed payload reached the updater but failed during +executable mapping with `mmap failed Operation not permitted`. Re-signing the +patch Mach-O with the Apple Development identity allowed the release app to boot +from patch `1`; the updater state promoted `last_booted_patch` to `1`, and an +instrumented pro payload wrote: + +```text +license:pro +pro-feature:enabled +``` + +This result proves updater selection, metadata compatibility, signing +requirements, and the native development path. It does not make native AOT patch +execution App Store-safe. The iOS App Store candidate test target is the +interpreter runtime mode (`runtime_mode=dart-bytecode-interpreter`) with +`DART_DYNAMIC_MODULES` disabled. + +On June 24, 2026, the local `ios_release` engine also built successfully with +the no-DDM interpreter configuration: + +```gn +dart_dynamic_modules = false +dart_enable_aot_patching = true +dart_enable_shorebird_interpreter = true +shorebird_use_interpreter = true +shorebird_enable_aot_patching = false +``` + +The matching host `gen_snapshot` build must also enable the no-DDM interpreter +path when it is used to produce iOS AOT snapshots: + +```sh +flutter/tools/gn --runtime-mode=release --mac-cpu=arm64 \ + --target-dir=host_release_arm64 --shorebird-interpreter +ninja -C out/host_release_arm64 gen_snapshot +``` + +Without the host-side interpreter flag, the generated app snapshot can bind AOT +static calls directly to base `Code` objects and omit the static-call metadata +that the iOS interpreter runtime uses to enter patched bytecode. + +The current open-source interpreter path wires the no-DDM artifact handoff and +an initial product-AOT function replacement mapper. Interpreter-mode artifacts +now force and validate `payload_kind=full-snapshot`; compact interpreter diffs +are rejected until runtime reconstruction exists. The engine can hand an +encrypted open patch artifact to `Dart_InstallAotPatch`, decrypt it with an +explicit `shorebird.yaml` AES key, verify the decrypted payload is Dart +bytecode, and install it through `Dart_ReloadBytecodePatch`. + +For product iOS AOT, `Dart_ReloadBytecodePatch` no longer uses stock VM reload. +It reads patch bytecode as data, maps declarations to already-loaded +libraries/classes/functions, and switches matched existing functions to the VM's +signed `InterpretCall` stub with `Function::AttachBytecode`. This updates VM +heap metadata only; it does not load native AOT patch files, map downloaded +text executable, or enable `DART_DYNAMIC_MODULES`. + +On June 25, 2026, the no-DDM interpreter route was verified on the same real +iPad. The app was built as a release iOS app with the local `ios_release` engine +and `host_release_arm64` snapshotter, then installed on device: + +```sh +flutter build ios --release \ + --local-engine-src-path=/Users/tonylu/git/shorebird-workspace/flutter/engine/src \ + --local-engine=ios_release \ + --local-engine-host=host_release_arm64 \ + --dart-define=LICENSE_TYPE=free + +xcrun devicectl device install app \ + --device 3289ED7F-552F-59D2-984F-AAE78463DA70 \ + testapps/license_flavor_patch_test/build/ios/iphoneos/Runner.app \ + --timeout 120 +``` + +The patch seed was copied into the app container: + +```text +Library/Application Support/shorebird/shorebird_updater/ +``` + +with these files: + +```text +patches/1/dlc.vmcode +patches/1/state.json +pointers.json +state.json +``` + +Launching the app with that seeded patch displayed: + +```text +license:pro +``` + +This verifies the real-device interpreter patch flow for an existing-function +full-snapshot bytecode payload: updater selection, artifact decryption, +`Dart_ReloadBytecodePatch`, bytecode attachment, and static-call dispatch all +worked in a release iOS app on physical hardware. + +The current release app bundle also passes the stricter pre-review route gate: + +```sh +APP_STORE_STRICT=1 \ +IOS_APP_BUNDLE=testapps/license_flavor_patch_test/build/ios/iphoneos/Runner.app \ +IOS_PATCH_ARTIFACT=/private/tmp/shorebird-seed-main/shorebird_updater/patches/1/dlc.vmcode \ + ./scripts/verify_ios_interpreter_route.sh +``` + +This verified the generated iOS and host engine args, found no bundled +`shorebird_updater` or `dlc.vmcode` payload in the app bundle, found no JIT or +unsigned-executable-memory entitlement, confirmed `get-task-allow` is not true, +and verified that the seeded patch artifact is an encrypted interpreter +full-snapshot for iOS arm64. Passing a Mach-O binary as `IOS_PATCH_ARTIFACT` +correctly fails the route gate. + +The remaining App Store/TestFlight proof is a distribution test, not a local +build test: + +1. Export the reviewed app as an App Store/TestFlight IPA. +2. Run the route gate: + + ```sh + APP_STORE_STRICT=1 \ + IOS_IPA=/path/to/App.ipa \ + IOS_PATCH_ARTIFACT=/path/to/dlc.vmcode \ + ./scripts/verify_ios_interpreter_route.sh + ``` + +3. Upload the IPA to App Store Connect and install it through TestFlight or the + App Store. +4. Publish or seed the interpreter patch after that reviewed app is installed. +5. Relaunch the installed app and verify the app displays the patched behavior + (`license:pro` for the current smoke app). + +This is still a runtime milestone, not a complete App Store proof. The mapper +currently targets existing libraries/classes/functions only. The patch compiler +must emit an interpreter payload in that compatible shape, and compact +reconstruction still needs to move into the SDK before compact bytecode patches +can be accepted. + +For development-device encrypted interpreter tests, `shorebird.yaml` may include +these top-level fields: + +```yaml +aot_patch_key_id: test-key +aot_patch_key_hex: 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +aot_patch_base_flavor_id: free +aot_patch_base_license_type: free +aot_patch_flavor_id: pro +aot_patch_license_type: pro +aot_patch_sdk_hash: +aot_patch_base_snapshot_hash: +``` + +The YAML key path is only the first open bridge for local verification. A +production App Store implementation still needs an app-owned key callback or +equivalent secure key source, a verified compatible interpreter payload +compiler, compact interpreter reconstruction, and TestFlight/App Store review +validation. diff --git a/flutter b/flutter index 9754ce0..542e6e8 160000 --- a/flutter +++ b/flutter @@ -1 +1 @@ -Subproject commit 9754ce03d76fb06c23a72ddbd8b7137bfa85446c +Subproject commit 542e6e89c85435b9c0662ba5e89b4eae2c2e3e2b diff --git a/scripts/platform_test_common.sh b/scripts/platform_test_common.sh index 7f0d4d6..a217410 100755 --- a/scripts/platform_test_common.sh +++ b/scripts/platform_test_common.sh @@ -55,12 +55,34 @@ run bash -lc "cd '$ROOT/shorebird/packages/shorebird_cli' && '$DART_BIN' pub get run bash -lc "cd '$ROOT/shorebird/packages/open_aot_patch_tools' && '$DART_BIN' pub get && '$DART_BIN' test" run bash -lc "cd '$ROOT/shorebird-server' && '$GO_BIN' test ./..." -AOT_ARGS="$ROOT/dart-sdk-new/out/ReleaseX64AotPatch/args.gn" -if [[ -f "$AOT_ARGS" ]]; then - run bash -lc "cd '$ROOT/testapps/license_flavor_patch_test' && '$FLUTTER_BIN' pub get && '$DART_BIN' run tool/verify_aot_patch.dart" +AOT_PATCH_BUILD_DIR="${AOT_PATCH_BUILD_DIR:-}" +if [[ -z "$AOT_PATCH_BUILD_DIR" ]]; then + for candidate in \ + "$ROOT/dart-sdk-new/xcodebuild/ReleaseARM64" \ + "$ROOT/dart-sdk-new/out/ReleaseARM64AotPatch" \ + "$ROOT/dart-sdk-new/out/ReleaseX64AotPatch"; do + if [[ -f "$candidate/args.gn" ]]; then + AOT_PATCH_BUILD_DIR="$candidate" + break + fi + done +fi + +if [[ -n "$AOT_PATCH_BUILD_DIR" && -f "$AOT_PATCH_BUILD_DIR/args.gn" ]]; then + run bash -lc "cd '$ROOT/testapps/license_flavor_patch_test' && '$FLUTTER_BIN' pub get && AOT_PATCH_BUILD_DIR='$AOT_PATCH_BUILD_DIR' '$DART_BIN' run tool/verify_aot_patch.dart" else echo - echo "==> skipping license/flavor AOT verification; missing $AOT_ARGS" + echo "==> skipping license/flavor AOT verification; missing AOT patch args.gn" +fi + +if [[ "$PLATFORM" == "macos" ]]; then + if [[ -f "$ROOT/flutter/engine/src/out/ios_release/args.gn" && + -f "$ROOT/flutter/engine/src/out/host_release_arm64/args.gn" ]]; then + run "$ROOT/scripts/verify_ios_interpreter_route.sh" + else + echo + echo "==> skipping iOS interpreter route verification; missing ios_release or host_release_arm64 args.gn" + fi fi if [[ "$PLATFORM" == "macos" && "${RUN_IOS_SMOKE:-0}" == "1" ]]; then diff --git a/scripts/sync_open_sources.sh b/scripts/sync_open_sources.sh index 5e067df..41115f3 100755 --- a/scripts/sync_open_sources.sh +++ b/scripts/sync_open_sources.sh @@ -2,21 +2,56 @@ set -euo pipefail ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +DART_SRC="${DART_SRC:-$ROOT/dart-sdk-new}" +DART_TARGET="$ROOT/flutter/engine/src/flutter/third_party/dart" UPDATER_SRC="${UPDATER_SRC:-$ROOT/updater}" UPDATER_URL="${UPDATER_URL:-https://github.com/shorebirdtech/updater.git}" TARGET="$ROOT/flutter/engine/src/flutter/third_party/updater" +is_git_checkout() { + git -C "$1" rev-parse --git-dir >/dev/null 2>&1 +} + +echo "[open-source-sync] dart source: $DART_SRC" +echo "[open-source-sync] dart target: $DART_TARGET" echo "[open-source-sync] updater source: $UPDATER_SRC" echo "[open-source-sync] target: $TARGET" +mkdir -p "$(dirname "$DART_TARGET")" mkdir -p "$(dirname "$TARGET")" +if [[ -L "$DART_TARGET" ]]; then + echo "[open-source-sync] Dart target is already a symlink." +elif is_git_checkout "$DART_TARGET"; then + echo "[open-source-sync] Dart target is already a git checkout." +elif [[ -e "$DART_TARGET" ]]; then + echo "Dart target exists but is not a symlink or git checkout: $DART_TARGET" >&2 + exit 1 +elif is_git_checkout "$DART_SRC"; then + rel_target="$(python3 - "$DART_TARGET" "$DART_SRC" <<'PY' +import os +import sys +print(os.path.relpath(sys.argv[2], os.path.dirname(sys.argv[1]))) +PY +)" + ln -s "$rel_target" "$DART_TARGET" + echo "[open-source-sync] linked Dart SDK checkout into Flutter engine." +else + echo "Dart source checkout is missing: $DART_SRC" >&2 + exit 1 +fi + +if [[ ! -f "$DART_TARGET/runtime/vm/dart_api_impl.h" ]]; then + echo "Dart checkout is missing runtime/vm/dart_api_impl.h" >&2 + exit 1 +fi + if [[ -L "$TARGET" ]]; then echo "[open-source-sync] updater target is already a symlink." exit 0 fi -if [[ -d "$TARGET/.git" ]]; then +if is_git_checkout "$TARGET"; then echo "[open-source-sync] updating existing updater checkout." git -C "$TARGET" fetch --tags origin git -C "$TARGET" checkout "${UPDATER_REVISION:-main}" @@ -26,7 +61,7 @@ if [[ -d "$TARGET/.git" ]]; then elif [[ -e "$TARGET" ]]; then echo "target exists but is not a symlink or git checkout: $TARGET" >&2 exit 1 -elif [[ -d "$UPDATER_SRC/.git" ]]; then +elif is_git_checkout "$UPDATER_SRC"; then rel_target="$(python3 - "$TARGET" "$UPDATER_SRC" <<'PY' import os import sys diff --git a/scripts/verify_ios_interpreter_route.sh b/scripts/verify_ios_interpreter_route.sh new file mode 100755 index 0000000..7a34eff --- /dev/null +++ b/scripts/verify_ios_interpreter_route.sh @@ -0,0 +1,245 @@ +#!/usr/bin/env bash +set -euo pipefail + +ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +IOS_ENGINE_DIR="${IOS_ENGINE_DIR:-$ROOT/flutter/engine/src/out/ios_release}" +HOST_ENGINE_DIR="${HOST_ENGINE_DIR:-$ROOT/flutter/engine/src/out/host_release_arm64}" +IOS_APP_BUNDLE="${IOS_APP_BUNDLE:-}" +IOS_IPA="${IOS_IPA:-}" +IOS_PATCH_ARTIFACT="${IOS_PATCH_ARTIFACT:-}" +APP_STORE_STRICT="${APP_STORE_STRICT:-0}" + +CHECKED_APP_BUNDLE="" +CHECKED_IPA="" +CHECKED_PATCH_ARTIFACT="" +ENTITLEMENTS_CHECKED=0 +APP_STORE_STRICT_CHECKED=0 +CLEANUP_DIR="" + +cleanup() { + if [[ -n "$CLEANUP_DIR" && -d "$CLEANUP_DIR" ]]; then + rm -rf "$CLEANUP_DIR" + fi +} +trap cleanup EXIT + +fail() { + echo "error: $*" >&2 + exit 1 +} + +read_gn_value() { + local file="$1" + local key="$2" + awk -v key="$key" ' + $1 == key && $2 == "=" { + value = $0 + sub("^[[:space:]]*" key "[[:space:]]*=[[:space:]]*", "", value) + print value + found = 1 + exit + } + END { + if (!found) { + exit 1 + } + } + ' "$file" +} + +require_gn_value() { + local file="$1" + local key="$2" + local expected="$3" + local actual + if ! actual="$(read_gn_value "$file" "$key")"; then + fail "$file is missing required GN arg $key" + fi + if [[ "$actual" != "$expected" ]]; then + fail "$file has $key = $actual; expected $expected" + fi +} + +verify_ios_engine_args() { + local args_file="$IOS_ENGINE_DIR/args.gn" + [[ -f "$args_file" ]] || fail "missing iOS engine args: $args_file" + + require_gn_value "$args_file" target_os '"ios"' + require_gn_value "$args_file" dart_dynamic_modules false + require_gn_value "$args_file" dart_enable_shorebird_interpreter true + require_gn_value "$args_file" shorebird_use_interpreter true + require_gn_value "$args_file" shorebird_enable_aot_patching false +} + +verify_host_engine_args() { + local args_file="$HOST_ENGINE_DIR/args.gn" + [[ -f "$args_file" ]] || fail "missing host engine args: $args_file" + + require_gn_value "$args_file" target_os '"mac"' + require_gn_value "$args_file" dart_dynamic_modules false + require_gn_value "$args_file" dart_enable_shorebird_interpreter true + require_gn_value "$args_file" shorebird_use_interpreter true +} + +app_bundle_from_ipa() { + [[ -f "$IOS_IPA" ]] || fail "missing iOS IPA: $IOS_IPA" + command -v unzip >/dev/null 2>&1 || fail "unzip is required to inspect IOS_IPA" + + CLEANUP_DIR="$(mktemp -d "${TMPDIR:-/tmp}/ios-route.XXXXXX")" + unzip -qq "$IOS_IPA" -d "$CLEANUP_DIR" + + local payload_dir="$CLEANUP_DIR/Payload" + [[ -d "$payload_dir" ]] || fail "IPA does not contain a Payload directory" + + local app_bundle + app_bundle="$(find "$payload_dir" -maxdepth 1 -type d -name "*.app" -print -quit)" + [[ -n "$app_bundle" ]] || fail "IPA does not contain a Payload/*.app bundle" + IOS_APP_BUNDLE="$app_bundle" + CHECKED_IPA="$IOS_IPA" +} + +verify_entitlements() { + local app_bundle="$1" + local entitlements + + if ! command -v codesign >/dev/null 2>&1; then + if [[ "$APP_STORE_STRICT" == "1" ]]; then + fail "codesign is required for APP_STORE_STRICT=1 entitlement checks" + fi + echo "warning: codesign not found; skipping entitlement checks" >&2 + return 0 + fi + + if ! entitlements="$(codesign -d --entitlements :- "$app_bundle" 2>/dev/null)"; then + if [[ "$APP_STORE_STRICT" == "1" ]]; then + fail "failed to read app entitlements with codesign: $app_bundle" + fi + echo "warning: failed to read app entitlements; skipping entitlement checks" >&2 + return 0 + fi + + local forbidden_entitlements=( + "com.apple.security.cs.allow-jit" + "com.apple.security.cs.allow-unsigned-executable-memory" + "com.apple.security.cs.disable-executable-page-protection" + "com.apple.security.cs.dynamic-codesigning" + ) + local entitlement + for entitlement in "${forbidden_entitlements[@]}"; do + if grep -Fq "$entitlement" <<<"$entitlements"; then + fail "app entitlement enables executable-memory behavior: $entitlement" + fi + done + + ENTITLEMENTS_CHECKED=1 + + if [[ "$APP_STORE_STRICT" == "1" ]]; then + local compact_entitlements + compact_entitlements="$(printf '%s' "$entitlements" | tr -d '\n\r\t ')" + if grep -Fq "get-task-allow" <<<"$compact_entitlements"; then + fail "APP_STORE_STRICT=1 rejects development entitlement get-task-allow=true" + fi + APP_STORE_STRICT_CHECKED=1 + fi +} + +verify_app_bundle() { + if [[ -n "$IOS_APP_BUNDLE" && -n "$IOS_IPA" ]]; then + fail "set only one of IOS_APP_BUNDLE or IOS_IPA" + fi + if [[ -n "$IOS_IPA" ]]; then + app_bundle_from_ipa + fi + [[ -n "$IOS_APP_BUNDLE" ]] || return 0 + [[ -d "$IOS_APP_BUNDLE" ]] || fail "missing iOS app bundle: $IOS_APP_BUNDLE" + CHECKED_APP_BUNDLE="$IOS_APP_BUNDLE" + + local bundled_patch + bundled_patch="$( + find "$IOS_APP_BUNDLE" \ + \( -path "*/shorebird_updater/*" -o -name "dlc.vmcode" \) \ + -print -quit + )" + if [[ -n "$bundled_patch" ]]; then + fail "reviewed app bundle contains a seeded patch payload: $bundled_patch" + fi + + verify_entitlements "$IOS_APP_BUNDLE" +} + +file_magic_hex() { + od -An -tx1 -N4 "$1" | tr -d ' \n' +} + +verify_patch_artifact() { + [[ -n "$IOS_PATCH_ARTIFACT" ]] || return 0 + [[ -f "$IOS_PATCH_ARTIFACT" ]] || fail "missing iOS patch artifact: $IOS_PATCH_ARTIFACT" + + local magic + magic="$(file_magic_hex "$IOS_PATCH_ARTIFACT")" + case "$magic" in + feedface|cefaedfe|feedfacf|cffaedfe) + fail "iOS interpreter route must not use a Mach-O native patch artifact: $IOS_PATCH_ARTIFACT" + ;; + 7f454c46) + fail "iOS interpreter route must not use an ELF native patch artifact: $IOS_PATCH_ARTIFACT" + ;; + esac + + local compact_json + compact_json="$(LC_ALL=C tr -d '[:space:]' < "$IOS_PATCH_ARTIFACT")" + + if [[ "$compact_json" != \{* ]]; then + fail "iOS patch artifact must be the encrypted open JSON wrapper, not a raw native/code payload" + fi + if ! grep -Fq '"format":"open-aot-vmcode-encrypted-v1"' <<<"$compact_json"; then + fail "iOS patch artifact is not an open encrypted VM code artifact" + fi + if grep -Fq '"runtime_mode":"dart-dynamic-modules"' <<<"$compact_json" || + grep -Fq '"runtime_mode":"dynamic-modules"' <<<"$compact_json"; then + fail "iOS patch artifact uses DART_DYNAMIC_MODULES runtime mode" + fi + if ! grep -Fq '"runtime_mode":"dart-bytecode-interpreter"' <<<"$compact_json"; then + fail "iOS patch artifact must declare runtime_mode dart-bytecode-interpreter" + fi + if ! grep -Fq '"target_os":"ios"' <<<"$compact_json"; then + fail "iOS patch artifact must target iOS" + fi + if ! grep -Fq '"target_arch":"arm64"' <<<"$compact_json"; then + fail "iOS patch artifact must target arm64" + fi + if ! grep -Fq '"payload_kind":"full-snapshot"' <<<"$compact_json"; then + fail "current iOS interpreter mapper requires payload_kind full-snapshot" + fi + + CHECKED_PATCH_ARTIFACT="$IOS_PATCH_ARTIFACT" +} + +verify_ios_engine_args +verify_host_engine_args +verify_app_bundle +verify_patch_artifact + +cat <" >&2 @@ -27,7 +35,7 @@ solutions = [ "custom_deps": {}, "custom_vars": { "dart_root": "dart-sdk-new", - "download_android_deps": False, + "download_android_deps": $DART_DOWNLOAD_ANDROID_DEPS, "checkout_javascript_engines": False, "checkout_benchmarks_internal": False, "checkout_flute": False, @@ -38,3 +46,57 @@ target_os = $TARGET_OS EOF echo "Wrote $ROOT/.gclient for $PLATFORM with target_os = $TARGET_OS" + +if [[ "$INCLUDE_ENGINE_DEPS" == "1" ]]; then + cat > "$ROOT/flutter/.gclient" < + + + diff --git a/testapps/license_flavor_patch_test/android/app/src/main/AndroidManifest.xml b/testapps/license_flavor_patch_test/android/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..40edf5e --- /dev/null +++ b/testapps/license_flavor_patch_test/android/app/src/main/AndroidManifest.xml @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/testapps/license_flavor_patch_test/android/app/src/main/kotlin/com/example/licenseflavorpatchtest/license_flavor_patch_test/MainActivity.kt b/testapps/license_flavor_patch_test/android/app/src/main/kotlin/com/example/licenseflavorpatchtest/license_flavor_patch_test/MainActivity.kt new file mode 100644 index 0000000..707be44 --- /dev/null +++ b/testapps/license_flavor_patch_test/android/app/src/main/kotlin/com/example/licenseflavorpatchtest/license_flavor_patch_test/MainActivity.kt @@ -0,0 +1,5 @@ +package com.example.licenseflavorpatchtest.license_flavor_patch_test + +import io.flutter.embedding.android.FlutterActivity + +class MainActivity : FlutterActivity() diff --git a/testapps/license_flavor_patch_test/android/app/src/main/res/drawable-v21/launch_background.xml b/testapps/license_flavor_patch_test/android/app/src/main/res/drawable-v21/launch_background.xml new file mode 100644 index 0000000..f74085f --- /dev/null +++ b/testapps/license_flavor_patch_test/android/app/src/main/res/drawable-v21/launch_background.xml @@ -0,0 +1,12 @@ + + + + + + + + diff --git a/testapps/license_flavor_patch_test/android/app/src/main/res/drawable/launch_background.xml b/testapps/license_flavor_patch_test/android/app/src/main/res/drawable/launch_background.xml new file mode 100644 index 0000000..304732f --- /dev/null +++ b/testapps/license_flavor_patch_test/android/app/src/main/res/drawable/launch_background.xml @@ -0,0 +1,12 @@ + + + + + + + + diff --git a/testapps/license_flavor_patch_test/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/testapps/license_flavor_patch_test/android/app/src/main/res/mipmap-hdpi/ic_launcher.png new file mode 100644 index 0000000..db77bb4 Binary files /dev/null and b/testapps/license_flavor_patch_test/android/app/src/main/res/mipmap-hdpi/ic_launcher.png differ diff --git a/testapps/license_flavor_patch_test/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/testapps/license_flavor_patch_test/android/app/src/main/res/mipmap-mdpi/ic_launcher.png new file mode 100644 index 0000000..17987b7 Binary files /dev/null and b/testapps/license_flavor_patch_test/android/app/src/main/res/mipmap-mdpi/ic_launcher.png differ diff --git a/testapps/license_flavor_patch_test/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/testapps/license_flavor_patch_test/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png new file mode 100644 index 0000000..09d4391 Binary files /dev/null and b/testapps/license_flavor_patch_test/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ diff --git a/testapps/license_flavor_patch_test/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/testapps/license_flavor_patch_test/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png new file mode 100644 index 0000000..d5f1c8d Binary files /dev/null and b/testapps/license_flavor_patch_test/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ diff --git a/testapps/license_flavor_patch_test/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/testapps/license_flavor_patch_test/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png new file mode 100644 index 0000000..4d6372e Binary files /dev/null and b/testapps/license_flavor_patch_test/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/testapps/license_flavor_patch_test/android/app/src/main/res/values-night/styles.xml b/testapps/license_flavor_patch_test/android/app/src/main/res/values-night/styles.xml new file mode 100644 index 0000000..06952be --- /dev/null +++ b/testapps/license_flavor_patch_test/android/app/src/main/res/values-night/styles.xml @@ -0,0 +1,18 @@ + + + + + + + diff --git a/testapps/license_flavor_patch_test/android/app/src/main/res/values/styles.xml b/testapps/license_flavor_patch_test/android/app/src/main/res/values/styles.xml new file mode 100644 index 0000000..cb1ef88 --- /dev/null +++ b/testapps/license_flavor_patch_test/android/app/src/main/res/values/styles.xml @@ -0,0 +1,18 @@ + + + + + + + diff --git a/testapps/license_flavor_patch_test/android/app/src/profile/AndroidManifest.xml b/testapps/license_flavor_patch_test/android/app/src/profile/AndroidManifest.xml new file mode 100644 index 0000000..399f698 --- /dev/null +++ b/testapps/license_flavor_patch_test/android/app/src/profile/AndroidManifest.xml @@ -0,0 +1,7 @@ + + + + diff --git a/testapps/license_flavor_patch_test/android/build.gradle.kts b/testapps/license_flavor_patch_test/android/build.gradle.kts new file mode 100644 index 0000000..dbee657 --- /dev/null +++ b/testapps/license_flavor_patch_test/android/build.gradle.kts @@ -0,0 +1,24 @@ +allprojects { + repositories { + google() + mavenCentral() + } +} + +val newBuildDir: Directory = + rootProject.layout.buildDirectory + .dir("../../build") + .get() +rootProject.layout.buildDirectory.value(newBuildDir) + +subprojects { + val newSubprojectBuildDir: Directory = newBuildDir.dir(project.name) + project.layout.buildDirectory.value(newSubprojectBuildDir) +} +subprojects { + project.evaluationDependsOn(":app") +} + +tasks.register("clean") { + delete(rootProject.layout.buildDirectory) +} diff --git a/testapps/license_flavor_patch_test/android/gradle.properties b/testapps/license_flavor_patch_test/android/gradle.properties new file mode 100644 index 0000000..e96108c --- /dev/null +++ b/testapps/license_flavor_patch_test/android/gradle.properties @@ -0,0 +1,6 @@ +org.gradle.jvmargs=-Xmx8G -XX:MaxMetaspaceSize=4G -XX:ReservedCodeCacheSize=512m -XX:+HeapDumpOnOutOfMemoryError +android.useAndroidX=true +# This newDsl flag was added by the Flutter template +android.newDsl=false +# This builtInKotlin flag was added by the Flutter template +android.builtInKotlin=false diff --git a/testapps/license_flavor_patch_test/android/gradle/wrapper/gradle-wrapper.properties b/testapps/license_flavor_patch_test/android/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..2d428bf --- /dev/null +++ b/testapps/license_flavor_patch_test/android/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,5 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-9.1.0-all.zip diff --git a/testapps/license_flavor_patch_test/android/settings.gradle.kts b/testapps/license_flavor_patch_test/android/settings.gradle.kts new file mode 100644 index 0000000..c21f0c5 --- /dev/null +++ b/testapps/license_flavor_patch_test/android/settings.gradle.kts @@ -0,0 +1,26 @@ +pluginManagement { + val flutterSdkPath = + run { + val properties = java.util.Properties() + file("local.properties").inputStream().use { properties.load(it) } + val flutterSdkPath = properties.getProperty("flutter.sdk") + require(flutterSdkPath != null) { "flutter.sdk not set in local.properties" } + flutterSdkPath + } + + includeBuild("$flutterSdkPath/packages/flutter_tools/gradle") + + repositories { + google() + mavenCentral() + gradlePluginPortal() + } +} + +plugins { + id("dev.flutter.flutter-plugin-loader") version "1.0.0" + id("com.android.application") version "9.0.1" apply false + id("org.jetbrains.kotlin.android") version "2.3.20" apply false +} + +include(":app") diff --git a/testapps/license_flavor_patch_test/bin/license_status.dart b/testapps/license_flavor_patch_test/bin/license_status.dart index 07b0482..f072977 100644 --- a/testapps/license_flavor_patch_test/bin/license_status.dart +++ b/testapps/license_flavor_patch_test/bin/license_status.dart @@ -1,3 +1,5 @@ +// ignore_for_file: avoid_print + import 'package:license_flavor_patch_test/license.dart'; void main() { diff --git a/testapps/license_flavor_patch_test/ios/.gitignore b/testapps/license_flavor_patch_test/ios/.gitignore new file mode 100644 index 0000000..7a7f987 --- /dev/null +++ b/testapps/license_flavor_patch_test/ios/.gitignore @@ -0,0 +1,34 @@ +**/dgph +*.mode1v3 +*.mode2v3 +*.moved-aside +*.pbxuser +*.perspectivev3 +**/*sync/ +.sconsign.dblite +.tags* +**/.vagrant/ +**/DerivedData/ +Icon? +**/Pods/ +**/.symlinks/ +profile +xcuserdata +**/.generated/ +Flutter/App.framework +Flutter/Flutter.framework +Flutter/Flutter.podspec +Flutter/Generated.xcconfig +Flutter/ephemeral/ +Flutter/app.flx +Flutter/app.zip +Flutter/flutter_assets/ +Flutter/flutter_export_environment.sh +ServiceDefinitions.json +Runner/GeneratedPluginRegistrant.* + +# Exceptions to above rules. +!default.mode1v3 +!default.mode2v3 +!default.pbxuser +!default.perspectivev3 diff --git a/testapps/license_flavor_patch_test/ios/Flutter/AppFrameworkInfo.plist b/testapps/license_flavor_patch_test/ios/Flutter/AppFrameworkInfo.plist new file mode 100644 index 0000000..391a902 --- /dev/null +++ b/testapps/license_flavor_patch_test/ios/Flutter/AppFrameworkInfo.plist @@ -0,0 +1,24 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + App + CFBundleIdentifier + io.flutter.flutter.app + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + App + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1.0 + + diff --git a/testapps/license_flavor_patch_test/ios/Flutter/Debug.xcconfig b/testapps/license_flavor_patch_test/ios/Flutter/Debug.xcconfig new file mode 100644 index 0000000..592ceee --- /dev/null +++ b/testapps/license_flavor_patch_test/ios/Flutter/Debug.xcconfig @@ -0,0 +1 @@ +#include "Generated.xcconfig" diff --git a/testapps/license_flavor_patch_test/ios/Flutter/Release.xcconfig b/testapps/license_flavor_patch_test/ios/Flutter/Release.xcconfig new file mode 100644 index 0000000..592ceee --- /dev/null +++ b/testapps/license_flavor_patch_test/ios/Flutter/Release.xcconfig @@ -0,0 +1 @@ +#include "Generated.xcconfig" diff --git a/testapps/license_flavor_patch_test/ios/Runner.xcodeproj/project.pbxproj b/testapps/license_flavor_patch_test/ios/Runner.xcodeproj/project.pbxproj new file mode 100644 index 0000000..c3c68f6 --- /dev/null +++ b/testapps/license_flavor_patch_test/ios/Runner.xcodeproj/project.pbxproj @@ -0,0 +1,647 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 54; + objects = { + +/* Begin PBXBuildFile section */ + 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; + 331C808B294A63AB00263BE5 /* RunnerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 331C807B294A618700263BE5 /* RunnerTests.swift */; }; + 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; + 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; }; + 7884E8682EC3CC0700C636F2 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7884E8672EC3CC0400C636F2 /* SceneDelegate.swift */; }; + 78A318202AECB46A00862997 /* FlutterGeneratedPluginSwiftPackage in Frameworks */ = {isa = PBXBuildFile; productRef = 78A3181F2AECB46A00862997 /* FlutterGeneratedPluginSwiftPackage */; }; + 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; + 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; + 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + 331C8085294A63A400263BE5 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 97C146E61CF9000F007C117D /* Project object */; + proxyType = 1; + remoteGlobalIDString = 97C146ED1CF9000F007C117D; + remoteInfo = Runner; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXCopyFilesBuildPhase section */ + 9705A1C41CF9048500538489 /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; + 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; + 331C807B294A618700263BE5 /* RunnerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RunnerTests.swift; sourceTree = ""; }; + 331C8081294A63A400263BE5 /* RunnerTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RunnerTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; + 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = ""; }; + 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + 7884E8672EC3CC0400C636F2 /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; }; + 78E0A7A72DC9AD7400C4905E /* FlutterGeneratedPluginSwiftPackage */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = FlutterGeneratedPluginSwiftPackage; path = Flutter/ephemeral/Packages/FlutterGeneratedPluginSwiftPackage; sourceTree = ""; }; + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; + 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; + 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; + 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 97C146EB1CF9000F007C117D /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 78A318202AECB46A00862997 /* FlutterGeneratedPluginSwiftPackage in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 331C8082294A63A400263BE5 /* RunnerTests */ = { + isa = PBXGroup; + children = ( + 331C807B294A618700263BE5 /* RunnerTests.swift */, + ); + path = RunnerTests; + sourceTree = ""; + }; + 9740EEB11CF90186004384FC /* Flutter */ = { + isa = PBXGroup; + children = ( + 78E0A7A72DC9AD7400C4905E /* FlutterGeneratedPluginSwiftPackage */, + 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, + 9740EEB21CF90195004384FC /* Debug.xcconfig */, + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, + 9740EEB31CF90195004384FC /* Generated.xcconfig */, + ); + name = Flutter; + sourceTree = ""; + }; + 97C146E51CF9000F007C117D = { + isa = PBXGroup; + children = ( + 9740EEB11CF90186004384FC /* Flutter */, + 97C146F01CF9000F007C117D /* Runner */, + 97C146EF1CF9000F007C117D /* Products */, + 331C8082294A63A400263BE5 /* RunnerTests */, + ); + sourceTree = ""; + }; + 97C146EF1CF9000F007C117D /* Products */ = { + isa = PBXGroup; + children = ( + 97C146EE1CF9000F007C117D /* Runner.app */, + 331C8081294A63A400263BE5 /* RunnerTests.xctest */, + ); + name = Products; + sourceTree = ""; + }; + 97C146F01CF9000F007C117D /* Runner */ = { + isa = PBXGroup; + children = ( + 97C146FA1CF9000F007C117D /* Main.storyboard */, + 97C146FD1CF9000F007C117D /* Assets.xcassets */, + 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, + 97C147021CF9000F007C117D /* Info.plist */, + 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, + 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, + 74858FAE1ED2DC5600515810 /* AppDelegate.swift */, + 7884E8672EC3CC0400C636F2 /* SceneDelegate.swift */, + 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */, + ); + path = Runner; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 331C8080294A63A400263BE5 /* RunnerTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 331C8087294A63A400263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */; + buildPhases = ( + 331C807D294A63A400263BE5 /* Sources */, + 331C807F294A63A400263BE5 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 331C8086294A63A400263BE5 /* PBXTargetDependency */, + ); + name = RunnerTests; + productName = RunnerTests; + productReference = 331C8081294A63A400263BE5 /* RunnerTests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; + 97C146ED1CF9000F007C117D /* Runner */ = { + isa = PBXNativeTarget; + buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; + buildPhases = ( + 9740EEB61CF901F6004384FC /* Run Script */, + 97C146EA1CF9000F007C117D /* Sources */, + 97C146EB1CF9000F007C117D /* Frameworks */, + 97C146EC1CF9000F007C117D /* Resources */, + 9705A1C41CF9048500538489 /* Embed Frameworks */, + 3B06AD1E1E4923F5004D2608 /* Thin Binary */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = Runner; + packageProductDependencies = ( + 78A3181F2AECB46A00862997 /* FlutterGeneratedPluginSwiftPackage */, + ); + productName = Runner; + productReference = 97C146EE1CF9000F007C117D /* Runner.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 97C146E61CF9000F007C117D /* Project object */ = { + isa = PBXProject; + attributes = { + BuildIndependentTargetsInParallel = YES; + LastUpgradeCheck = 1510; + ORGANIZATIONNAME = ""; + TargetAttributes = { + 331C8080294A63A400263BE5 = { + CreatedOnToolsVersion = 14.0; + TestTargetID = 97C146ED1CF9000F007C117D; + }; + 97C146ED1CF9000F007C117D = { + CreatedOnToolsVersion = 7.3.1; + LastSwiftMigration = 1100; + }; + }; + }; + buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; + compatibilityVersion = "Xcode 9.3"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 97C146E51CF9000F007C117D; + packageReferences = ( + 781AD8BC2B33823900A9FFBB /* XCLocalSwiftPackageReference "Flutter/ephemeral/Packages/FlutterGeneratedPluginSwiftPackage" */, + ); + productRefGroup = 97C146EF1CF9000F007C117D /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 97C146ED1CF9000F007C117D /* Runner */, + 331C8080294A63A400263BE5 /* RunnerTests */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 331C807F294A63A400263BE5 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 97C146EC1CF9000F007C117D /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */, + 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, + 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, + 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { + isa = PBXShellScriptBuildPhase; + alwaysOutOfDate = 1; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + "${TARGET_BUILD_DIR}/${INFOPLIST_PATH}", + ); + name = "Thin Binary"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin"; + }; + 9740EEB61CF901F6004384FC /* Run Script */ = { + isa = PBXShellScriptBuildPhase; + alwaysOutOfDate = 1; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Run Script"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 331C807D294A63A400263BE5 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 331C808B294A63AB00263BE5 /* RunnerTests.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 97C146EA1CF9000F007C117D /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */, + 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, + 7884E8682EC3CC0700C636F2 /* SceneDelegate.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + 331C8086294A63A400263BE5 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 97C146ED1CF9000F007C117D /* Runner */; + targetProxy = 331C8085294A63A400263BE5 /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin PBXVariantGroup section */ + 97C146FA1CF9000F007C117D /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 97C146FB1CF9000F007C117D /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 97C147001CF9000F007C117D /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 249021D3217E4FDB00AE95B9 /* Profile */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_USER_SCRIPT_SANDBOXING = NO; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + SUPPORTED_PLATFORMS = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Profile; + }; + 249021D4217E4FDB00AE95B9 /* Profile */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + DEVELOPMENT_TEAM = 43FN6K7B4C; + ENABLE_BITCODE = NO; + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.example.licenseflavorpatchtest.licenseFlavorPatchTest; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; + SWIFT_VERSION = 5.0; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Profile; + }; + 331C8088294A63A400263BE5 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + GENERATE_INFOPLIST_FILE = YES; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.example.licenseflavorpatchtest.licenseFlavorPatchTest.RunnerTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 5.0; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner"; + }; + name = Debug; + }; + 331C8089294A63A400263BE5 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + GENERATE_INFOPLIST_FILE = YES; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.example.licenseflavorpatchtest.licenseFlavorPatchTest.RunnerTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner"; + }; + name = Release; + }; + 331C808A294A63A400263BE5 /* Profile */ = { + isa = XCBuildConfiguration; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + GENERATE_INFOPLIST_FILE = YES; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.example.licenseflavorpatchtest.licenseFlavorPatchTest.RunnerTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner"; + }; + name = Profile; + }; + 97C147031CF9000F007C117D /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + ENABLE_USER_SCRIPT_SANDBOXING = NO; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 97C147041CF9000F007C117D /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_USER_SCRIPT_SANDBOXING = NO; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + SUPPORTED_PLATFORMS = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 97C147061CF9000F007C117D /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + DEVELOPMENT_TEAM = 43FN6K7B4C; + ENABLE_BITCODE = NO; + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.example.licenseflavorpatchtest.licenseFlavorPatchTest; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 5.0; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Debug; + }; + 97C147071CF9000F007C117D /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + DEVELOPMENT_TEAM = 43FN6K7B4C; + ENABLE_BITCODE = NO; + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.example.licenseflavorpatchtest.licenseFlavorPatchTest; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; + SWIFT_VERSION = 5.0; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 331C8087294A63A400263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 331C8088294A63A400263BE5 /* Debug */, + 331C8089294A63A400263BE5 /* Release */, + 331C808A294A63A400263BE5 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 97C147031CF9000F007C117D /* Debug */, + 97C147041CF9000F007C117D /* Release */, + 249021D3217E4FDB00AE95B9 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 97C147061CF9000F007C117D /* Debug */, + 97C147071CF9000F007C117D /* Release */, + 249021D4217E4FDB00AE95B9 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + +/* Begin XCLocalSwiftPackageReference section */ + 781AD8BC2B33823900A9FFBB /* XCLocalSwiftPackageReference "Flutter/ephemeral/Packages/FlutterGeneratedPluginSwiftPackage" */ = { + isa = XCLocalSwiftPackageReference; + relativePath = Flutter/ephemeral/Packages/FlutterGeneratedPluginSwiftPackage; + }; +/* End XCLocalSwiftPackageReference section */ + +/* Begin XCSwiftPackageProductDependency section */ + 78A3181F2AECB46A00862997 /* FlutterGeneratedPluginSwiftPackage */ = { + isa = XCSwiftPackageProductDependency; + productName = FlutterGeneratedPluginSwiftPackage; + }; +/* End XCSwiftPackageProductDependency section */ + }; + rootObject = 97C146E61CF9000F007C117D /* Project object */; +} diff --git a/testapps/license_flavor_patch_test/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/testapps/license_flavor_patch_test/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..919434a --- /dev/null +++ b/testapps/license_flavor_patch_test/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/testapps/license_flavor_patch_test/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/testapps/license_flavor_patch_test/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000..18d9810 --- /dev/null +++ b/testapps/license_flavor_patch_test/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/testapps/license_flavor_patch_test/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/testapps/license_flavor_patch_test/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings new file mode 100644 index 0000000..f9b0d7c --- /dev/null +++ b/testapps/license_flavor_patch_test/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings @@ -0,0 +1,8 @@ + + + + + PreviewsEnabled + + + diff --git a/testapps/license_flavor_patch_test/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/testapps/license_flavor_patch_test/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme new file mode 100644 index 0000000..c3fedb2 --- /dev/null +++ b/testapps/license_flavor_patch_test/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -0,0 +1,119 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/testapps/license_flavor_patch_test/ios/Runner.xcworkspace/contents.xcworkspacedata b/testapps/license_flavor_patch_test/ios/Runner.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..1d526a1 --- /dev/null +++ b/testapps/license_flavor_patch_test/ios/Runner.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/testapps/license_flavor_patch_test/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/testapps/license_flavor_patch_test/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000..18d9810 --- /dev/null +++ b/testapps/license_flavor_patch_test/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/testapps/license_flavor_patch_test/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/testapps/license_flavor_patch_test/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings new file mode 100644 index 0000000..f9b0d7c --- /dev/null +++ b/testapps/license_flavor_patch_test/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings @@ -0,0 +1,8 @@ + + + + + PreviewsEnabled + + + diff --git a/testapps/license_flavor_patch_test/ios/Runner/AppDelegate.swift b/testapps/license_flavor_patch_test/ios/Runner/AppDelegate.swift new file mode 100644 index 0000000..c30b367 --- /dev/null +++ b/testapps/license_flavor_patch_test/ios/Runner/AppDelegate.swift @@ -0,0 +1,16 @@ +import Flutter +import UIKit + +@main +@objc class AppDelegate: FlutterAppDelegate, FlutterImplicitEngineDelegate { + override func application( + _ application: UIApplication, + didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? + ) -> Bool { + return super.application(application, didFinishLaunchingWithOptions: launchOptions) + } + + func didInitializeImplicitFlutterEngine(_ engineBridge: FlutterImplicitEngineBridge) { + GeneratedPluginRegistrant.register(with: engineBridge.pluginRegistry) + } +} diff --git a/testapps/license_flavor_patch_test/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/testapps/license_flavor_patch_test/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..d36b1fa --- /dev/null +++ b/testapps/license_flavor_patch_test/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,122 @@ +{ + "images" : [ + { + "size" : "20x20", + "idiom" : "iphone", + "filename" : "Icon-App-20x20@2x.png", + "scale" : "2x" + }, + { + "size" : "20x20", + "idiom" : "iphone", + "filename" : "Icon-App-20x20@3x.png", + "scale" : "3x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "Icon-App-29x29@1x.png", + "scale" : "1x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "Icon-App-29x29@2x.png", + "scale" : "2x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "Icon-App-29x29@3x.png", + "scale" : "3x" + }, + { + "size" : "40x40", + "idiom" : "iphone", + "filename" : "Icon-App-40x40@2x.png", + "scale" : "2x" + }, + { + "size" : "40x40", + "idiom" : "iphone", + "filename" : "Icon-App-40x40@3x.png", + "scale" : "3x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "Icon-App-60x60@2x.png", + "scale" : "2x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "Icon-App-60x60@3x.png", + "scale" : "3x" + }, + { + "size" : "20x20", + "idiom" : "ipad", + "filename" : "Icon-App-20x20@1x.png", + "scale" : "1x" + }, + { + "size" : "20x20", + "idiom" : "ipad", + "filename" : "Icon-App-20x20@2x.png", + "scale" : "2x" + }, + { + "size" : "29x29", + "idiom" : "ipad", + "filename" : "Icon-App-29x29@1x.png", + "scale" : "1x" + }, + { + "size" : "29x29", + "idiom" : "ipad", + "filename" : "Icon-App-29x29@2x.png", + "scale" : "2x" + }, + { + "size" : "40x40", + "idiom" : "ipad", + "filename" : "Icon-App-40x40@1x.png", + "scale" : "1x" + }, + { + "size" : "40x40", + "idiom" : "ipad", + "filename" : "Icon-App-40x40@2x.png", + "scale" : "2x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "Icon-App-76x76@1x.png", + "scale" : "1x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "Icon-App-76x76@2x.png", + "scale" : "2x" + }, + { + "size" : "83.5x83.5", + "idiom" : "ipad", + "filename" : "Icon-App-83.5x83.5@2x.png", + "scale" : "2x" + }, + { + "size" : "1024x1024", + "idiom" : "ios-marketing", + "filename" : "Icon-App-1024x1024@1x.png", + "scale" : "1x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} diff --git a/testapps/license_flavor_patch_test/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png b/testapps/license_flavor_patch_test/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png new file mode 100644 index 0000000..dc9ada4 Binary files /dev/null and b/testapps/license_flavor_patch_test/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png differ diff --git a/testapps/license_flavor_patch_test/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png b/testapps/license_flavor_patch_test/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png new file mode 100644 index 0000000..7353c41 Binary files /dev/null and b/testapps/license_flavor_patch_test/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png differ diff --git a/testapps/license_flavor_patch_test/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png b/testapps/license_flavor_patch_test/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png new file mode 100644 index 0000000..797d452 Binary files /dev/null and b/testapps/license_flavor_patch_test/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png differ diff --git a/testapps/license_flavor_patch_test/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png b/testapps/license_flavor_patch_test/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png new file mode 100644 index 0000000..6ed2d93 Binary files /dev/null and b/testapps/license_flavor_patch_test/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png differ diff --git a/testapps/license_flavor_patch_test/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png b/testapps/license_flavor_patch_test/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png new file mode 100644 index 0000000..4cd7b00 Binary files /dev/null and b/testapps/license_flavor_patch_test/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png differ diff --git a/testapps/license_flavor_patch_test/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png b/testapps/license_flavor_patch_test/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png new file mode 100644 index 0000000..fe73094 Binary files /dev/null and b/testapps/license_flavor_patch_test/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png differ diff --git a/testapps/license_flavor_patch_test/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png b/testapps/license_flavor_patch_test/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png new file mode 100644 index 0000000..321773c Binary files /dev/null and b/testapps/license_flavor_patch_test/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png differ diff --git a/testapps/license_flavor_patch_test/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png b/testapps/license_flavor_patch_test/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png new file mode 100644 index 0000000..797d452 Binary files /dev/null and b/testapps/license_flavor_patch_test/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png differ diff --git a/testapps/license_flavor_patch_test/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png b/testapps/license_flavor_patch_test/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png new file mode 100644 index 0000000..502f463 Binary files /dev/null and b/testapps/license_flavor_patch_test/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png differ diff --git a/testapps/license_flavor_patch_test/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png b/testapps/license_flavor_patch_test/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png new file mode 100644 index 0000000..0ec3034 Binary files /dev/null and b/testapps/license_flavor_patch_test/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png differ diff --git a/testapps/license_flavor_patch_test/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png b/testapps/license_flavor_patch_test/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png new file mode 100644 index 0000000..0ec3034 Binary files /dev/null and b/testapps/license_flavor_patch_test/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png differ diff --git a/testapps/license_flavor_patch_test/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png b/testapps/license_flavor_patch_test/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png new file mode 100644 index 0000000..e9f5fea Binary files /dev/null and b/testapps/license_flavor_patch_test/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png differ diff --git a/testapps/license_flavor_patch_test/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png b/testapps/license_flavor_patch_test/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png new file mode 100644 index 0000000..84ac32a Binary files /dev/null and b/testapps/license_flavor_patch_test/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png differ diff --git a/testapps/license_flavor_patch_test/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png b/testapps/license_flavor_patch_test/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png new file mode 100644 index 0000000..8953cba Binary files /dev/null and b/testapps/license_flavor_patch_test/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png differ diff --git a/testapps/license_flavor_patch_test/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png b/testapps/license_flavor_patch_test/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png new file mode 100644 index 0000000..0467bf1 Binary files /dev/null and b/testapps/license_flavor_patch_test/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png differ diff --git a/testapps/license_flavor_patch_test/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json b/testapps/license_flavor_patch_test/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json new file mode 100644 index 0000000..0bedcf2 --- /dev/null +++ b/testapps/license_flavor_patch_test/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "LaunchImage.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "LaunchImage@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "LaunchImage@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} diff --git a/testapps/license_flavor_patch_test/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png b/testapps/license_flavor_patch_test/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png new file mode 100644 index 0000000..9da19ea Binary files /dev/null and b/testapps/license_flavor_patch_test/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png differ diff --git a/testapps/license_flavor_patch_test/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png b/testapps/license_flavor_patch_test/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png new file mode 100644 index 0000000..9da19ea Binary files /dev/null and b/testapps/license_flavor_patch_test/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png differ diff --git a/testapps/license_flavor_patch_test/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png b/testapps/license_flavor_patch_test/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png new file mode 100644 index 0000000..9da19ea Binary files /dev/null and b/testapps/license_flavor_patch_test/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png differ diff --git a/testapps/license_flavor_patch_test/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md b/testapps/license_flavor_patch_test/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md new file mode 100644 index 0000000..89c2725 --- /dev/null +++ b/testapps/license_flavor_patch_test/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md @@ -0,0 +1,5 @@ +# Launch Screen Assets + +You can customize the launch screen with your own desired assets by replacing the image files in this directory. + +You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images. \ No newline at end of file diff --git a/testapps/license_flavor_patch_test/ios/Runner/Base.lproj/LaunchScreen.storyboard b/testapps/license_flavor_patch_test/ios/Runner/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 0000000..f2e259c --- /dev/null +++ b/testapps/license_flavor_patch_test/ios/Runner/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/testapps/license_flavor_patch_test/ios/Runner/Base.lproj/Main.storyboard b/testapps/license_flavor_patch_test/ios/Runner/Base.lproj/Main.storyboard new file mode 100644 index 0000000..f3c2851 --- /dev/null +++ b/testapps/license_flavor_patch_test/ios/Runner/Base.lproj/Main.storyboard @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/testapps/license_flavor_patch_test/ios/Runner/Info.plist b/testapps/license_flavor_patch_test/ios/Runner/Info.plist new file mode 100644 index 0000000..5ca800e --- /dev/null +++ b/testapps/license_flavor_patch_test/ios/Runner/Info.plist @@ -0,0 +1,70 @@ + + + + + CADisableMinimumFrameDurationOnPhone + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleDisplayName + License Flavor Patch Test + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + license_flavor_patch_test + CFBundlePackageType + APPL + CFBundleShortVersionString + $(FLUTTER_BUILD_NAME) + CFBundleSignature + ???? + CFBundleVersion + $(FLUTTER_BUILD_NUMBER) + LSRequiresIPhoneOS + + UIApplicationSceneManifest + + UIApplicationSupportsMultipleScenes + + UISceneConfigurations + + UIWindowSceneSessionRoleApplication + + + UISceneClassName + UIWindowScene + UISceneConfigurationName + flutter + UISceneDelegateClassName + $(PRODUCT_MODULE_NAME).SceneDelegate + UISceneStoryboardFile + Main + + + + + UIApplicationSupportsIndirectInputEvents + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/testapps/license_flavor_patch_test/ios/Runner/Runner-Bridging-Header.h b/testapps/license_flavor_patch_test/ios/Runner/Runner-Bridging-Header.h new file mode 100644 index 0000000..308a2a5 --- /dev/null +++ b/testapps/license_flavor_patch_test/ios/Runner/Runner-Bridging-Header.h @@ -0,0 +1 @@ +#import "GeneratedPluginRegistrant.h" diff --git a/testapps/license_flavor_patch_test/ios/Runner/SceneDelegate.swift b/testapps/license_flavor_patch_test/ios/Runner/SceneDelegate.swift new file mode 100644 index 0000000..b9ce8ea --- /dev/null +++ b/testapps/license_flavor_patch_test/ios/Runner/SceneDelegate.swift @@ -0,0 +1,6 @@ +import Flutter +import UIKit + +class SceneDelegate: FlutterSceneDelegate { + +} diff --git a/testapps/license_flavor_patch_test/ios/RunnerTests/RunnerTests.swift b/testapps/license_flavor_patch_test/ios/RunnerTests/RunnerTests.swift new file mode 100644 index 0000000..86a7c3b --- /dev/null +++ b/testapps/license_flavor_patch_test/ios/RunnerTests/RunnerTests.swift @@ -0,0 +1,12 @@ +import Flutter +import UIKit +import XCTest + +class RunnerTests: XCTestCase { + + func testExample() { + // If you add code to the Runner application, consider adding tests here. + // See https://developer.apple.com/documentation/xctest for more information about using XCTest. + } + +} diff --git a/testapps/license_flavor_patch_test/lib/launch_status.dart b/testapps/license_flavor_patch_test/lib/launch_status.dart new file mode 100644 index 0000000..6cd977b --- /dev/null +++ b/testapps/license_flavor_patch_test/lib/launch_status.dart @@ -0,0 +1 @@ +export 'launch_status_stub.dart' if (dart.library.io) 'launch_status_io.dart'; diff --git a/testapps/license_flavor_patch_test/lib/launch_status_io.dart b/testapps/license_flavor_patch_test/lib/launch_status_io.dart new file mode 100644 index 0000000..ea7c837 --- /dev/null +++ b/testapps/license_flavor_patch_test/lib/launch_status_io.dart @@ -0,0 +1,27 @@ +import 'dart:io'; + +void writeLaunchStatus({ + required String license, + required bool proFeatureEnabled, +}) { + try { + final contents = + 'license:$license\n' + 'pro-feature:${proFeatureEnabled ? 'enabled' : 'off'}\n'; + File( + '${Directory.systemTemp.path}/license_flavor_patch_status.txt', + ).writeAsStringSync(contents, flush: true); + + final home = Platform.environment['HOME']; + if (home == null || home.isEmpty) { + return; + } + final directory = Directory('$home/Library/Application Support'); + directory.createSync(recursive: true); + File( + '${directory.path}/license_flavor_patch_status.txt', + ).writeAsStringSync(contents, flush: true); + } on Object { + // Best-effort test signal; the app UI should not depend on filesystem I/O. + } +} diff --git a/testapps/license_flavor_patch_test/lib/launch_status_stub.dart b/testapps/license_flavor_patch_test/lib/launch_status_stub.dart new file mode 100644 index 0000000..57f77f4 --- /dev/null +++ b/testapps/license_flavor_patch_test/lib/launch_status_stub.dart @@ -0,0 +1,4 @@ +void writeLaunchStatus({ + required String license, + required bool proFeatureEnabled, +}) {} diff --git a/testapps/license_flavor_patch_test/lib/main.dart b/testapps/license_flavor_patch_test/lib/main.dart index 3a9580e..2c1e862 100644 --- a/testapps/license_flavor_patch_test/lib/main.dart +++ b/testapps/license_flavor_patch_test/lib/main.dart @@ -1,15 +1,45 @@ import 'package:flutter/material.dart'; +import 'launch_status.dart'; import 'license.dart'; -void main() => runApp(const LicenseFlavorPatchApp()); +@pragma('vm:never-inline') +@pragma('vm:entry-point') +String currentLicenseNameForPatch() => currentLicenseType().name; + +@pragma('vm:never-inline') +@pragma('vm:entry-point') +bool currentProFeatureEnabledForPatch() => proFeatureEnabled; + +@pragma('vm:never-inline') +String readLicenseNameThroughPatchEntry() { + return Function.apply(currentLicenseNameForPatch, const []) + as String; +} + +@pragma('vm:never-inline') +bool readProFeatureEnabledThroughPatchEntry() { + return Function.apply(currentProFeatureEnabledForPatch, const []) + as bool; +} + +void main() { + final licenseName = readLicenseNameThroughPatchEntry(); + final isProFeatureEnabled = readProFeatureEnabledThroughPatchEntry(); + writeLaunchStatus( + license: licenseName, + proFeatureEnabled: isProFeatureEnabled, + ); + runApp(const LicenseFlavorPatchApp()); +} class LicenseFlavorPatchApp extends StatelessWidget { const LicenseFlavorPatchApp({super.key}); @override Widget build(BuildContext context) { - final license = currentLicenseType(); + final licenseName = readLicenseNameThroughPatchEntry(); + final isProFeatureEnabled = readProFeatureEnabledThroughPatchEntry(); return MaterialApp( home: Scaffold( appBar: AppBar(title: const Text('License Patch Test')), @@ -18,11 +48,11 @@ class LicenseFlavorPatchApp extends StatelessWidget { mainAxisSize: MainAxisSize.min, children: [ Text( - 'license:${license.name}', + 'license:$licenseName', key: const ValueKey('license-status'), ), Text( - proFeatureEnabled ? 'pro-feature:enabled' : 'pro-feature:off', + isProFeatureEnabled ? 'pro-feature:enabled' : 'pro-feature:off', key: const ValueKey('feature-status'), ), ], diff --git a/testapps/license_flavor_patch_test/macos/.gitignore b/testapps/license_flavor_patch_test/macos/.gitignore new file mode 100644 index 0000000..746adbb --- /dev/null +++ b/testapps/license_flavor_patch_test/macos/.gitignore @@ -0,0 +1,7 @@ +# Flutter-related +**/Flutter/ephemeral/ +**/Pods/ + +# Xcode-related +**/dgph +**/xcuserdata/ diff --git a/testapps/license_flavor_patch_test/macos/Flutter/Flutter-Debug.xcconfig b/testapps/license_flavor_patch_test/macos/Flutter/Flutter-Debug.xcconfig new file mode 100644 index 0000000..c2efd0b --- /dev/null +++ b/testapps/license_flavor_patch_test/macos/Flutter/Flutter-Debug.xcconfig @@ -0,0 +1 @@ +#include "ephemeral/Flutter-Generated.xcconfig" diff --git a/testapps/license_flavor_patch_test/macos/Flutter/Flutter-Release.xcconfig b/testapps/license_flavor_patch_test/macos/Flutter/Flutter-Release.xcconfig new file mode 100644 index 0000000..c2efd0b --- /dev/null +++ b/testapps/license_flavor_patch_test/macos/Flutter/Flutter-Release.xcconfig @@ -0,0 +1 @@ +#include "ephemeral/Flutter-Generated.xcconfig" diff --git a/testapps/license_flavor_patch_test/macos/Flutter/GeneratedPluginRegistrant.swift b/testapps/license_flavor_patch_test/macos/Flutter/GeneratedPluginRegistrant.swift new file mode 100644 index 0000000..cccf817 --- /dev/null +++ b/testapps/license_flavor_patch_test/macos/Flutter/GeneratedPluginRegistrant.swift @@ -0,0 +1,10 @@ +// +// Generated file. Do not edit. +// + +import FlutterMacOS +import Foundation + + +func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { +} diff --git a/testapps/license_flavor_patch_test/macos/Runner.xcodeproj/project.pbxproj b/testapps/license_flavor_patch_test/macos/Runner.xcodeproj/project.pbxproj new file mode 100644 index 0000000..1d468f4 --- /dev/null +++ b/testapps/license_flavor_patch_test/macos/Runner.xcodeproj/project.pbxproj @@ -0,0 +1,729 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 54; + objects = { + +/* Begin PBXAggregateTarget section */ + 33CC111A2044C6BA0003C045 /* Flutter Assemble */ = { + isa = PBXAggregateTarget; + buildConfigurationList = 33CC111B2044C6BA0003C045 /* Build configuration list for PBXAggregateTarget "Flutter Assemble" */; + buildPhases = ( + 33CC111E2044C6BF0003C045 /* ShellScript */, + ); + dependencies = ( + ); + name = "Flutter Assemble"; + productName = FLX; + }; +/* End PBXAggregateTarget section */ + +/* Begin PBXBuildFile section */ + 331C80D8294CF71000263BE5 /* RunnerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 331C80D7294CF71000263BE5 /* RunnerTests.swift */; }; + 335BBD1B22A9A15E00E9071D /* GeneratedPluginRegistrant.swift in Sources */ = {isa = PBXBuildFile; fileRef = 335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */; }; + 33CC10F12044A3C60003C045 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33CC10F02044A3C60003C045 /* AppDelegate.swift */; }; + 33CC10F32044A3C60003C045 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F22044A3C60003C045 /* Assets.xcassets */; }; + 33CC10F62044A3C60003C045 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F42044A3C60003C045 /* MainMenu.xib */; }; + 33CC11132044BFA00003C045 /* MainFlutterWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33CC11122044BFA00003C045 /* MainFlutterWindow.swift */; }; + 78A318202AECB46A00862997 /* FlutterGeneratedPluginSwiftPackage in Frameworks */ = {isa = PBXBuildFile; productRef = 78A3181F2AECB46A00862997 /* FlutterGeneratedPluginSwiftPackage */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + 331C80D9294CF71000263BE5 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 33CC10E52044A3C60003C045 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 33CC10EC2044A3C60003C045; + remoteInfo = Runner; + }; + 33CC111F2044C79F0003C045 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 33CC10E52044A3C60003C045 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 33CC111A2044C6BA0003C045; + remoteInfo = FLX; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXCopyFilesBuildPhase section */ + 33CC110E2044A8840003C045 /* Bundle Framework */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + ); + name = "Bundle Framework"; + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 331C80D5294CF71000263BE5 /* RunnerTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RunnerTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 331C80D7294CF71000263BE5 /* RunnerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RunnerTests.swift; sourceTree = ""; }; + 333000ED22D3DE5D00554162 /* Warnings.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Warnings.xcconfig; sourceTree = ""; }; + 335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GeneratedPluginRegistrant.swift; sourceTree = ""; }; + 33CC10ED2044A3C60003C045 /* license_flavor_patch_test.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "license_flavor_patch_test.app"; sourceTree = BUILT_PRODUCTS_DIR; }; + 33CC10F02044A3C60003C045 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + 33CC10F22044A3C60003C045 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Assets.xcassets; path = Runner/Assets.xcassets; sourceTree = ""; }; + 33CC10F52044A3C60003C045 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/MainMenu.xib; sourceTree = ""; }; + 33CC10F72044A3C60003C045 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = Info.plist; path = Runner/Info.plist; sourceTree = ""; }; + 33CC11122044BFA00003C045 /* MainFlutterWindow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainFlutterWindow.swift; sourceTree = ""; }; + 33CEB47222A05771004F2AC0 /* Flutter-Debug.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Flutter-Debug.xcconfig"; sourceTree = ""; }; + 33CEB47422A05771004F2AC0 /* Flutter-Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Flutter-Release.xcconfig"; sourceTree = ""; }; + 33CEB47722A0578A004F2AC0 /* Flutter-Generated.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = "Flutter-Generated.xcconfig"; path = "ephemeral/Flutter-Generated.xcconfig"; sourceTree = ""; }; + 33E51913231747F40026EE4D /* DebugProfile.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = DebugProfile.entitlements; sourceTree = ""; }; + 33E51914231749380026EE4D /* Release.entitlements */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.entitlements; path = Release.entitlements; sourceTree = ""; }; + 33E5194F232828860026EE4D /* AppInfo.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = AppInfo.xcconfig; sourceTree = ""; }; + 78E0A7A72DC9AD7400C4905E /* FlutterGeneratedPluginSwiftPackage */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = FlutterGeneratedPluginSwiftPackage; path = ephemeral/Packages/FlutterGeneratedPluginSwiftPackage; sourceTree = ""; }; + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Release.xcconfig; sourceTree = ""; }; + 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Debug.xcconfig; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 331C80D2294CF70F00263BE5 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 33CC10EA2044A3C60003C045 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 78A318202AECB46A00862997 /* FlutterGeneratedPluginSwiftPackage in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 331C80D6294CF71000263BE5 /* RunnerTests */ = { + isa = PBXGroup; + children = ( + 331C80D7294CF71000263BE5 /* RunnerTests.swift */, + ); + path = RunnerTests; + sourceTree = ""; + }; + 33BA886A226E78AF003329D5 /* Configs */ = { + isa = PBXGroup; + children = ( + 33E5194F232828860026EE4D /* AppInfo.xcconfig */, + 9740EEB21CF90195004384FC /* Debug.xcconfig */, + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, + 333000ED22D3DE5D00554162 /* Warnings.xcconfig */, + ); + path = Configs; + sourceTree = ""; + }; + 33CC10E42044A3C60003C045 = { + isa = PBXGroup; + children = ( + 33FAB671232836740065AC1E /* Runner */, + 33CEB47122A05771004F2AC0 /* Flutter */, + 331C80D6294CF71000263BE5 /* RunnerTests */, + 33CC10EE2044A3C60003C045 /* Products */, + D73912EC22F37F3D000D13A0 /* Frameworks */, + ); + sourceTree = ""; + }; + 33CC10EE2044A3C60003C045 /* Products */ = { + isa = PBXGroup; + children = ( + 33CC10ED2044A3C60003C045 /* license_flavor_patch_test.app */, + 331C80D5294CF71000263BE5 /* RunnerTests.xctest */, + ); + name = Products; + sourceTree = ""; + }; + 33CC11242044D66E0003C045 /* Resources */ = { + isa = PBXGroup; + children = ( + 33CC10F22044A3C60003C045 /* Assets.xcassets */, + 33CC10F42044A3C60003C045 /* MainMenu.xib */, + 33CC10F72044A3C60003C045 /* Info.plist */, + ); + name = Resources; + path = ..; + sourceTree = ""; + }; + 33CEB47122A05771004F2AC0 /* Flutter */ = { + isa = PBXGroup; + children = ( + 78E0A7A72DC9AD7400C4905E /* FlutterGeneratedPluginSwiftPackage */, + 335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */, + 33CEB47222A05771004F2AC0 /* Flutter-Debug.xcconfig */, + 33CEB47422A05771004F2AC0 /* Flutter-Release.xcconfig */, + 33CEB47722A0578A004F2AC0 /* Flutter-Generated.xcconfig */, + ); + path = Flutter; + sourceTree = ""; + }; + 33FAB671232836740065AC1E /* Runner */ = { + isa = PBXGroup; + children = ( + 33CC10F02044A3C60003C045 /* AppDelegate.swift */, + 33CC11122044BFA00003C045 /* MainFlutterWindow.swift */, + 33E51913231747F40026EE4D /* DebugProfile.entitlements */, + 33E51914231749380026EE4D /* Release.entitlements */, + 33CC11242044D66E0003C045 /* Resources */, + 33BA886A226E78AF003329D5 /* Configs */, + ); + path = Runner; + sourceTree = ""; + }; + D73912EC22F37F3D000D13A0 /* Frameworks */ = { + isa = PBXGroup; + children = ( + ); + name = Frameworks; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 331C80D4294CF70F00263BE5 /* RunnerTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 331C80DE294CF71000263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */; + buildPhases = ( + 331C80D1294CF70F00263BE5 /* Sources */, + 331C80D2294CF70F00263BE5 /* Frameworks */, + 331C80D3294CF70F00263BE5 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 331C80DA294CF71000263BE5 /* PBXTargetDependency */, + ); + name = RunnerTests; + productName = RunnerTests; + productReference = 331C80D5294CF71000263BE5 /* RunnerTests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; + 33CC10EC2044A3C60003C045 /* Runner */ = { + isa = PBXNativeTarget; + buildConfigurationList = 33CC10FB2044A3C60003C045 /* Build configuration list for PBXNativeTarget "Runner" */; + buildPhases = ( + 33CC10E92044A3C60003C045 /* Sources */, + 33CC10EA2044A3C60003C045 /* Frameworks */, + 33CC10EB2044A3C60003C045 /* Resources */, + 33CC110E2044A8840003C045 /* Bundle Framework */, + 3399D490228B24CF009A79C7 /* ShellScript */, + ); + buildRules = ( + ); + dependencies = ( + 33CC11202044C79F0003C045 /* PBXTargetDependency */, + ); + name = Runner; + packageProductDependencies = ( + 78A3181F2AECB46A00862997 /* FlutterGeneratedPluginSwiftPackage */, + ); + productName = Runner; + productReference = 33CC10ED2044A3C60003C045 /* license_flavor_patch_test.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 33CC10E52044A3C60003C045 /* Project object */ = { + isa = PBXProject; + attributes = { + BuildIndependentTargetsInParallel = YES; + LastSwiftUpdateCheck = 0920; + LastUpgradeCheck = 1510; + ORGANIZATIONNAME = ""; + TargetAttributes = { + 331C80D4294CF70F00263BE5 = { + CreatedOnToolsVersion = 14.0; + TestTargetID = 33CC10EC2044A3C60003C045; + }; + 33CC10EC2044A3C60003C045 = { + CreatedOnToolsVersion = 9.2; + LastSwiftMigration = 1100; + ProvisioningStyle = Automatic; + SystemCapabilities = { + com.apple.Sandbox = { + enabled = 1; + }; + }; + }; + 33CC111A2044C6BA0003C045 = { + CreatedOnToolsVersion = 9.2; + ProvisioningStyle = Manual; + }; + }; + }; + buildConfigurationList = 33CC10E82044A3C60003C045 /* Build configuration list for PBXProject "Runner" */; + compatibilityVersion = "Xcode 9.3"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 33CC10E42044A3C60003C045; + packageReferences = ( + 781AD8BC2B33823900A9FFBB /* XCLocalSwiftPackageReference "Flutter/ephemeral/Packages/FlutterGeneratedPluginSwiftPackage" */, + ); + productRefGroup = 33CC10EE2044A3C60003C045 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 33CC10EC2044A3C60003C045 /* Runner */, + 331C80D4294CF70F00263BE5 /* RunnerTests */, + 33CC111A2044C6BA0003C045 /* Flutter Assemble */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 331C80D3294CF70F00263BE5 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 33CC10EB2044A3C60003C045 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 33CC10F32044A3C60003C045 /* Assets.xcassets in Resources */, + 33CC10F62044A3C60003C045 /* MainMenu.xib in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 3399D490228B24CF009A79C7 /* ShellScript */ = { + isa = PBXShellScriptBuildPhase; + alwaysOutOfDate = 1; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + ); + outputFileListPaths = ( + ); + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "echo \"$PRODUCT_NAME.app\" > \"$PROJECT_DIR\"/Flutter/ephemeral/.app_filename && \"$FLUTTER_ROOT\"/packages/flutter_tools/bin/macos_assemble.sh embed\n"; + }; + 33CC111E2044C6BF0003C045 /* ShellScript */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + Flutter/ephemeral/FlutterInputs.xcfilelist, + ); + inputPaths = ( + Flutter/ephemeral/tripwire, + ); + outputFileListPaths = ( + Flutter/ephemeral/FlutterOutputs.xcfilelist, + ); + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"$FLUTTER_ROOT\"/packages/flutter_tools/bin/macos_assemble.sh && touch Flutter/ephemeral/tripwire"; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 331C80D1294CF70F00263BE5 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 331C80D8294CF71000263BE5 /* RunnerTests.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 33CC10E92044A3C60003C045 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 33CC11132044BFA00003C045 /* MainFlutterWindow.swift in Sources */, + 33CC10F12044A3C60003C045 /* AppDelegate.swift in Sources */, + 335BBD1B22A9A15E00E9071D /* GeneratedPluginRegistrant.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + 331C80DA294CF71000263BE5 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 33CC10EC2044A3C60003C045 /* Runner */; + targetProxy = 331C80D9294CF71000263BE5 /* PBXContainerItemProxy */; + }; + 33CC11202044C79F0003C045 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 33CC111A2044C6BA0003C045 /* Flutter Assemble */; + targetProxy = 33CC111F2044C79F0003C045 /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin PBXVariantGroup section */ + 33CC10F42044A3C60003C045 /* MainMenu.xib */ = { + isa = PBXVariantGroup; + children = ( + 33CC10F52044A3C60003C045 /* Base */, + ); + name = MainMenu.xib; + path = Runner; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 331C80DB294CF71000263BE5 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CURRENT_PROJECT_VERSION = 1; + GENERATE_INFOPLIST_FILE = YES; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.example.licenseflavorpatchtest.licenseFlavorPatchTest.RunnerTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/license_flavor_patch_test.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/license_flavor_patch_test"; + }; + name = Debug; + }; + 331C80DC294CF71000263BE5 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CURRENT_PROJECT_VERSION = 1; + GENERATE_INFOPLIST_FILE = YES; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.example.licenseflavorpatchtest.licenseFlavorPatchTest.RunnerTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/license_flavor_patch_test.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/license_flavor_patch_test"; + }; + name = Release; + }; + 331C80DD294CF71000263BE5 /* Profile */ = { + isa = XCBuildConfiguration; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CURRENT_PROJECT_VERSION = 1; + GENERATE_INFOPLIST_FILE = YES; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.example.licenseflavorpatchtest.licenseFlavorPatchTest.RunnerTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/license_flavor_patch_test.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/license_flavor_patch_test"; + }; + name = Profile; + }; + 338D0CE9231458BD00FA5F75 /* Profile */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CODE_SIGN_IDENTITY = "-"; + COPY_PHASE_STRIP = NO; + DEAD_CODE_STRIPPING = YES; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_USER_SCRIPT_SANDBOXING = NO; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + MACOSX_DEPLOYMENT_TARGET = 10.15; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = macosx; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + }; + name = Profile; + }; + 338D0CEA231458BD00FA5F75 /* Profile */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 33E5194F232828860026EE4D /* AppInfo.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_ENTITLEMENTS = Runner/DebugProfile.entitlements; + CODE_SIGN_STYLE = Automatic; + COMBINE_HIDPI_IMAGES = YES; + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/../Frameworks", + ); + PROVISIONING_PROFILE_SPECIFIER = ""; + SWIFT_VERSION = 5.0; + }; + name = Profile; + }; + 338D0CEB231458BD00FA5F75 /* Profile */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Manual; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Profile; + }; + 33CC10F92044A3C60003C045 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CODE_SIGN_IDENTITY = "-"; + COPY_PHASE_STRIP = NO; + DEAD_CODE_STRIPPING = YES; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + ENABLE_USER_SCRIPT_SANDBOXING = NO; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + MACOSX_DEPLOYMENT_TARGET = 10.15; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = macosx; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Debug; + }; + 33CC10FA2044A3C60003C045 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CODE_SIGN_IDENTITY = "-"; + COPY_PHASE_STRIP = NO; + DEAD_CODE_STRIPPING = YES; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_USER_SCRIPT_SANDBOXING = NO; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + MACOSX_DEPLOYMENT_TARGET = 10.15; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = macosx; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + }; + name = Release; + }; + 33CC10FC2044A3C60003C045 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 33E5194F232828860026EE4D /* AppInfo.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_ENTITLEMENTS = Runner/DebugProfile.entitlements; + CODE_SIGN_STYLE = Automatic; + COMBINE_HIDPI_IMAGES = YES; + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/../Frameworks", + ); + PROVISIONING_PROFILE_SPECIFIER = ""; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 5.0; + }; + name = Debug; + }; + 33CC10FD2044A3C60003C045 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 33E5194F232828860026EE4D /* AppInfo.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_ENTITLEMENTS = Runner/Release.entitlements; + CODE_SIGN_STYLE = Automatic; + COMBINE_HIDPI_IMAGES = YES; + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/../Frameworks", + ); + PROVISIONING_PROFILE_SPECIFIER = ""; + SWIFT_VERSION = 5.0; + }; + name = Release; + }; + 33CC111C2044C6BA0003C045 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Manual; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + 33CC111D2044C6BA0003C045 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 331C80DE294CF71000263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 331C80DB294CF71000263BE5 /* Debug */, + 331C80DC294CF71000263BE5 /* Release */, + 331C80DD294CF71000263BE5 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 33CC10E82044A3C60003C045 /* Build configuration list for PBXProject "Runner" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 33CC10F92044A3C60003C045 /* Debug */, + 33CC10FA2044A3C60003C045 /* Release */, + 338D0CE9231458BD00FA5F75 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 33CC10FB2044A3C60003C045 /* Build configuration list for PBXNativeTarget "Runner" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 33CC10FC2044A3C60003C045 /* Debug */, + 33CC10FD2044A3C60003C045 /* Release */, + 338D0CEA231458BD00FA5F75 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 33CC111B2044C6BA0003C045 /* Build configuration list for PBXAggregateTarget "Flutter Assemble" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 33CC111C2044C6BA0003C045 /* Debug */, + 33CC111D2044C6BA0003C045 /* Release */, + 338D0CEB231458BD00FA5F75 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + +/* Begin XCLocalSwiftPackageReference section */ + 781AD8BC2B33823900A9FFBB /* XCLocalSwiftPackageReference "Flutter/ephemeral/Packages/FlutterGeneratedPluginSwiftPackage" */ = { + isa = XCLocalSwiftPackageReference; + relativePath = Flutter/ephemeral/Packages/FlutterGeneratedPluginSwiftPackage; + }; +/* End XCLocalSwiftPackageReference section */ + +/* Begin XCSwiftPackageProductDependency section */ + 78A3181F2AECB46A00862997 /* FlutterGeneratedPluginSwiftPackage */ = { + isa = XCSwiftPackageProductDependency; + productName = FlutterGeneratedPluginSwiftPackage; + }; +/* End XCSwiftPackageProductDependency section */ + }; + rootObject = 33CC10E52044A3C60003C045 /* Project object */; +} diff --git a/testapps/license_flavor_patch_test/macos/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/testapps/license_flavor_patch_test/macos/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000..18d9810 --- /dev/null +++ b/testapps/license_flavor_patch_test/macos/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/testapps/license_flavor_patch_test/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/testapps/license_flavor_patch_test/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme new file mode 100644 index 0000000..cda73cf --- /dev/null +++ b/testapps/license_flavor_patch_test/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -0,0 +1,117 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/testapps/license_flavor_patch_test/macos/Runner.xcworkspace/contents.xcworkspacedata b/testapps/license_flavor_patch_test/macos/Runner.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..1d526a1 --- /dev/null +++ b/testapps/license_flavor_patch_test/macos/Runner.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/testapps/license_flavor_patch_test/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/testapps/license_flavor_patch_test/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000..18d9810 --- /dev/null +++ b/testapps/license_flavor_patch_test/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/testapps/license_flavor_patch_test/macos/Runner/AppDelegate.swift b/testapps/license_flavor_patch_test/macos/Runner/AppDelegate.swift new file mode 100644 index 0000000..b3c1761 --- /dev/null +++ b/testapps/license_flavor_patch_test/macos/Runner/AppDelegate.swift @@ -0,0 +1,13 @@ +import Cocoa +import FlutterMacOS + +@main +class AppDelegate: FlutterAppDelegate { + override func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool { + return true + } + + override func applicationSupportsSecureRestorableState(_ app: NSApplication) -> Bool { + return true + } +} diff --git a/testapps/license_flavor_patch_test/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/testapps/license_flavor_patch_test/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..a2ec33f --- /dev/null +++ b/testapps/license_flavor_patch_test/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,68 @@ +{ + "images" : [ + { + "size" : "16x16", + "idiom" : "mac", + "filename" : "app_icon_16.png", + "scale" : "1x" + }, + { + "size" : "16x16", + "idiom" : "mac", + "filename" : "app_icon_32.png", + "scale" : "2x" + }, + { + "size" : "32x32", + "idiom" : "mac", + "filename" : "app_icon_32.png", + "scale" : "1x" + }, + { + "size" : "32x32", + "idiom" : "mac", + "filename" : "app_icon_64.png", + "scale" : "2x" + }, + { + "size" : "128x128", + "idiom" : "mac", + "filename" : "app_icon_128.png", + "scale" : "1x" + }, + { + "size" : "128x128", + "idiom" : "mac", + "filename" : "app_icon_256.png", + "scale" : "2x" + }, + { + "size" : "256x256", + "idiom" : "mac", + "filename" : "app_icon_256.png", + "scale" : "1x" + }, + { + "size" : "256x256", + "idiom" : "mac", + "filename" : "app_icon_512.png", + "scale" : "2x" + }, + { + "size" : "512x512", + "idiom" : "mac", + "filename" : "app_icon_512.png", + "scale" : "1x" + }, + { + "size" : "512x512", + "idiom" : "mac", + "filename" : "app_icon_1024.png", + "scale" : "2x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} diff --git a/testapps/license_flavor_patch_test/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png b/testapps/license_flavor_patch_test/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png new file mode 100644 index 0000000..82b6f9d Binary files /dev/null and b/testapps/license_flavor_patch_test/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png differ diff --git a/testapps/license_flavor_patch_test/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png b/testapps/license_flavor_patch_test/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png new file mode 100644 index 0000000..13b35eb Binary files /dev/null and b/testapps/license_flavor_patch_test/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png differ diff --git a/testapps/license_flavor_patch_test/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png b/testapps/license_flavor_patch_test/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png new file mode 100644 index 0000000..0a3f5fa Binary files /dev/null and b/testapps/license_flavor_patch_test/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png differ diff --git a/testapps/license_flavor_patch_test/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png b/testapps/license_flavor_patch_test/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png new file mode 100644 index 0000000..bdb5722 Binary files /dev/null and b/testapps/license_flavor_patch_test/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png differ diff --git a/testapps/license_flavor_patch_test/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png b/testapps/license_flavor_patch_test/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png new file mode 100644 index 0000000..f083318 Binary files /dev/null and b/testapps/license_flavor_patch_test/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png differ diff --git a/testapps/license_flavor_patch_test/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png b/testapps/license_flavor_patch_test/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png new file mode 100644 index 0000000..326c0e7 Binary files /dev/null and b/testapps/license_flavor_patch_test/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png differ diff --git a/testapps/license_flavor_patch_test/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png b/testapps/license_flavor_patch_test/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png new file mode 100644 index 0000000..2f1632c Binary files /dev/null and b/testapps/license_flavor_patch_test/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png differ diff --git a/testapps/license_flavor_patch_test/macos/Runner/Base.lproj/MainMenu.xib b/testapps/license_flavor_patch_test/macos/Runner/Base.lproj/MainMenu.xib new file mode 100644 index 0000000..80e867a --- /dev/null +++ b/testapps/license_flavor_patch_test/macos/Runner/Base.lproj/MainMenu.xib @@ -0,0 +1,343 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/testapps/license_flavor_patch_test/macos/Runner/Configs/AppInfo.xcconfig b/testapps/license_flavor_patch_test/macos/Runner/Configs/AppInfo.xcconfig new file mode 100644 index 0000000..e591aae --- /dev/null +++ b/testapps/license_flavor_patch_test/macos/Runner/Configs/AppInfo.xcconfig @@ -0,0 +1,14 @@ +// Application-level settings for the Runner target. +// +// This may be replaced with something auto-generated from metadata (e.g., pubspec.yaml) in the +// future. If not, the values below would default to using the project name when this becomes a +// 'flutter create' template. + +// The application's name. By default this is also the title of the Flutter window. +PRODUCT_NAME = license_flavor_patch_test + +// The application's bundle identifier +PRODUCT_BUNDLE_IDENTIFIER = com.example.licenseflavorpatchtest.licenseFlavorPatchTest + +// The copyright displayed in application information +PRODUCT_COPYRIGHT = Copyright © 2026 com.example.licenseflavorpatchtest. All rights reserved. diff --git a/testapps/license_flavor_patch_test/macos/Runner/Configs/Debug.xcconfig b/testapps/license_flavor_patch_test/macos/Runner/Configs/Debug.xcconfig new file mode 100644 index 0000000..36b0fd9 --- /dev/null +++ b/testapps/license_flavor_patch_test/macos/Runner/Configs/Debug.xcconfig @@ -0,0 +1,2 @@ +#include "../../Flutter/Flutter-Debug.xcconfig" +#include "Warnings.xcconfig" diff --git a/testapps/license_flavor_patch_test/macos/Runner/Configs/Release.xcconfig b/testapps/license_flavor_patch_test/macos/Runner/Configs/Release.xcconfig new file mode 100644 index 0000000..dff4f49 --- /dev/null +++ b/testapps/license_flavor_patch_test/macos/Runner/Configs/Release.xcconfig @@ -0,0 +1,2 @@ +#include "../../Flutter/Flutter-Release.xcconfig" +#include "Warnings.xcconfig" diff --git a/testapps/license_flavor_patch_test/macos/Runner/Configs/Warnings.xcconfig b/testapps/license_flavor_patch_test/macos/Runner/Configs/Warnings.xcconfig new file mode 100644 index 0000000..42bcbf4 --- /dev/null +++ b/testapps/license_flavor_patch_test/macos/Runner/Configs/Warnings.xcconfig @@ -0,0 +1,13 @@ +WARNING_CFLAGS = -Wall -Wconditional-uninitialized -Wnullable-to-nonnull-conversion -Wmissing-method-return-type -Woverlength-strings +GCC_WARN_UNDECLARED_SELECTOR = YES +CLANG_UNDEFINED_BEHAVIOR_SANITIZER_NULLABILITY = YES +CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE +CLANG_WARN__DUPLICATE_METHOD_MATCH = YES +CLANG_WARN_PRAGMA_PACK = YES +CLANG_WARN_STRICT_PROTOTYPES = YES +CLANG_WARN_COMMA = YES +GCC_WARN_STRICT_SELECTOR_MATCH = YES +CLANG_WARN_OBJC_REPEATED_USE_OF_WEAK = YES +CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES +GCC_WARN_SHADOW = YES +CLANG_WARN_UNREACHABLE_CODE = YES diff --git a/testapps/license_flavor_patch_test/macos/Runner/DebugProfile.entitlements b/testapps/license_flavor_patch_test/macos/Runner/DebugProfile.entitlements new file mode 100644 index 0000000..dddb8a3 --- /dev/null +++ b/testapps/license_flavor_patch_test/macos/Runner/DebugProfile.entitlements @@ -0,0 +1,12 @@ + + + + + com.apple.security.app-sandbox + + com.apple.security.cs.allow-jit + + com.apple.security.network.server + + + diff --git a/testapps/license_flavor_patch_test/macos/Runner/Info.plist b/testapps/license_flavor_patch_test/macos/Runner/Info.plist new file mode 100644 index 0000000..4789daa --- /dev/null +++ b/testapps/license_flavor_patch_test/macos/Runner/Info.plist @@ -0,0 +1,32 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIconFile + + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + $(FLUTTER_BUILD_NAME) + CFBundleVersion + $(FLUTTER_BUILD_NUMBER) + LSMinimumSystemVersion + $(MACOSX_DEPLOYMENT_TARGET) + NSHumanReadableCopyright + $(PRODUCT_COPYRIGHT) + NSMainNibFile + MainMenu + NSPrincipalClass + NSApplication + + diff --git a/testapps/license_flavor_patch_test/macos/Runner/MainFlutterWindow.swift b/testapps/license_flavor_patch_test/macos/Runner/MainFlutterWindow.swift new file mode 100644 index 0000000..3cc05eb --- /dev/null +++ b/testapps/license_flavor_patch_test/macos/Runner/MainFlutterWindow.swift @@ -0,0 +1,15 @@ +import Cocoa +import FlutterMacOS + +class MainFlutterWindow: NSWindow { + override func awakeFromNib() { + let flutterViewController = FlutterViewController() + let windowFrame = self.frame + self.contentViewController = flutterViewController + self.setFrame(windowFrame, display: true) + + RegisterGeneratedPlugins(registry: flutterViewController) + + super.awakeFromNib() + } +} diff --git a/testapps/license_flavor_patch_test/macos/Runner/Release.entitlements b/testapps/license_flavor_patch_test/macos/Runner/Release.entitlements new file mode 100644 index 0000000..852fa1a --- /dev/null +++ b/testapps/license_flavor_patch_test/macos/Runner/Release.entitlements @@ -0,0 +1,8 @@ + + + + + com.apple.security.app-sandbox + + + diff --git a/testapps/license_flavor_patch_test/macos/RunnerTests/RunnerTests.swift b/testapps/license_flavor_patch_test/macos/RunnerTests/RunnerTests.swift new file mode 100644 index 0000000..61f3bd1 --- /dev/null +++ b/testapps/license_flavor_patch_test/macos/RunnerTests/RunnerTests.swift @@ -0,0 +1,12 @@ +import Cocoa +import FlutterMacOS +import XCTest + +class RunnerTests: XCTestCase { + + func testExample() { + // If you add code to the Runner application, consider adding tests here. + // See https://developer.apple.com/documentation/xctest for more information about using XCTest. + } + +} diff --git a/testapps/license_flavor_patch_test/pubspec.lock b/testapps/license_flavor_patch_test/pubspec.lock index 3dc43b3..90d3e9b 100644 --- a/testapps/license_flavor_patch_test/pubspec.lock +++ b/testapps/license_flavor_patch_test/pubspec.lock @@ -54,6 +54,14 @@ packages: description: flutter source: sdk version: "0.0.0" + flutter_lints: + dependency: "direct dev" + description: + name: flutter_lints + sha256: "3105dc8492f6183fb076ccf1f351ac3d60564bff92e20bfc4af9cc1651f4e7e1" + url: "https://pub.dev" + source: hosted + version: "6.0.0" flutter_test: dependency: "direct dev" description: flutter @@ -83,6 +91,14 @@ packages: url: "https://pub.dev" source: hosted version: "3.0.2" + lints: + dependency: transitive + description: + name: lints + sha256: "12f842a479589fea194fe5c5a3095abc7be0c1f2ddfa9a0e76aed1dbd26a87df" + url: "https://pub.dev" + source: hosted + version: "6.1.0" matcher: dependency: transitive description: @@ -103,10 +119,10 @@ packages: dependency: transitive description: name: meta - sha256: "23f08335362185a5ea2ad3a4e597f1375e78bce8a040df5c600c8d3552ef2394" + sha256: "1741988757a65eb6b36abe716829688cf01910bbf91c34354ff7ec1c3de2b349" url: "https://pub.dev" source: hosted - version: "1.17.0" + version: "1.18.0" path: dependency: transitive description: @@ -164,10 +180,10 @@ packages: dependency: transitive description: name: test_api - sha256: "8161c84903fd860b26bfdefb7963b3f0b68fee7adea0f59ef805ecca346f0c7a" + sha256: "949a932224383300f01be9221c39180316445ecb8e7547f70a41a35bf421fb9e" url: "https://pub.dev" source: hosted - version: "0.7.10" + version: "0.7.11" vector_math: dependency: transitive description: @@ -185,5 +201,5 @@ packages: source: hosted version: "15.2.0" sdks: - dart: ">=3.9.0 <4.0.0" + dart: ">=3.10.0-0 <4.0.0" flutter: ">=3.18.0-18.0.pre.54" diff --git a/testapps/license_flavor_patch_test/pubspec.yaml b/testapps/license_flavor_patch_test/pubspec.yaml index b3b901c..ccc097b 100644 --- a/testapps/license_flavor_patch_test/pubspec.yaml +++ b/testapps/license_flavor_patch_test/pubspec.yaml @@ -12,6 +12,7 @@ dependencies: dev_dependencies: flutter_test: sdk: flutter + flutter_lints: ^6.0.0 flutter: uses-material-design: true diff --git a/testapps/license_flavor_patch_test/shorebird.yaml b/testapps/license_flavor_patch_test/shorebird.yaml index 243d9b1..1122e72 100644 --- a/testapps/license_flavor_patch_test/shorebird.yaml +++ b/testapps/license_flavor_patch_test/shorebird.yaml @@ -1,4 +1,12 @@ app_id: license-flavor-patch-test +aot_patch_key_id: test-key +aot_patch_key_hex: "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f" +aot_patch_base_flavor_id: free +aot_patch_base_license_type: free +aot_patch_flavor_id: pro +aot_patch_license_type: pro +aot_patch_sdk_hash: 98fd753f4b3b45929a3266dada4322df0824072be56fdd7e2d3cb208f6a4d3a7 +aot_patch_base_snapshot_hash: 8dd6ed61971e6e0ca7994f003b6adf827dfaef7538dd19e13964fc284cf111af flavors: free: license-flavor-free pro: license-flavor-pro diff --git a/testapps/license_flavor_patch_test/test/widget_test.dart b/testapps/license_flavor_patch_test/test/widget_test.dart new file mode 100644 index 0000000..e2a07e6 --- /dev/null +++ b/testapps/license_flavor_patch_test/test/widget_test.dart @@ -0,0 +1,12 @@ +import 'package:flutter_test/flutter_test.dart'; + +import 'package:license_flavor_patch_test/main.dart'; + +void main() { + testWidgets('renders default license status', (tester) async { + await tester.pumpWidget(const LicenseFlavorPatchApp()); + + expect(find.text('license:free'), findsOneWidget); + expect(find.text('pro-feature:off'), findsOneWidget); + }); +} diff --git a/testapps/license_flavor_patch_test/tool/verify_aot_patch.dart b/testapps/license_flavor_patch_test/tool/verify_aot_patch.dart index 084779e..5d40940 100644 --- a/testapps/license_flavor_patch_test/tool/verify_aot_patch.dart +++ b/testapps/license_flavor_patch_test/tool/verify_aot_patch.dart @@ -5,7 +5,7 @@ Future main() async { final appDir = File.fromUri(Platform.script).parent.parent; final workspaceRoot = appDir.parent.parent; final dartRoot = Directory('${workspaceRoot.path}/dart-sdk-new'); - final patchBuildDir = Directory('${dartRoot.path}/out/ReleaseX64AotPatch'); + final patchBuildDir = _resolvePatchBuildDir(dartRoot); final toolWorkspace = Directory('${workspaceRoot.path}/shorebird'); final workDir = Directory('${appDir.path}/build/open_aot_patch_verify'); @@ -17,12 +17,38 @@ Future main() async { ); } final args = argsFile.readAsStringSync(); - if (!args.contains('dart_enable_aot_patching = true') || - !args.contains('dart_dynamic_modules = false')) { + if (!_gnBool(args, 'dart_enable_aot_patching') || + _gnBool(args, 'dart_dynamic_modules')) { throw StateError( '${argsFile.path} must enable AOT patching and disable dynamic modules.', ); } + final targetOs = _targetOs(args); + final targetArch = _targetArch(args); + final dart = _resolveExecutable([ + '${patchBuildDir.path}/dart-sdk/bin/dart', + '${patchBuildDir.path}/dart', + '${dartRoot.path}/tools/sdks/dart-sdk/bin/dart', + ], 'dart'); + final genSnapshot = _resolveExecutable([ + '${patchBuildDir.path}/gen_snapshot_product', + '${patchBuildDir.path}/exe.stripped/gen_snapshot_product', + '${patchBuildDir.path}/gen_snapshot', + '${patchBuildDir.path}/exe.stripped/gen_snapshot', + ], 'gen_snapshot'); + final dartaotruntime = _resolveExecutable([ + '${patchBuildDir.path}/dartaotruntime_product', + '${patchBuildDir.path}/exe.stripped/dartaotruntime_product', + '${patchBuildDir.path}/dartaotruntime', + '${patchBuildDir.path}/dart-sdk/bin/dartaotruntime', + '${patchBuildDir.path}/exe.stripped/dartaotruntime', + ], 'dartaotruntime'); + final vmPlatformProduct = File( + '${patchBuildDir.path}/vm_platform_product.dill', + ); + if (!vmPlatformProduct.existsSync()) { + throw StateError('Missing ${vmPlatformProduct.path}.'); + } if (workDir.existsSync()) { workDir.deleteSync(recursive: true); @@ -53,7 +79,10 @@ Future main() async { await _compileAot( workspaceRoot: workspaceRoot, dartRoot: dartRoot, - patchBuildDir: patchBuildDir, + dart: dart, + genSnapshot: genSnapshot, + vmPlatformProduct: vmPlatformProduct, + targetOs: targetOs, packageConfig: packageConfig, licenseType: 'free', outputVmcode: baseVmcode, @@ -62,7 +91,10 @@ Future main() async { await _compileAot( workspaceRoot: workspaceRoot, dartRoot: dartRoot, - patchBuildDir: patchBuildDir, + dart: dart, + genSnapshot: genSnapshot, + vmPlatformProduct: vmPlatformProduct, + targetOs: targetOs, packageConfig: packageConfig, licenseType: 'pro', outputVmcode: patchVmcode, @@ -71,12 +103,12 @@ Future main() async { ); _expectStatus( - await _runAot(patchBuildDir, baseVmcode), + await _runAot(dartaotruntime, baseVmcode), license: 'free', proFeature: false, ); _expectStatus( - await _runAot(patchBuildDir, patchVmcode), + await _runAot(dartaotruntime, patchVmcode), license: 'pro', proFeature: true, ); @@ -94,7 +126,7 @@ Future main() async { const beforeExpiry = '2029-01-01T00:00:00Z'; const afterExpiry = '2031-01-01T00:00:00Z'; - await _runTool(toolWorkspace, [ + await _runTool(toolWorkspace, dart, [ 'link', '--base=${baseVmcode.path}', '--patch=${patchVmcode.path}', @@ -105,9 +137,9 @@ Future main() async { '--base-license-type=free', '--flavor-id=pro', '--license-type=pro', - '--sdk-hash=${_sha256File(File('${patchBuildDir.path}/gen_snapshot.exe'))}', - '--target-os=windows', - '--target-arch=x64', + '--sdk-hash=${_sha256File(genSnapshot)}', + '--target-os=$targetOs', + '--target-arch=$targetArch', '--obfuscation-map-hash=${_sha256File(baseMap)}', '--offline-expires-at=$offlineExpiresAt', '--full-snapshot=true', @@ -123,7 +155,7 @@ Future main() async { throw StateError('Expected normalized offline_expires_at metadata.'); } - await _runTool(toolWorkspace, [ + await _runTool(toolWorkspace, dart, [ 'encrypt', '--input=${artifact.path}', '--output=${encrypted.path}', @@ -132,7 +164,7 @@ Future main() async { '--nonce-hex=$nonceHex', ]); - await _runTool(toolWorkspace, [ + await _runTool(toolWorkspace, dart, [ 'verify', '--input=${encrypted.path}', '--key-hex=$keyHex', @@ -144,7 +176,7 @@ Future main() async { '--base=${baseVmcode.path}', '--now=$beforeExpiry', ]); - await _runToolExpectFailure(toolWorkspace, [ + await _runToolExpectFailure(toolWorkspace, dart, [ 'verify', '--input=${encrypted.path}', '--key-hex=$keyHex', @@ -155,7 +187,7 @@ Future main() async { '--base=${baseVmcode.path}', '--now=$afterExpiry', ]); - await _runToolExpectFailure(toolWorkspace, [ + await _runToolExpectFailure(toolWorkspace, dart, [ 'verify', '--input=${encrypted.path}', '--key-hex=$wrongKeyHex', @@ -165,7 +197,7 @@ Future main() async { '--license-type=pro', '--base=${baseVmcode.path}', ]); - await _runToolExpectFailure(toolWorkspace, [ + await _runToolExpectFailure(toolWorkspace, dart, [ 'verify', '--input=${encrypted.path}', '--key-hex=$keyHex', @@ -176,7 +208,7 @@ Future main() async { '--base=${baseVmcode.path}', ]); - await _runTool(toolWorkspace, [ + await _runTool(toolWorkspace, dart, [ 'dump-blobs', '--input=${encrypted.path}', '--key-hex=$keyHex', @@ -189,12 +221,12 @@ Future main() async { } _expectStatus( - await _runAot(patchBuildDir, reconstructedVmcode), + await _runAot(dartaotruntime, reconstructedVmcode), license: 'pro', proFeature: true, ); - await _runToolExpectFailure(toolWorkspace, [ + await _runToolExpectFailure(toolWorkspace, dart, [ 'dump-blobs', '--input=${encrypted.path}', '--key-hex=$keyHex', @@ -215,27 +247,29 @@ Future main() async { Future _compileAot({ required Directory workspaceRoot, required Directory dartRoot, - required Directory patchBuildDir, + required File dart, + required File genSnapshot, + required File vmPlatformProduct, + required String targetOs, required File packageConfig, required String licenseType, required File outputVmcode, required File saveObfuscationMap, File? loadObfuscationMap, }) async { - final dart = '${dartRoot.path}/tools/sdks/dart-sdk/bin/dart.exe'; final genKernel = '${dartRoot.path}/pkg/vm/bin/gen_kernel.dart'; final source = '${workspaceRoot.path}/testapps/license_flavor_patch_test/bin/license_status.dart'; final dill = File('${outputVmcode.parent.path}/${licenseType}_app.dill'); - await _run(dart, [ + await _run(dart.path, [ genKernel, '--packages', packageConfig.path, '--platform', - '${patchBuildDir.path}/vm_platform_product.dill', + vmPlatformProduct.path, '--aot', '--target-os', - 'windows', + targetOs, '-Ddart.vm.product=true', '-DLICENSE_TYPE=$licenseType', '-o', @@ -245,10 +279,8 @@ Future _compileAot({ source, ]); - final genSnapshot = '${patchBuildDir.path}/gen_snapshot.exe'; - await _run(genSnapshot, [ - '--snapshot-kind=app-aot-elf', - '--elf=${outputVmcode.path}', + await _run(genSnapshot.path, [ + ..._snapshotOutputArgs(targetOs, outputVmcode), '--strip', '--obfuscate', if (loadObfuscationMap != null) @@ -258,33 +290,31 @@ Future _compileAot({ ]); } -Future _runAot(Directory patchBuildDir, File vmcode) async { - final result = await _run('${patchBuildDir.path}/dartaotruntime.exe', [ - vmcode.path, - ]); +Future _runAot(File dartaotruntime, File vmcode) async { + final result = await _run(dartaotruntime.path, [vmcode.path]); return result.stdout as String; } Future _runTool( Directory toolWorkspace, + File dart, List args, ) async { - return _run( - '${toolWorkspace.parent.path}/dart-sdk-new/tools/sdks/dart-sdk/bin/dart.exe', - ['packages/open_aot_patch_tools/bin/open_aot_patch_tools.dart', ...args], - workingDirectory: toolWorkspace, - ); + return _run(dart.path, [ + 'packages/open_aot_patch_tools/bin/open_aot_patch_tools.dart', + ...args, + ], workingDirectory: toolWorkspace); } Future _runToolExpectFailure( Directory toolWorkspace, + File dart, List args, ) async { - final result = await Process.run( - '${toolWorkspace.parent.path}/dart-sdk-new/tools/sdks/dart-sdk/bin/dart.exe', - ['packages/open_aot_patch_tools/bin/open_aot_patch_tools.dart', ...args], - workingDirectory: toolWorkspace.path, - ); + final result = await Process.run(dart.path, [ + 'packages/open_aot_patch_tools/bin/open_aot_patch_tools.dart', + ...args, + ], workingDirectory: toolWorkspace.path); if (result.exitCode == 0) { throw StateError( 'Expected open_aot_patch_tools ${args.join(' ')} to fail.', @@ -293,6 +323,77 @@ Future _runToolExpectFailure( return result; } +Directory _resolvePatchBuildDir(Directory dartRoot) { + final override = Platform.environment['AOT_PATCH_BUILD_DIR']; + if (override != null && override.isNotEmpty) { + return Directory(override); + } + final candidates = [ + '${dartRoot.path}/xcodebuild/ReleaseARM64', + '${dartRoot.path}/out/ReleaseARM64AotPatch', + '${dartRoot.path}/out/ReleaseX64AotPatch', + ]; + for (final path in candidates) { + final dir = Directory(path); + if (File('${dir.path}/args.gn').existsSync()) { + return dir; + } + } + return Directory(candidates.first); +} + +File _resolveExecutable(List candidates, String name) { + final suffix = Platform.isWindows ? '.exe' : ''; + for (final path in candidates) { + final file = File('$path$suffix'); + if (file.existsSync()) { + return file; + } + } + throw StateError( + 'Unable to find $name. Tried:\n' + '${candidates.map((path) => ' $path$suffix').join('\n')}', + ); +} + +bool _gnBool(String args, String key) { + final value = _gnString(args, key); + return value == 'true'; +} + +String? _gnString(String args, String key) { + final match = RegExp( + '^$key = (?:"([^"]+)"|(true|false))\$', + multiLine: true, + ).firstMatch(args); + return match?.group(1) ?? match?.group(2); +} + +String _targetOs(String args) { + final targetOs = _gnString(args, 'target_os') ?? Platform.operatingSystem; + return switch (targetOs) { + 'mac' => 'macos', + 'win' => 'windows', + _ => targetOs, + }; +} + +String _targetArch(String args) { + return _gnString(args, 'dart_target_arch') ?? + _gnString(args, 'target_cpu') ?? + 'x64'; +} + +List _snapshotOutputArgs(String targetOs, File outputVmcode) { + return switch (targetOs) { + 'ios' || 'macos' => [ + '--snapshot-kind=app-aot-macho-dylib', + '--macho=${outputVmcode.path}', + ], + _ => ['--snapshot-kind=app-aot-elf', '--elf=${outputVmcode.path}'], + }; +} + Future _run( String executable, List args, { @@ -340,15 +441,16 @@ void _expectStatus( } String _sha256File(File file) { - final result = Process.runSync('certutil', [ - '-hashfile', - file.path, - 'SHA256', - ]); + final (executable, args) = switch (Platform.operatingSystem) { + 'windows' => ('certutil', ['-hashfile', file.path, 'SHA256']), + 'macos' => ('shasum', ['-a', '256', file.path]), + _ => ('sha256sum', [file.path]), + }; + final result = Process.runSync(executable, args); if (result.exitCode != 0) { throw ProcessException( - 'certutil', - ['-hashfile', file.path, 'SHA256'], + executable, + args, result.stderr.toString(), result.exitCode, ); diff --git a/testapps/license_flavor_patch_test/web/favicon.png b/testapps/license_flavor_patch_test/web/favicon.png new file mode 100644 index 0000000..8aaa46a Binary files /dev/null and b/testapps/license_flavor_patch_test/web/favicon.png differ diff --git a/testapps/license_flavor_patch_test/web/icons/Icon-192.png b/testapps/license_flavor_patch_test/web/icons/Icon-192.png new file mode 100644 index 0000000..b749bfe Binary files /dev/null and b/testapps/license_flavor_patch_test/web/icons/Icon-192.png differ diff --git a/testapps/license_flavor_patch_test/web/icons/Icon-512.png b/testapps/license_flavor_patch_test/web/icons/Icon-512.png new file mode 100644 index 0000000..88cfd48 Binary files /dev/null and b/testapps/license_flavor_patch_test/web/icons/Icon-512.png differ diff --git a/testapps/license_flavor_patch_test/web/icons/Icon-maskable-192.png b/testapps/license_flavor_patch_test/web/icons/Icon-maskable-192.png new file mode 100644 index 0000000..eb9b4d7 Binary files /dev/null and b/testapps/license_flavor_patch_test/web/icons/Icon-maskable-192.png differ diff --git a/testapps/license_flavor_patch_test/web/icons/Icon-maskable-512.png b/testapps/license_flavor_patch_test/web/icons/Icon-maskable-512.png new file mode 100644 index 0000000..d69c566 Binary files /dev/null and b/testapps/license_flavor_patch_test/web/icons/Icon-maskable-512.png differ diff --git a/testapps/license_flavor_patch_test/web/index.html b/testapps/license_flavor_patch_test/web/index.html new file mode 100644 index 0000000..aac5325 --- /dev/null +++ b/testapps/license_flavor_patch_test/web/index.html @@ -0,0 +1,46 @@ + + + + + + + + + + + + + + + + + + + + license_flavor_patch_test + + + + + + + diff --git a/testapps/license_flavor_patch_test/web/manifest.json b/testapps/license_flavor_patch_test/web/manifest.json new file mode 100644 index 0000000..abf0726 --- /dev/null +++ b/testapps/license_flavor_patch_test/web/manifest.json @@ -0,0 +1,35 @@ +{ + "name": "license_flavor_patch_test", + "short_name": "license_flavor_patch_test", + "start_url": ".", + "display": "standalone", + "background_color": "#0175C2", + "theme_color": "#0175C2", + "description": "A new Flutter project.", + "orientation": "portrait-primary", + "prefer_related_applications": false, + "icons": [ + { + "src": "icons/Icon-192.png", + "sizes": "192x192", + "type": "image/png" + }, + { + "src": "icons/Icon-512.png", + "sizes": "512x512", + "type": "image/png" + }, + { + "src": "icons/Icon-maskable-192.png", + "sizes": "192x192", + "type": "image/png", + "purpose": "maskable" + }, + { + "src": "icons/Icon-maskable-512.png", + "sizes": "512x512", + "type": "image/png", + "purpose": "maskable" + } + ] +}