fix: default the scanner to portrait orientation
Use Portrait when no valid orientation preference is saved; preserve all explicit user choices, including System default. Cover missing, invalid, explicit and platform orientation behavior in four focused tests. Focused tests, debug lint (zero errors/warnings) and debug assembly pass. A matching-signer in-place TC22 update preserved login/enrollment and Android reports the normal activity requested portrait. Record exact physical Code128 evidence and fully green prior native CI separately. Co-Authored-By: OpenAI Codex <noreply@openai.com> Signed-off-by: James Maes <james@kof22.com>
This commit is contained in:
1 parent
229fce30a1
commit
7de2b5088f
7 files changed
+62
-7
No files matched your search
+1
-1
@@ -1,6 +1,6 @@
|
||||
# Hosted scanner fixture
|
||||
|
||||
The source pins and complete Maven commands live in [Scanner Android](../.github/workflows/scanner.yml). The fixture uses core commit `ecf0f550a0357cec6387c2b54efca128a405a629` and scanner server commit `b14d925b741e815d1cfa4f62301f19207f25b03f`. The core includes the UI API 1.9 native authentication contract, credential log redaction, explicit JSON null handling, the Guava 33.7.2-jre security update, portable SPA filesystem paths, and automatically allocated spec-test ports. The scanner includes the canonical UTC H2 migration and the demo BOM import that aligns all transitive QQQ dependencies with the selected version.
|
||||
The source pins and complete Maven commands live in [Scanner Android](../.github/workflows/scanner.yml). The fixture uses core commit `ecf0f550a0357cec6387c2b54efca128a405a629` and scanner server commit `10416938724c9663d66f7848ff2b1a63fe635794`. The core includes the UI API 1.9 native authentication contract, credential log redaction, explicit JSON null handling, the Guava 33.7.2-jre security update, portable SPA filesystem paths, and automatically allocated spec-test ports. The scanner includes the canonical UTC H2 migration, the demo BOM import that aligns all transitive QQQ dependencies with the selected version, and the additive mobile-scanners1.2 capture-mode contract. The normal operator server remains a separately qualified runtime; a CI source pin does not replace it.
|
||||
|
||||
Each job creates a fresh Maven repository under the runner's temporary directory. Core is built as `4.1.0-ci.<full-core-SHA>`; the scanner and demo receive that exact version through `qqq.version`. This 49-character value retains the full commit identity and fits the core's 50-character help-bundle version limit. Nothing installs into the runner's shared Maven repository, substitutes a published artifact, or restores a cached QQQ snapshot. The scanner's own fixture snapshot is built from its checked source in that same fresh repository. This is an isolated CI source qualification, not publication of a production release or adoption by an operator server. The optional Record Files integration has its own dependency qualification.
|
||||
|
||||
|
||||
@@ -44,6 +44,6 @@ node scripts/ci/scanner-device-photo-e2e.mjs --serial TC22_SERIAL --fixture PRIV
|
||||
|
||||
This runner accepts only that loopback fixture's expected account/process/parent contract. It does not start, stop or delete the external fixture. Its test intercepts Android camera/picker activity results with a generated image, verifies automatic camera upload and retained server association/hash, then checks pending gallery-original retention across rotation and cleanup on administrator-forced logout. No surroundings are photographed.
|
||||
|
||||
Device Settings includes **Orientation**: System default, Portrait, Landscape, Reverse portrait and Reverse landscape. The choice is local to this installation and survives sign-out, server changes and restarts; it does not modify Android's global auto-rotate preference. Android can recreate the Activity when applying a choice. The host retains process ViewModels and saves unsubmitted manual scanner text across that recreation. Pending photo originals remain with the process's retained ViewModel.
|
||||
Device Settings includes **Orientation**: System default, Portrait, Landscape, Reverse portrait and Reverse landscape. **Portrait is the default** when no choice has been saved or the saved value is invalid. An existing explicit choice, including System default, is preserved. The choice is local to this installation and survives sign-out, server changes and restarts; it does not modify Android's global auto-rotate preference. Android can recreate the Activity when applying a choice. The host retains process ViewModels and saves unsubmitted manual scanner text across that recreation. Pending photo originals remain with the process's retained ViewModel.
|
||||
|
||||
The TC22 test target runs Android 14. Android's [requested-orientation API](https://developer.android.com/reference/android/app/Activity#setRequestedOrientation(int)) permits manufacturer overrides; for apps targeting API36 or later, Android16 [ignores orientation restrictions on displays whose smallest width is at least 600dp](https://developer.android.com/about/versions/16/behavior-changes-16#adaptive-layouts). The setting requests the platform policy and does not force transforms or work around those system restrictions.
|
||||
@@ -0,0 +1,28 @@
|
||||
# Physical TC22 acceptance — November 1, 2026
|
||||
|
||||
This records current development-package evidence, not production release acceptance. The normal application was updated in place after signer verification and private-data backup. The emulator remains off.
|
||||
|
||||
| Component | Exact tested checkpoint |
|
||||
| --- | --- |
|
||||
| Development APK SHA-256 | `F3AF638E34AA0B6FB44D789362BED2838202EDAF681DF775F2A5FAD3AB3E9FAA` |
|
||||
| Production source checkpoint | `e04fdb2d21d4f84253f12137af106bbcb0344a19` |
|
||||
| Backend core | `ecf0f550a0357cec6387c2b54efca128a405a629` |
|
||||
| Running scanner server | `b14d925b741e815d1cfa4f62301f19207f25b03f`, UI API1.9/mobile-scanners1.1 |
|
||||
|
||||
Direct display inspection confirmed sign-in, the Apps menu, Scan Capture and “Scanner ready.” The operator then reported “Saved scan.” A direct, ownership-guarded backend query verified eight new `QQQ-TEST-123456` records with `scanSource=zebra-emdk`, `symbology=CODE128`, TC22 model attribution and eight distinct event identities. Their device capture times run from `2026-11-01T11:02:17.572512Z` through `2026-11-01T11:02:40.208343Z`. Device capture and server receipt times are separate clock observations.
|
||||
|
||||
This proves a trusted hardware trigger-to-save positive control. The operator confirmed the captures came from multiple deliberate trigger pulls. Historical DataWedge records were excluded from this result. The normal database has eleven records at the observation, including its three preserved historical scans; no disposable instrumentation was run over this walkthrough.
|
||||
|
||||
| Required behavior | Current proof |
|
||||
| --- | --- |
|
||||
| Code128 trigger to durable scan | Verified on the current EMDK path, with operator Saved scan and matching backend records. |
|
||||
| Leading-zero QR `001234567890` | Current QR displayed; operator/backend confirmation pending. Historical DataWedge QR does not satisfy this gate. |
|
||||
| Separate repeated trigger intent | Eight distinct events observed; operator confirmed multiple deliberate pulls. |
|
||||
| Rotation/recreation, background/resume, scanner ownership restoration | Physical matrix pending; native synthetic/hosted evidence is separate. |
|
||||
| Connection failure, uncertain receipt/retry, leave/cancel and switching apps | Operator walkthrough pending; automated regressions remain separately scoped. |
|
||||
| Remote termination and fresh login | Final hosted verification and current operator checks pending. |
|
||||
| Actual projection, camera/gallery and GPS | Separate consent/provider/runtime gates; not implied by barcode capture. |
|
||||
|
||||
The reported disappearance before sign-in was inspected directly: the process remained alive/resumed/focused, the crash buffer was empty and the display showed connected sign-in. No app crash or product fix is established by that observation. The desktop mirror was black; direct local ADB screenshots provided the usable display evidence.
|
||||
|
||||
The later portrait-default update produced development APK `C89161C522AA7DFFE09C009ABDE769C1BADB7E6C64BFCE699857062A1CEC6340`. Four focused policy tests, debug lint (zero errors/warnings) and debug assembly pass. It was installed in place with a matching signer and another private-data backup. Direct Android inspection confirms the normal scanner Activity resumed with `SCREEN_ORIENTATION_PORTRAIT`; the display shows its signed-in Apps menu. Missing/invalid settings now default to portrait; explicit saved choices remain intact. The barcode observations above belong to the earlier exact APK, and current QR/lifecycle checks remain pending after this update.
|
||||
@@ -1,5 +1,17 @@
|
||||
# Session state
|
||||
|
||||
## November 1 portrait default installed; prior source fully green
|
||||
|
||||
The user requested portrait lock by default. Missing/invalid preferences now choose Portrait; all explicit saved choices remain available. Four focused policy tests, debug lint (zero errors/warnings) and debug assembly pass. Development APK C89161C…C6340 was installed in place after signer verification and a new private-data backup; no app data was cleared. Android reports the normal Activity resumed with SCREEN_ORIENTATION_PORTRAIT, and a direct screenshot confirms the signed-in Apps menu. Barcode/lifecycle acceptance of these new APK bytes remains pending; earlier F3AF physical evidence is preserved.
|
||||
|
||||
All eleven hosted checks at229fce3 passed, including both GitHub native runs (jobs124829276568/124828879619):35 shared cases, PixelCopy and all seven semantic scenarios. Logs show session-login-action-ready, session-fresh-login and the semantic request audit in both runs. Server documentation checkpoint2de8470 also passes all eight checks. Fresh checks will qualify the portrait-default source update. The operator confirmed the eight earlier Code128 events were deliberate trigger pulls. The QR was not visible in chat; a direct image link was supplied after unreliable browser automation, and current QR acceptance remains pending.
|
||||
|
||||
## November 1 physical EMDK positive control verified
|
||||
|
||||
The operator reported Saved scan on the normal F3AF development app. Direct ownership-guarded backend inspection verifies eight new Code128 records for QQQ-TEST-123456, source zebra-emdk, TC22 attribution and eight distinct event IDs. This closes the current trusted hardware positive-control gap for Code128 only. Operator confirmation of repeated trigger intent and the current leading-zero QR remain pending; [physical acceptance](PHYSICAL-TC22-ACCEPTANCE.md) records exact APK/runtime and remaining lifecycle/retry/ownership gates. No normal app/data clear or QA run occurred.
|
||||
|
||||
Strict Firefox profile-only CA trust now passes issuer/hostname checks using the supported PLAYWRIGHT_FIREFOX_POLICIES_JSON entry point. Windows trust is unchanged; the earlier Windows-root approval question is obsolete. Actual provider startup/exchange remains unexecuted while an independently reviewed known-listener guard is prepared for genuine TIME_WAIT rows. Independent architecture closure of Android229/server2de reports no additional concrete source blocker and maps A1-A11 controls/tests; runtime/deployment/dependency/signing limits remain. Record Files compatibility now has a concrete exact-revision filesystem dependency gate in a new private cache; no frozen0515/default/runtime adoption occurred.
|
||||
|
||||
## November 1 native CI — rotation passes, fresh-login test readiness under correction
|
||||
|
||||
Android5ba PR run41297344726 passed:35 shared native cases, PixelCopy and all seven semantic scenarios, including session-monitor. The duplicate push run41297340376 also passed rotation/recreation/mirroring/administrator termination, then timed out waiting for Username after clicking Log back in. Its request audit shows completed Android logout200 and no second Android manageSession. Static review confirms that the test awaited only the label, which also renders while the logout action is disabled. This supports a test-readiness race; the failure artifact does not record the button state at the click, so no production cause is asserted. The correction waits for a final signed-out message and enabled action, asserts enabled and clicks once; it retains all fresh-login/session assertions. The opt-in device-screen test uses the same readiness requirement. Fresh native execution remains required.
|
||||
|
||||
+5
-1
@@ -1,7 +1,11 @@
|
||||
# TODO
|
||||
|
||||
- [x] Verify current TC22 Code128 hardware trigger-to-save on the trusted EMDK path with operator Saved scan, matching backend source/model and distinct event identities; see [physical evidence](PHYSICAL-TC22-ACCEPTANCE.md).
|
||||
- [ ] Finish current EMDK leading-zero QR, repeat-intent, lifecycle/ownership and retry/leave acceptance; historical DataWedge scans do not qualify these checks.
|
||||
|
||||
- [x] Verify the synchronized rotation/recreation assertions in both5ba GitHub native runs; one entire run passed and the other reached a later fresh-login timeout.
|
||||
- [ ] Verify final fresh-login readiness in native CI: wait for the completed logout message and enabled button before clicking once. Both isolated test packages must compile; hosted execution is the acceptance gate.
|
||||
- [x] Verify final fresh-login readiness at229fce3 in both GitHub native runs:35 shared cases, PixelCopy and all seven semantic scenarios pass, including completed logout, enabled login action and a new session. All eleven hosted checks pass; the later portrait-default update requires its own fresh checks.
|
||||
- [x] Make portrait the default for missing/invalid preferences while preserving explicit choices; four focused tests, lint/debug assembly and preserving TC22 install pass, with actual requested portrait orientation confirmed.
|
||||
- [ ] Finish the operator walkthrough on the newly updated normal TC22 app; private data/enrollment and the development signing identity were preserved.
|
||||
- [x] Compile the opt-in screen-consent QA harness and ordinary E2E tests; verify early opt-in/protected-port safety gates. Actual permission/display acceptance remains open.
|
||||
- [x] Compile/review additive consent-based device-screen client and paired1.2 server:137 JVM, package/lint/APK inspection, ordinary-UID TC22 scan-input rejection,39 server/six demo/all15 browser cases and strict provenance pass. Actual projection acceptance remains separate.
|
||||
|
||||
@@ -26,7 +26,7 @@ enum class OrientationPolicy(val label: String, val requested: Int)
|
||||
|
||||
companion object
|
||||
{
|
||||
fun parse(value: String?) = entries.firstOrNull { it.name == value } ?: SYSTEM
|
||||
fun parse(value: String?) = entries.firstOrNull { it.name == value } ?: PORTRAIT
|
||||
fun read(context: Context) = parse(context.getSharedPreferences("host", Context.MODE_PRIVATE).getString("orientation", null))
|
||||
}
|
||||
|
||||
|
||||
@@ -7,10 +7,21 @@ import org.junit.Test
|
||||
|
||||
class OrientationPolicyTest
|
||||
{
|
||||
@Test fun missingOrUnknownSavedValuesKeepSystemBehavior()
|
||||
@Test fun missingSavedValueDefaultsToPortrait()
|
||||
{
|
||||
assertEquals(OrientationPolicy.SYSTEM, OrientationPolicy.parse(null))
|
||||
assertEquals(OrientationPolicy.SYSTEM, OrientationPolicy.parse("unknown"))
|
||||
assertEquals(OrientationPolicy.PORTRAIT, OrientationPolicy.parse(null))
|
||||
}
|
||||
|
||||
@Test fun unrecognizedSavedValuesDefaultToPortrait()
|
||||
{
|
||||
listOf("unknown", "", " ", "portrait").forEach { value ->
|
||||
assertEquals(OrientationPolicy.PORTRAIT, OrientationPolicy.parse(value))
|
||||
}
|
||||
}
|
||||
|
||||
@Test fun explicitSavedChoicesIncludingSystemArePreserved()
|
||||
{
|
||||
assertEquals(OrientationPolicy.SYSTEM, OrientationPolicy.parse("SYSTEM"))
|
||||
OrientationPolicy.entries.forEach { assertEquals(it, OrientationPolicy.parse(it.name)) }
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user