Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
245164c
chore(release): upgrade engine to Flutter 3.44.2 (1.3.1)
MAUstaoglu Jun 14, 2026
f9d655a
fix(platform): make tvOS platform identity correct in AOT/release builds
MAUstaoglu Jun 16, 2026
409d812
fix(rcu): retry the configure handshake until the native plugin is ready
MAUstaoglu Jun 16, 2026
08581da
docs(changelog): document the AOT platform-identity fix in 1.3.1
MAUstaoglu Jun 16, 2026
5882954
fix(platform): compile profile AOT against the non-product host SDK
MAUstaoglu Jun 16, 2026
987f4c8
docs(changelog): note on-device debug (JIT/hot reload) fix for tvOS 26
MAUstaoglu Jun 16, 2026
b5bf86d
test(artifacts): assert engine variant selection per build mode
MAUstaoglu Jun 16, 2026
26cf7da
rcu: report configure-handshake exhaustion + narrow retry catch (PR #…
MAUstaoglu Jun 16, 2026
294b8b6
fix(precache): fetch only tvOS + universal artifacts
MAUstaoglu Jun 19, 2026
34e87f8
fix(create): exit with usage when no output directory given
MAUstaoglu Jun 19, 2026
e1e4d55
docs(changelog): note precache scope + create usage fixes
MAUstaoglu Jun 19, 2026
d30f330
Merge pull request #25 from fluttertv/fix/cli-precache-and-create
MAUstaoglu Jun 22, 2026
d8d042e
chore: upgrade to Flutter 3.44.3 (1.3.2)
MAUstaoglu Jun 22, 2026
9797085
docs: refresh READMEs for 3.44.3 and flutter_tvos 1.1.1
MAUstaoglu Jun 22, 2026
5e5f664
release(flutter_tvos): 1.1.2 (docs refresh)
MAUstaoglu Jun 22, 2026
7d5e358
chore: gitignore per-user SwiftPM/Xcode state under plugin tvos/
MAUstaoglu Jun 22, 2026
930e23d
Merge pull request #26 from fluttertv/feat/flutter-3.44.3-upgrade
MAUstaoglu Jun 22, 2026
75ac599
Merge remote-tracking branch 'origin/main' into dev
MAUstaoglu Jun 22, 2026
dc1a64d
refactor(precache): testable artifact selection + harden flag parsing…
MAUstaoglu Jun 22, 2026
7c91a9c
test: drop the create no-args test (transitively invokes Pub in CI)
MAUstaoglu Jun 22, 2026
a9d7a8d
Merge remote-tracking branch 'origin/main' into dev
MAUstaoglu Jul 17, 2026
57d585d
docs: PR template + contributing guide for the dev-branch workflow
MAUstaoglu Jul 17, 2026
fd8847d
docs(changelog): add [Unreleased] section for incoming PR entries
MAUstaoglu Jul 17, 2026
23692b2
Skip plugin registration with a clear message when the engine isn't r…
SupposedlySam Jul 17, 2026
7014a93
Bump engine and SDK to Flutter 3.44.6, fix tvOS<26 simulator crash (1…
MAUstaoglu Jul 20, 2026
4f7af73
Bump to Flutter 3.44.7 (1.4.2), fix Platform.isTvOS in debug builds (…
MAUstaoglu Jul 21, 2026
404c6ac
Merge main into dev
MAUstaoglu Jul 21, 2026
98d02ed
Merge pull request #42 from fluttertv/chore/sync-main-into-dev
MAUstaoglu Jul 21, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 35 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,41 @@ All notable changes to flutter-tvos will be documented here.

## [Unreleased]

## [1.4.2] - 2026-07-21

### Changed

- Bumped the pinned Flutter SDK to **3.44.7** (`84fc5cbb223b`).
- Engine artifacts are now `v1.0.1-flutter3.44.7`. These are **byte-identical**
to `v1.0.1-flutter3.44.6`, republished under the new name rather than
rebuilt: nothing in 3.44.7 reaches the tvOS engine. The only functional
change in the range is Android-side (`FlutterRenderer.java`), `DEPS` is
byte-identical, the Dart submodule is unchanged, and `darwin/`, `ios/` and
`impeller/` are untouched. The remaining commits are CI config and changelog
text.

Verified with these artifacts against the 3.44.7 SDK before shipping: AOT on a
physical Apple TV 4K (tvOS 26.5) keeps platform identity intact
(`operatingSystem=tvos`, `isTvOS=true`), and a JIT/debug run on a tvOS 17.5
simulator is clean with zero `Target OS is incompatible` errors, so the
metallib fix from 1.4.1 still holds on older runtimes.

### Fixed

- `Platform.isTvOS` now compiles in **debug** builds. It previously worked only
in profile/release: debug compiled against the stock Flutter SDK, which does
not declare the getter, so an app using the API the README recommends failed
to build with `Member not found: 'isTvOS'`. Present since the getter was
introduced — reproduced identically on 1.4.1 — and easy to miss because the
*values* (`operatingSystem`, `isIOS`) resolve at runtime from the device
engine in JIT and are correct in every mode; only the new member was missing
from the type checker's view.

Debug now compiles against the same patched `flutter_patched_sdk` as profile,
which the `host_debug_unopt` artifact already shipped. Verified on a tvOS 17.5
simulator (`isTvOS=true` in debug, `isAndroid`/`isMacOS` unaffected), AOT on a
physical Apple TV 4K is unchanged, and hot reload still works.

<!-- Contributors: add entries for user-visible changes here (see CONTRIBUTING.md).
Do not add a version heading or bump pubspec.yaml — maintainers assign
versions at release time. -->
Expand Down
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ A Flutter toolchain for building and running Flutter apps on **Apple TV (tvOS)**

## Current version

- flutter-tvos: `1.4.1`
- Flutter SDK: `3.44.6` (`ee80f08bbf97172ec030b8751ceab557177a34a6`)
- tvOS engine artifacts: `v1.0.1-flutter3.44.6` (origin-signed)
- flutter-tvos: `1.4.2`
- Flutter SDK: `3.44.7` (`84fc5cbb223bc12f83d65b647ff8a56caf779ffd`)
- tvOS engine artifacts: `v1.0.1-flutter3.44.7` (origin-signed)

## Installation

Expand Down
2 changes: 1 addition & 1 deletion bin/internal/engine.version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
v1.0.1-flutter3.44.6
v1.0.1-flutter3.44.7
2 changes: 1 addition & 1 deletion bin/internal/flutter.version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
ee80f08bbf97172ec030b8751ceab557177a34a6
84fc5cbb223bc12f83d65b647ff8a56caf779ffd
38 changes: 21 additions & 17 deletions lib/tvos_artifacts.dart
Original file line number Diff line number Diff line change
Expand Up @@ -53,24 +53,28 @@ class TvosArtifacts extends CachedArtifacts {
}
}

// For AOT (profile/release) builds, compile the app kernel against OUR
// patched `flutter_patched_sdk` (shipped inside the host engine artifact)
// rather than the stock Flutter checkout's. The patched dart:io
// `platform.dart` defines `isIOS = operatingSystem == "ios" || == "tvos"`
// and adds the `isTvOS` getter, so the un-folded platform-const getters
// evaluate correctly at runtime on tvOS. This is the companion to
// `TvosKernelSnapshot.build()`, which passes `targetOS: null` so those
// getters are not const-folded to "ios" at compile time.
// Compile the app kernel against OUR patched `flutter_patched_sdk`
// (shipped inside the host engine artifact) rather than the stock Flutter
// checkout's. The patched dart:io `platform.dart` defines
// `isIOS = operatingSystem == "ios" || == "tvos"` and adds the `isTvOS`
// getter, so the un-folded platform-const getters evaluate correctly at
// runtime on tvOS. This is the companion to `TvosKernelSnapshot.build()`,
// which passes `targetOS: null` so those getters are not const-folded to
// "ios" at compile time.
//
// Debug (JIT) deliberately keeps the stock SDK: platform identity there is
// resolved by the device engine's own (patched) core libraries at runtime,
// so the compile SDK is irrelevant and we avoid disturbing the proven
// debug path. We only need our patched SDK where gen_snapshot bakes the
// SDK code into the app snapshot — i.e. precompiled builds.
if ((mode?.isPrecompiled ?? false) &&
(artifact == Artifact.flutterPatchedSdkPath ||
artifact == Artifact.platformKernelDill)) {
final String patchedSdkDir = _hostPatchedSdkDirectory(mode!);
// This applies to debug as well, not just AOT. Platform identity *values*
// do resolve at runtime in JIT — dart:io comes from the device engine's
// own patched core libraries — so for `operatingSystem` and `isIOS` the
// compile SDK genuinely is irrelevant there. But `isTvOS` is a member the
// stock SDK does not declare at all, and the frontend server type-checks
// against the compile SDK before anything runs: an app touching
// `Platform.isTvOS` failed to build in debug with
// `Member not found: 'isTvOS'` while compiling fine in profile/release.
// Pointing debug at the same patched SDK (which `host_debug_unopt` already
// ships) makes the getter exist in every mode.
if (artifact == Artifact.flutterPatchedSdkPath ||
artifact == Artifact.platformKernelDill) {
final String patchedSdkDir = _hostPatchedSdkDirectory(mode ?? BuildMode.debug);
if (artifact == Artifact.platformKernelDill) {
return _fileSystem.path.join(patchedSdkDir, 'platform_strong.dill');
}
Expand Down
2 changes: 1 addition & 1 deletion pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name: flutter_tvos
description: Flutter CLI tool for building and running Flutter apps on Apple TV (tvOS). A custom embedder wrapping Flutter SDK with tvOS-specific build targets, device management, and plugin support.
version: 1.4.1
version: 1.4.2
homepage: https://fluttertv.dev
repository: https://github.com/fluttertv/flutter-tvos
publish_to: "none"
Expand Down
36 changes: 23 additions & 13 deletions test/general/tvos_artifacts_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -68,23 +68,33 @@ void main() {
);
});

test('debug flutterPatchedSdkPath falls through to stock resolution', () {
// Debug resolves platform identity at runtime via the device engine, so
// the override is intentionally NOT applied — the path must come from
// the stock CachedArtifacts logic, not our engine_artifacts host SDK.
final String path = artifacts.getArtifactPath(
Artifact.flutterPatchedSdkPath,
mode: BuildMode.debug,
test('debug also uses the patched SDK (host_debug_unopt)', () {
// Debug resolves platform identity *values* at runtime via the device
// engine, so for `operatingSystem` and `isIOS` the compile SDK is
// irrelevant. But `isTvOS` is a member the stock SDK does not declare,
// and the frontend server type-checks against the compile SDK before
// anything runs — so with stock resolution an app touching
// `Platform.isTvOS` failed to build in debug with
// `Member not found: 'isTvOS'` while compiling fine in profile/release.
// Debug uses the same non-product SDK as profile.
expect(
artifacts.getArtifactPath(Artifact.flutterPatchedSdkPath, mode: BuildMode.debug),
'/engine_artifacts/host_debug_unopt/flutter_patched_sdk',
);
expect(
artifacts.getArtifactPath(Artifact.platformKernelDill, mode: BuildMode.debug),
'/engine_artifacts/host_debug_unopt/flutter_patched_sdk/platform_strong.dill',
);
expect(path, isNot(contains('engine_artifacts')));
});

test('debug platformKernelDill falls through to stock resolution', () {
final String path = artifacts.getArtifactPath(
Artifact.platformKernelDill,
mode: BuildMode.debug,
test('a null mode resolves to the debug (non-product) SDK', () {
// getArtifactPath is reachable without a mode; it must not throw and
// must not silently pick the product SDK, which would drop entry-point
// classes the JIT engine looks up natively.
expect(
artifacts.getArtifactPath(Artifact.flutterPatchedSdkPath),
'/engine_artifacts/host_debug_unopt/flutter_patched_sdk',
);
expect(path, isNot(contains('engine_artifacts')));
});

test('handles the nested directory layout from zip extraction', () {
Expand Down
Loading