Repository navigation
feat(platform): treat HarmonyOS as a mobile target - #270
TiaraBasori wants to merge 15 commits into
Conversation
Automated PR reviewHead: Review unavailable: Malformed model finding; manual review required. Remaining gates
No PR code runs with the model key or write token. Free-only routing; provider/rate-limit failures never authorize a merge. Existing review findings must be resolved, not hidden by a new recommendation. |
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
iebb
left a comment
There was a problem hiding this comment.
Reviewed current head 7784f8c and its actual failing Quality evidence. This is a useful direction, but is not ready to merge.
-
[P1] Preserve UI target-platform behavior. isMobilePlatform reads Platform.operatingSystem, but VideoPlayerView previously gated its orientation control on defaultTargetPlatform. On the Linux-hosted iPhone widget test this now removes video-more-orientation: mobile_fullscreen_video_player_widget_test.dart:425 fails with zero matches. Evidence: https://github.com/iebb/mithka/actions/runs/39993012046 . Keep the UI platform boundary mockable/preserve its existing semantics while adding OHOS, and rerun that focused production-widget test plus the full suite. This is a hosted iPhone-layout test finding, not a claim about a physical iPhone.
-
Split mobile form factor from implemented native capabilities. AccountBackupService now becomes eligible on OHOS, but its isSupported probe directly calls mithka/account_backup; the submitted OHOS host registers generated plugins and contains no implementation of that custom channel. Gallery saving is also enabled while the dependency PR explicitly lacks photo_manager. Unsupported native operations must return a safe unsupported result rather than being advertised just because the OS is mobile. Cover missing channels, unavailable biometrics and denied permissions at the production boundary.
Please complete the repository PR template's Terms classification/basic checks and attach a successful credential-free build of the assembled OHOS target. The new pure OS-string mapping tests do not cover these affected UI/native entry points. Keeping this legitimate PR open.
8fa30d8 to
c345a45
Compare
Review finding iebb#2 on PR iebb#270: AccountBackupService became eligible on OHOS because isMobilePlatform now includes it, but its isSupported probe calls the mithka/account_backup channel the OHOS host never implements — and gallery saving was likewise advertised while photo_manager's channel is absent there. A mobile form factor says nothing about which native channels a host implements, so each capability now degrades to its own unsupported result at the production boundary instead of throwing MissingPluginException at call time: - AccountBackupService: the isSupported/isLocalStorageSupported probes catch MissingPluginException/PlatformException and report false; the login restore icon follows the answered capability (_canRestoreAccountBackup) instead of the form factor alone. - MediaLibrarySaver: save/savePreparedFile translate a missing photo_manager channel into MediaLibrarySaveResult.unsupported, the same answer a desktop host gets. - LocalAppLockController: a missing flutter_secure_storage port reads as no lock configured (nothing was ever persisted) instead of failing closed behind a gate no credential could open; a real storage error still fails closed. - CallScreen: native video views and the flip-camera affordance follow the engine capability (supportsMediaCalls, Android/iOS tgcalls) rather than the form factor, so a mobile host without the engine keeps the placeholder glyph. Behavior on Android/iOS/Windows/macOS/Linux is unchanged: the form factor and the capability still agree there, and the new branches only fire when the channel is absent.
|
Finding 2 addressed at head 22f7862 — the mobile form factor is now split from implemented native capability at every
Android/iOS/desktop behavior is byte-identical (form factor and capability agree there; the new branches never fire — pinned by the "keeps saving"/"still fails closed" tests). 15 new boundary cases across 4 suites, all green: The image ref note from mithka-tdjson#4 (the original container ref was |
Review finding iebb#2 on PR iebb#270: AccountBackupService became eligible on OHOS because isMobilePlatform now includes it, but its isSupported probe calls the mithka/account_backup channel the OHOS host never implements — and gallery saving was likewise advertised while photo_manager's channel is absent there. A mobile form factor says nothing about which native channels a host implements, so each capability now degrades to its own unsupported result at the production boundary instead of throwing MissingPluginException at call time: - AccountBackupService: the isSupported/isLocalStorageSupported probes catch MissingPluginException/PlatformException and report false; the login restore icon follows the answered capability (_canRestoreAccountBackup) instead of the form factor alone. - MediaLibrarySaver: save/savePreparedFile translate a missing photo_manager channel into MediaLibrarySaveResult.unsupported, the same answer a desktop host gets. - LocalAppLockController: a missing flutter_secure_storage port reads as no lock configured (nothing was ever persisted) instead of failing closed behind a gate no credential could open; a real storage error still fails closed. - CallScreen: native video views and the flip-camera affordance follow the engine capability (supportsMediaCalls, Android/iOS tgcalls) rather than the form factor, so a mobile host without the engine keeps the placeholder glyph. Behavior on Android/iOS/Windows/macOS/Linux is unchanged: the form factor and the capability still agree there, and the new branches only fire when the channel is absent.
22f7862 to
5d0aebd
Compare
Review finding iebb#2 on PR iebb#270: AccountBackupService became eligible on OHOS because isMobilePlatform now includes it, but its isSupported probe calls the mithka/account_backup channel the OHOS host never implements — and gallery saving was likewise advertised while photo_manager's channel is absent there. A mobile form factor says nothing about which native channels a host implements, so each capability now degrades to its own unsupported result at the production boundary instead of throwing MissingPluginException at call time: - AccountBackupService: the isSupported/isLocalStorageSupported probes catch MissingPluginException/PlatformException and report false; the login restore icon follows the answered capability (_canRestoreAccountBackup) instead of the form factor alone. - MediaLibrarySaver: save/savePreparedFile translate a missing photo_manager channel into MediaLibrarySaveResult.unsupported, the same answer a desktop host gets. - LocalAppLockController: a missing flutter_secure_storage port reads as no lock configured (nothing was ever persisted) instead of failing closed behind a gate no credential could open; a real storage error still fails closed. - CallScreen: native video views and the flip-camera affordance follow the engine capability (supportsMediaCalls, Android/iOS tgcalls) rather than the form factor, so a mobile host without the engine keeps the placeholder glyph. Behavior on Android/iOS/Windows/macOS/Linux is unchanged: the form factor and the capability still agree there, and the new branches only fire when the channel is absent.
5d0aebd to
9453c28
Compare
TiaraBasori
left a comment
There was a problem hiding this comment.
Finding 1 (preserving UI target-platform behavior) addressed at head 9453c28 — the same head announced for finding 2, via c345a45 + a7997d1 "let widget tests pin the mobile branch".
What changed. isMobilePlatform previously read only Platform.operatingSystem. On the Linux-hosted iPhone widget test this made mobile_fullscreen_video_player_widget_test.dart:425 match zero (the mobile-gated orientation action video-more-orientation was never offered). The helper now also returns true when debugDefaultTargetPlatformOverride is explicitly TargetPlatform.android/iOS; the override is null on real devices, so production still decides purely by operating system (ohos included).
Evidence (the failing evidence now passes).
- Focused hosted suite at this head, on the stock SDK (CI's 3.44.2 —
/tmp/flutter-3.44.2on the dev box):flutter test test/mobile_fullscreen_video_player_widget_test.dart→ 33/33 passed, including thevideo-more-orientationcase review cited. No change in app behavior on Android/iOS/desktop (form factor and capability agree there; the new branch never fires — pinned by the keeps-saving / still-fails-closed tests). - Full suite in Quality CI on this head: green (13m13s). Format
Formatted 11 files (0 changed), analyze no new issues (only the 12 pre-existingunawaited_return_in_try_blockalready on master).
Finding 2's capability split remains as described in the previous comment (9453c28 "split mobile form factor from native capability" + 41/41 boundary tests across four suites); production behavior is Android/iOS/desktop-identical.
iebb
left a comment
There was a problem hiding this comment.
Reviewed exact head 9453c285b591f54e15f18479defb288eaa983084. Changes requested before publication.
[P1] Preserve a known app lock when secure-storage capability disappears. In lib/security/local_app_lock_controller.dart:156–162,206–228, any MissingPluginException calls _resetForMissingSecureStorage(), clearing stored lock, locked state and storage-unavailable state. That catch includes reload of a known existing lock and successful credential read followed by failure reading the attempts channel—not just a first install on an unsupported host. This creates a source-derived fail-open path into previously protected UI.
Explicitly distinguish “unsupported capability on a never-configured install” from storage failure/known-lock reload. Preserve known protection and fail closed where state is uncertain. Add production-boundary regressions for existing-lock reload with missing storage and credential-read-success/attempts-read-failure; retain the safe unsupported-first-install behavior separately.
I withdraw the old blanket backup/gallery/missing-native-call crash concerns: the current capability probes, unsupported results and media-engine branches address those named paths with tests. The mandatory author template is now complete; do not interpret this review as still demanding missing author checkboxes. api_credentials_view.dart is ordinary reviewed UI with a generic device-label fallback, not an omitted credential file or protected automation path. No new Terms exception was identified.
The platform effort remains useful. Please supply accurate assembled-target build/capability evidence after the lock fix. This is a statically traced security risk, not a claim that a new device exploit or runtime crash was reproduced.
No approval is granted. Current-base merged-result Quality is not yet fresh in the reviewed evidence; before publication require fresh ordinary PR Quality on this exact head merged with live master, applicable platform checks, resolved findings and genuine exact-head owner approval. No incoming PR code was executed for this review.
|
Addressed the [P1] fail-open path at new head A known lock now fails closed when secure storage vanishes. The old catch treated every One ordering subtlety the regression forced out: the known-lock flag is recorded before the attempts read (that read is exactly where the plugin can vanish next), not after the whole happy path. Regressions (
Gates at this head with CI's toolchain ( The assembled OHOS build/capability evidence you asked for after the lock fix is the remaining platform item; this head carries no OHOS host change, so the existing host stack (PR #271/#272/#273) remains the place where that build lands. |
iebb
left a comment
There was a problem hiding this comment.
Re-reviewed exact head 744cb4de00e77aabbb056c4db9817776bb2d1896. The two new same-process regressions address the previously identified known-lock reload and credential-read/attempt-read failure paths; those improvements are acknowledged.
[P1] Fresh startup still assumes missing storage means no existing lock. In lib/security/local_app_lock_controller.dart, a newly created controller starts with _missingStorageKnownLock == false. If its first credential read throws MissingPluginException, initialization still calls _resetForMissingSecureStorage() and exposes the unlocked UI. An existing protected installation whose plugin disappears on a new launch takes the same branch as a never-configured unsupported host; neither new test covers this restart boundary. The secure read failing is not evidence that nothing was previously persisted.
Constrain the unsupported-host exception to a positively identified never-supported capability/installation, and keep ordinary supported hosts or uncertain previously protected state fail-closed. Add a fresh-controller/first-read-missing regression, alongside the two existing known-lock tests and a separately justified unsupported-first-install case. This is a static control-flow finding, not a claim of a reproduced device exploit. Do not add plaintext credential fallback.
Current-base Quality and assembled OHOS capability/build/startup evidence are still required before merging this platform change. Keep this legitimate improvement open for revision.
Review finding iebb#2 on PR iebb#270: AccountBackupService became eligible on OHOS because isMobilePlatform now includes it, but its isSupported probe calls the mithka/account_backup channel the OHOS host never implements — and gallery saving was likewise advertised while photo_manager's channel is absent there. A mobile form factor says nothing about which native channels a host implements, so each capability now degrades to its own unsupported result at the production boundary instead of throwing MissingPluginException at call time: - AccountBackupService: the isSupported/isLocalStorageSupported probes catch MissingPluginException/PlatformException and report false; the login restore icon follows the answered capability (_canRestoreAccountBackup) instead of the form factor alone. - MediaLibrarySaver: save/savePreparedFile translate a missing photo_manager channel into MediaLibrarySaveResult.unsupported, the same answer a desktop host gets. - LocalAppLockController: a missing flutter_secure_storage port reads as no lock configured (nothing was ever persisted) instead of failing closed behind a gate no credential could open; a real storage error still fails closed. - CallScreen: native video views and the flip-camera affordance follow the engine capability (supportsMediaCalls, Android/iOS tgcalls) rather than the form factor, so a mobile host without the engine keeps the placeholder glyph. Behavior on Android/iOS/Windows/macOS/Linux is unchanged: the form factor and the capability still agree there, and the new branches only fire when the channel is absent.
744cb4d to
1302841
Compare
|
Rebased onto current master |
|
Maintainer policy update: one feature/fix must have one canonical open PR per repository. Please consolidate the HarmonyOS platform, host, dependency and build work from #270, #271, #272 and #273 into this existing PR (#270), preserving the intended changes, review findings and validation evidence. Update this PR for subsequent fixes/tests/docs/CI; do not open another replacement or stacked PR for the same feature. The native producer iebb/mithka-tdjson#4 remains its own repository's PR. Close the superseded Mithka PRs only after their work and outstanding findings are preserved in the canonical diff. Current read-only review against master The previously requested assembled-target evidence is still necessary. I rechecked the exact pinned TDJSON OHOS release tag used by #271/#273; GitHub still returns 404. Consolidation does not approve the outstanding loader, build-status, capability and immutable-source/publication findings. Require the real pinned artifact and a credential-free, read-only Actions build/startup of the combined source before merge. No incoming code ran locally and no release workflow was dispatched. |
isMobilePlatform read only Platform.operatingSystem, so widget tests that simulate Android or iOS through debugDefaultTargetPlatformOverride kept seeing the desktop host and lost every mobile-gated surface: the fullscreen orientation action and the backgrounded-playback controller lifecycle. Count an explicit Android/iOS override as mobile as well. The override is null on real devices and profiles, so production still decides purely by operating system (ohos included).
Review finding iebb#2 on PR iebb#270: AccountBackupService became eligible on OHOS because isMobilePlatform now includes it, but its isSupported probe calls the mithka/account_backup channel the OHOS host never implements — and gallery saving was likewise advertised while photo_manager's channel is absent there. A mobile form factor says nothing about which native channels a host implements, so each capability now degrades to its own unsupported result at the production boundary instead of throwing MissingPluginException at call time: - AccountBackupService: the isSupported/isLocalStorageSupported probes catch MissingPluginException/PlatformException and report false; the login restore icon follows the answered capability (_canRestoreAccountBackup) instead of the form factor alone. - MediaLibrarySaver: save/savePreparedFile translate a missing photo_manager channel into MediaLibrarySaveResult.unsupported, the same answer a desktop host gets. - LocalAppLockController: a missing flutter_secure_storage port reads as no lock configured (nothing was ever persisted) instead of failing closed behind a gate no credential could open; a real storage error still fails closed. - CallScreen: native video views and the flip-camera affordance follow the engine capability (supportsMediaCalls, Android/iOS tgcalls) rather than the form factor, so a mobile host without the engine keeps the placeholder glyph. Behavior on Android/iOS/Windows/macOS/Linux is unchanged: the form factor and the capability still agree there, and the new branches only fire when the channel is absent.
The app-lock controller treated every MissingPluginException as the unsupported-first-install case, resetting the stored lock, the locked state and the storage-unavailable flag. That catch also covers reloading a known existing lock and a credential read that succeeds before the attempts read fails, so a mobile host losing its secure-storage plugin mid-session silently disabled existing protection — a fail-open into previously protected UI. The reset now happens only when no lock is known (nothing ever persisted, the HarmonyOS first-install case). A known lock — read this pass or established by an earlier one — fails closed instead, in both initialize and reloadFromStorage. Regressions: a known lock that loses secure storage mid-read fails closed (credential record reads, attempts read throws) and reloading a known lock against a vanished implementation fails closed (initialize on a working store, plugin gone before the desktop-sync reload). Both fail on the previous head; the safe first-install case stays green.
Make the HarmonyOS host a verifiable runnable target: the manifest now carries tdjson-ohos-arm64.zip with archive+member SHA-256/size and a per-asset release_tag pointing at the immutable tdjson#4 secondary release tdjson-ohos-1.8.68-c15d3f5a5de6-mithka-2e7f8ff14657-build-f6b13ce5aa13-v2 so scripts/build-hap.sh can install arm64-v8a/libtdjson.so into ohos/entry/libs/arm64-v8a/ via the same pinned schema-v2 manifest contract the release CI uses. The installer validates sha256/size, checks that the zipped member matches the pinned digest, and downloads from the per-asset release when the manifest carries one; HAP verification can then byte-compare libs/arm64-v8a/libtdjson.so against the same pinned entry. Align ohos/README.md with the release job's validated SDK combination (API 26 raw SDK or pinned API 22+patched embedding HAR) and document the controlled embedding patch boundary. Addresses PR iebb#271 review findings: pinned OHOS entry, consumer/producer manifest contract, environment-contract coherence, and build-hap verifiability.
The entry module only declared the home entity/action, so no link could ever target the ability and app_links had nothing to deliver. The entry ability now also declares browsable entity + viewData action with the tg scheme and the https t.me host — the same pair the Android manifest declares — for both cold launch and warm-delivery routing through the account-aware link path.
Add OpenHarmony ports of the federated plugins mithka consumes, so the OHOS Flutter fork can resolve a native implementation when building for HarmonyOS while stock flutter_tools ignores the ohos platform entries (verified: pub get, analyze, and `flutter build apk --config-only` stay green and no plugin registrant changes on android/linux/ios). Regular dependencies (8, Dart-3 compatible on pub.dev): - shared_preferences_ohos 2.2.0 (implements shared_preferences) - path_provider_ohos 2.2.1 (implements path_provider) - url_launcher_ohos 6.3.0 (implements url_launcher) - open_filex_ohos 4.7.0 (implements open_filex) - local_auth_ohos 1.0.0 (implements local_auth) - webview_flutter_ohos 3.15.0 (implements webview_flutter) - sensors_plus_ohos 0.1.2 (companion; serves sensors_plus channels) - app_links_ohos 0.2.0 (companion for app_links) Overlay-only (4; every published version pins sdk <3.0.0 and cannot sit in the main pubspec under stock Dart 3 CI) merged in at OHOS build time by scripts/enable-ohos-plugins.sh from pubspec_overrides.ohos.yaml: - package_info_plus_ohos 0.0.7, permission_handler_ohos 0.0.8, file_picker_ohos 1.0.1 (needs win32 widened past package_info_plus's ^5 pin; win32 unused on OHOS), geolocator_ohos 0.0.3. Verified: overlay pub get + analyze green, host lock pins unchanged. Still missing on HarmonyOS (no compatible pub.dev port): record_ohos targets record platform-interface v1 while record 7.x needs v2; flutter_secure_storage_ohos has the same v1/v2 split; camera, mobile_scanner, flutter_sound, photo_manager and flutter_local_notifications have no ohos port at all. Voice notes, secure storage, camera/QR, photo picking and local notifications are unavailable on OHOS until ports catch up. pubspec.lock gains exactly the 8 new entries (repo convention: lock is committed with dependency changes).
PR iebb#272 review finding [P1]: apply could discard unrelated work. A second apply overwrote the only backup of the pre-overlay original with the already-overlaid file, so apply/apply/revert could no longer restore the starting content. pubspec.lock was not backed up even though pub get rewrites it, and apply edited tracked .gitignore at runtime. revert without a backup ran git checkout on pubspec.yaml, losing edits the user had made but not yet committed. The operation now refuses unsafe states instead of repairing them by resetting files. apply backs up both pubspec.yaml and pubspec.lock and refuses when an overlay is already active or when the backup would be overwritten; revert refuses when no apply is active and restores both locked files byte-for-byte. No tracked file besides the committed .gitignore entry is edited. Eight offline behavioral tests (apply, repeated apply, revert without a backup, dirty-file preservation, apply/resolve/revert lockfile rewriting, stale-backup refusal, no runtime edit of .gitignore) each include the exact mutation that fails it.
…evert Two restoration defects in the overlay helper: a tree that had no pubspec.lock before apply kept the lock the overlay's pub get created (revert now removes it — the backup's absence records the original absence), and the YAML backup round-tripped through text mode, folding CRLF to LF (the backup now copies the file byte-for-byte, so a dirty CRLF pubspec restores byte-identically). Regressions: apply/resolve/revert from a lockless tree restores lock absence and a dirty CRLF pubspec restores byte-identically, both red on the previous head.
Add a build-ohos job to the release workflow. It runs in the niuhuan harmony-next-flutter-pipeline container (HarmonyOS SDK API 22, hvigor/ohpm/node18), installs the 3.44.9+ohos-0.0.1-canary1 Flutter fork at /opt/flutter-ohos (cached), and patches the engine embedding HAR so its ArkTS compiles against API 22: autoFillManager API-26 types are replaced by local aliases, duplicate unfocus XComponent ids are made unique, and CompetitionStrategy.DEFAULT is spelled as its raw value. The patched har is repacked with the package/ member prefix ohpm requires. The job tolerates the not-yet-merged sibling ohos PRs: it runs scripts/enable-ohos-plugins.sh and installs the pinned tdjson-ohos-arm64.zip only when present (warning otherwise), and generates the ohos host via flutter create --platforms ohos when the repository has no ohos/ directory yet. flutter build hap exits non-zero without signing configs after hvigor produced the unsigned hap, so the build step warns and the verify step gates on the artifact: the hap must exist, unzip, and contain pack.info and ets/modules.abc. The release job now depends on build-ohos, requires exactly one mithka-*-ohos-arm64.hap asset, and cleans .hap assets when re-publishing.
Address PR iebb#273 review findings: 1. Never publish a hap without TDLib. The pinned manifest now carries tdjson-ohos-arm64.zip (archive+member SHA-256/size plus a per-asset release_tag pointing at the immutable tdjson#4 secondary release), the installer treats it as required, and the install step re-hashes the installed ohos/entry/libs/arm64-v8a/libtdjson.so against that entry. The hap verification now requires libs/arm64-v8a/libtdjson.so inside the hap, compares its packaged bytes to the installed pinned bytes, checks the arm64 ELF identity, and asserts the td_json_client_* entry points the Dart loader resolves are present. pack.info/ets/modules.abc alone no longer pass the gate. 2. Only a specifically verified signing failure is tolerated. The build step captures the flutter log, and a nonzero exit only continues when the unsigned hap exists and the log names a signing cause; compiler, resource, dependency, or packaging failures fail the job. 3. scripts/enable-ohos-plugins.sh is invoked with its mandatory apply argument so the combined stack with iebb#272 no longer exits 2. 4. The engine embedding HAR patch is an explicitly reviewed capability fallback: it refuses to apply unless the engine still guards autofill below sdkApiVersion 26, so requestAutoFill/requestAutoSave stubs can never change behaviour on API 26+ runtimes without failing the build. Installer tests cover the required ohos asset, a manifest missing it, and the per-asset release tag override.
Four release-workflow hardenings for the OHOS pipeline: - Credential boundary: the build-ohos container job drops to contents:read, checks out with persist-credentials:false, and the third-party pipeline image is pinned by digest (sha256:2ec15faf…e2a9) instead of the mutable latest tag; publication credentials remain exclusive to the release job. - Status capture: the hap build step runs under bash and captures the pipeline status explicitly (set -uo pipefail with || status=0), so the signing-only tolerance can actually see a non-zero exit instead of errexit killing the script first; the release job no longer hard-depends on build-ohos while the assembled path is being validated. - Loader gate: the hap verifier parses the packaged ELF's .dynsym and requires the five td_json_client entry points as DEFINED STT_FUNC globals — a byte substring could match a string-table mention the loader never resolves. Extracted to scripts/verify_ohos_hap_payload.py with offline tests against a committed aarch64 stub ELF built by the NDK clang (defines exactly the five entry points; digest mismatch also proven to fail). - Autofill shim: the API 22 stub now fails loudly (hilog error before the failure callback) so a >= 26 runtime surfaces the lost capability instead of silently degrading, with the hilog import ensured.
The Dart client (lib/tdlib/td_bindings.dart) binds td_create_client_id, td_send, td_receive and td_execute; the gate previously required only the five legacy td_json_client_* aliases, so a stub library the client cannot actually load would pass. Require the four modern exports instead and add a legacy-only stub fixture that fails the gate; both fixtures are regenerable via scripts/gen-libtdjson-stub-fixtures.py.
Master removed test/call_screen_test.dart and duplicated a manifest key in tdjson_artifact_installer_test; keep the missing-capability call regression as a focused suite (call_screen_capability_test.dart) and drop the duplicate key. All consolidated suites pass on the merged tree.
1302841 to
7a15a8f
Compare
|
Consolidated per the maintainer's one-canonical-PR policy (2026-10-29): #270 now carries the platform, host (#271), dependency (#272) and release-CI (#273) work as one stack of 15 clean commits rebased on current master Also addressed from the 2026-10-29 review notes:
Verification on the consolidated head
Still open and unchanged in status: the pinned |
Change
Adds HarmonyOS (NEXT) as a mobile platform target.
The ohos Flutter fork (openharmony-sig/flutter_flutter 3.44.9+ohos, same Dart 3.12.2 lineage as this repo's CI pin) reports
Platform.operatingSystem == 'ohos'. The stock SDK'sTargetPlatformhas no such value, so the detection uses the operating-system string instead of aTargetPlatform.ohosliteral — stock CI keeps compiling.lib/platform/ohos_support.dart:isOhos/isMobilePlatformhelpers, pure mapping covered by VM tests. A widget test that simulates Android/iOS throughdebugDefaultTargetPlatformOverridestill counts as mobile (the override is null on real devices, so production decides purely by OS).td_bindings.dart: on ohos,DynamicLibrary.open('libtdjson.so')resolves by soname from the hap'slibs/arm64-v8a, same as Android jniLibs.Platform.isAndroid || Platform.isIOS) converge onisMobilePlatform(immersive status bar, orientation, app-lock biometrics, backup consent).MissingPluginExceptionat call time.AccountBackupService.isSupported/ probes catchMissingPluginException/PlatformExceptionand report unsupported; the login restore icon follows the answered capability (_canRestoreAccountBackup).MediaLibrarySaver: a missingphoto_managerport returns the sameunsupportedresult desktop gets (a real ohos port lights it up without a code change); the distinctpermissionDeniedpath is preserved.local_app_lock_controller.dart: a missing secure-storage port degrades to "no lock configured"; a realPlatformExceptionstill fails closed; a missinglocal_authport reports biometrics unavailable.manager.supportsMediaCalls(engine capability), not the form factor.api_credentials_view.dart/app_icon_controller.dart: exhaustive switches get a_catch-all for the fork's extra enum value.Related issues: none. Companion PRs: #271 (host project), #272 (dependencies), #273 (release CI). TDLib cross-build: TiaraBasori/mithka-tdjson#4.
Telegram API Terms classification
allowTelegramTosViolations(I_DONT_FUCKING_CARE_ABOUT_TOS), disabled in official builds, and available only in an explicitly enabled self-build.Reason and affected Telegram behavior: platform plumbing only — OS detection, dynamic-library loading, status-bar/orientation handling, and capability degradation for unimplemented native channels. No Telegram API behavior, no new TDLib calls, no content policy or service destination changes. Form-factor and capability logic are Android/iOS/desktop-identical (pinned by the keeps-saving / still-fails-closed tests).
Basic checks (every PR)
dart format --set-exit-if-changedover the 11 touched lib files — 0 changed.flutter analyzeat head9453c285— no new issues (only the 12 pre-existingunawaited_return_in_try_blockwarnings already on master).flutter test --concurrency=4.Commands, results, platform/build/UI evidence, and reasons for inapplicable checks:
At head
9453c285, run serially on the PR worktree (4G box, one compile at a time):flutter test test/mobile_fullscreen_video_player_widget_test.dart— 33/33 passed (the suite review found failing on the first head, includingvideo-more-orientationat :425; the explicit-override fix restores it).flutter test test/account_backup_consent_test.dart test/call_screen_test.dart test/local_app_lock_controller_test.dart test/media_library_saver_test.dart— 41/41 passed (15 new boundary cases across the four suites; missing-channel, denied-permission, missing-biometrics and answering-implementation paths).flutter test test/ohos_support_test.dart test/local_app_lock_controller_test.dart— 14/14 passed.flutter testruns in Quality CI on this head (link in checks), including the three l10n gates.translations/tools/check.pyuntouched, no visible literals introduced.Analyze and testgreen); the assembled ohos target builds in feat(ohos): add the HarmonyOS host project #271/feat(deps): federated HarmonyOS plugin implementations #272/feat(ci): build the HarmonyOS hap in the release pipeline #273 (credential-free, no local ohos toolchain on the dev box).Section 1.4 exception checks
Not applicable.