AOSP hard-errors if BOARD_SYSTEM_EXTIMAGE_PARTITION_SIZE and
BOARD_SYSTEM_EXTIMAGE_PARTITION_RESERVED_SIZE are both defined once
PRODUCT_USE_DYNAMIC_PARTITION_SIZE is on (build/make/core/config.mk) --
this partition already had both set, harmless before dynamic sizing was
enabled product-wide for the vendor.img fix, a hard build error now.
Drops the fixed size, keeping dynamic sizing + the existing 100M reserve.
A fixed BOARD_VENDORIMAGE_PARTITION_SIZE forces vendor.img to always equal
that value exactly -- build_image.py never shrinks a fixed-size ext4 image
to its real content in this AOSP branch. Combined with
BOARD_USES_FULL_RECOVERY_IMAGE folding recovery.img into the same
assert-max-image-size check, "vendor.img + recovery.img <= ceiling" was
unsatisfiable at any fixed value (X + 128M <= X has no solution) --
confirmed by PAWLET_BUILD_RECOVERY=1 pdist failing with vendor.img already
at exactly the old 2304M ceiling. Switches to dynamic sizing
(PRODUCT_USE_DYNAMIC_PARTITION_SIZE, common.mk) with a 192M reserved size
(128M recovery.img + 64M slack) instead. mkimg.sh's fixed VENDOR_SIZE stays
valid as the physical partition ceiling -- ext4 doesn't need to fill its
containing partition.
Still M0 placeholder (starts, logs, idles) — no device-access code yet, so
nothing to deny. Also fixes rpi5's copy missing coredomain, which its own
sibling file's comment (rpi4) says is required since the exec type is
system_file_type.
shrink_ext4_image's returned byte size wasn't MB-aligned (ext4 block size
is 4096 bytes, not 1048576), but the GPT partition sizing later does
SIZE / 1048576 with integer division -- truncating down, making the
partition up to ~1MB smaller than the actual shrunk file being dd'd into
it. Confirmed on real hardware: dd failed with "No space left on device"
on system/system_ext/vendor despite --slim's own reported sizes matching
what got written to the GPT table. Round up to the next MB boundary
before truncating so the later division is always exact.
With BOARD_USES_FULL_RECOVERY_IMAGE := true, AOSP's assert-max-image-size
checks vendor.img + recovery.img together against
BOARD_VENDORIMAGE_PARTITION_SIZE. vendor.img builds to its full declared
size (confirmed: 2.0G on disk, not shrunk), and recovery.img is always a
fixed 128M FAT container (mkbootimg.mk), so the old 2GB ceiling overflowed
by exactly 128M whenever recovery was built alongside vendor. Bumped to
2.25GB (2048M vendor budget + 256M headroom) and updated mkimg.sh's
VENDOR_SIZE to match, since it's a separate hardcoded constant that has to
stay in sync with BoardConfig.mk's partition size.
losetup -d was unconditionally called after kpartx -dv, which already
detaches the loop device itself once the last partition mapping is removed
-- always failed with "No such device or address" but was otherwise
harmless. Now only detaches if still attached.
--slim shrinks system/system_ext/vendor to their actual used size (e2fsck
-f + resize2fs -M + truncate) instead of the fixed 8GB/4GB/2GB
BoardConfig.mk partition sizes, before sizing the GPT partitions and
writing the image. userdata/metadata stay fixed-size for now -- growing
userdata to fill the real target device is a separate, deferred piece of
work (first-boot on-device growth, not something buildable at
image-creation time since the real device size isn't known yet).
Its exec file is system_file_type (installs to /system/bin), but the domain
itself was never classified coredomain -- Treble's vendor-vs-system
neverallow rules then treat it as a vendor domain executing/entering a
system file. Classifying it coredomain matches where the binary actually
lives.
- device.mk: guard the Widevine CDM PRODUCT_COPY_FILES entry with
$(wildcard ...) so a checkout that hasn't run extract-widevine.sh still
builds (the HAL dlopen()s it at runtime and degrades gracefully already).
- ramdisk/init.rpi4.rc: restore the ${ro.hardware} mount_all generalization
(matches pawlet_rpi5, which already had it — this device tree's copy was
lost when an earlier android-16.0 upstream-sync merge got reset away).
Commented out (not removed) across pawlet_rpi4.mk, pawlet_rpi4_phone.mk,
and pawlet_rpi4_tablet.mk. Default AOSP launcher (pulled in by
full_base.mk) is used in the meantime.
adb remount and adb disable-verity require ro.boot.verifiedbootstate
to equal "orange" (bootloader unlocked), otherwise fs_mgr_remount
refuses with "Device must be bootloader unlocked" even on userdebug
builds. This board has no real bootloader/AVB enforcement
(TARGET_NO_BOOTLOADER := true), so the property was never set and
adb remount always failed.
Same fix as applied upstream for hikey/hikey960:
https://android.googlesource.com/device/linaro/hikey/+/fa66979a87e53d92dc717fd524f7958af20eb9f3
Tested on real Raspberry Pi 4 hardware: after this change,
ro.boot.verifiedbootstate=orange is reported and
"adb root && adb remount" succeeds (remounts / and /vendor as RW).
* config_voice_capable is not overridden here as car build target needs the
DIALER role to be available and com.android.car.dialer gets its runtime
phone permissions auto-granted for Bluetooth HFP calling.
M0 scaffold wiring for app_PawletAndroidAuto (native daemon + app) and the
Widevine L3 HAL: product packages, file_contexts, and a permissive
domain for pawlet.androidauto-daemon.
- mkbootimg.mk: boot.img uses the normal ramdisk again; the recovery.img rule
is guarded so it only builds when recovery is enabled (PAWLET_BUILD_RECOVERY=1)
and carries the recovery ramdisk.
- config.txt [tryboot] back to boot_partition=2 (A/B trial); recovery enters
via reboot,3.
- vendor.prop reboot reason back to reboot,tryboot.
- drop the no-op reserved-size lines (AOSP ignores RESERVED_SIZE for fixed
non-dynamic partitions).
- mkbootimg.mk: rm -rf the rpiboot staging dir at the start of the stamp rule
and strip any cmdline*.txt before assembling the images. A stale cmdline.txt
left in staging by the previous recipe got bulk-copied into the FAT, so the
per-image `mcopy ... ::cmdline.txt` then blocked forever on mtools'
interactive overwrite prompt ("stuck on boot.img/recovery.img").
- BoardConfig.mk: add BOARD_SYSTEMIMAGE_PARTITION_RESERVED_SIZE (100MB) so
system.img is sized to content + reserve instead of padded to the full 8GB
(matches system_ext / vendor); clears the "approaching size limit" warning.
Recovery lives in the boot partition WITHOUT BOARD_USES_RECOVERY_AS_BOOT —
that flag makes AOSP claim the boot.img rule (Makefile:2840, no custom-bootimg
guard) and collide with the custom FAT mkbootimg.mk. Instead:
- BOARD_USES_FULL_RECOVERY_IMAGE=true, TARGET_NO_RECOVERY=false so the recovery
ramdisk builds (BOARD_USES_RECOVERY_AS_BOOT stays false, from
BoardConfigPawlet.mk).
- mkbootimg.mk stages ramdisk-recovery.img into the boot FAT as ramdisk.img and
writes two cmdlines: cmdline.txt with androidboot.force_normal_boot=1
(first-stage init boots Android) and cmdline_recovery.txt without it.
config.txt [tryboot] selects cmdline_recovery.txt, so `reboot tryboot` from
pawlet-recoveryboot.sh brings the same partition up in recovery.
- mkbootimg.mk also builds a standalone recovery.img (satisfies
INSTALLED_RECOVERYIMAGE_TARGET; a fallback, not flashed by default).
- A/B slot switching uses a one-shot `reboot,2` (vendor.prop reboot_reason),
freeing tryboot for recovery.
Also size vendor.img to content + 100MB reserved (matching system_ext) so
vendor.img plus the recovery.img added to its size assertion fit under 2GB.
device.mk: move core_64_bit_only / dalvik-heap inherits ahead of the ADB block.
Firmware behaviors to verify on first flash: [tryboot] cmdline selection and
the reboot,2 partition boot.
private/domain.te neverallows misc_block_device access for all but a few
domains, and the check always compiles as a user build, so the custom
domain failed the sepolicy_neverallows gate. hal_bootctl_server (the other
exempt candidate) is out: hal_neverallows.te forbids HAL domains from
exec'ing vendor sh/toybox, and the chain-loader is a shell script. So use
AOSP's vendor_misc_writer — the domain built for vendor tools touching
misc — adding BCB read-back, vendor shell/toybox exec, the /metadata
attempt counter, sys.powerctl, and kmsg logging on top of the write
access system policy already grants.
Recovery support in two pieces that were always meant to fit together:
build/make stages recovery/root and produces ramdisk-recovery.img
itself, and skips its own mkbootimg-based recovery.img rule whenever
BOARD_CUSTOM_BOOTIMG_MK is set — expecting the custom mk to provide it.
mkbootimg.mk now does: same firmware/kernel/DTB payload as boot.img,
config.txt sed'd to load ramdisk-recovery.img, packed into a 128M FAT32
that wrimg.sh dd's to partition 3. Firmware boots it via autoboot.txt
boot_partition=3 (runtime reboot-to-recovery switcher: follow-up).
BoardConfig: recovery re-enabled with the STOCK AOSP recovery UI —
TARGET_RECOVERY_UI_LIB stays commented until the TWRP GUI port links
(libaosprecovery gap). BOARD_USES_FULL_RECOVERY_IMAGE=true disables the
legacy boot->recovery imgdiff path (recovery-resource.dat) that failed
the previous full build. TARGET_RECOVERY_PIXEL_FORMAT must be unquoted:
literal quotes leak into soong.*.extra.variables and break its JSON.
The old PRODUCT_COPY_FILES recovery/root line is dropped — product vars
in board makefiles are never collected; the TWRP helper files it aimed
at return via device.mk in Phase 2.
Verified: m recoveryimage produces recovery.img (FAT: kernel, DTBs,
overlays, ramdisk-recovery.img, correct initramfs line).
Enabling it (a116945) breaks every full build: RPi has no
INSTALLED_KERNEL_TARGET so build/make never emits a recovery.img rule,
but with BUILDING_RECOVERY_IMAGE on, vendor installs
recovery-resource.dat which depends on recovery.img -> ninja 'missing
and no known rule'. librecovery_ui_pawlet_twrp also still cannot link
(libaosprecovery unported). Block kept, commented, with both blockers
documented.
The RRO that points config_recentsComponentName at app.lawnchair has
existed in prebuilt_lawnchair all along but was never in
PRODUCT_PACKAGES — so the framework kept recents on the stock Launcher3
component (which the Lawnchair prebuilt overrides away), Lawnchair
disabled its quickstep half, SystemUI had no TouchInteractionService to
bind, and no taskbar/nav buttons ever rendered. Verified on device: with
the overlay pushed manually, SystemUI binds TIS.
Old block inherited a full TWRP recovery.mk fork and was disabled
pending Android 16 TWRP support. Current design keeps stock
bootable/recovery unforked and points TARGET_RECOVERY_UI_LIB at
librecovery_ui_pawlet_twrp (vendor/pawlet/recovery_ui), which
recovery_main.cpp dlopen()s at runtime. Not build-tested yet —
libaosprecovery (vendor/pawlet/recovery_toolkit/helpers) has no
Android.bp yet, so this module won't link until that's ported.
start console (was incorrectly stop) so the UART shell is interactive.
Add logcat_uart service writing to /dev/ttyS0 so Java crashes are
visible on the serial console.
AndroidRpiOverlay, AndroidTvRpiOverlay, BluetoothRpiOverlay,
CarServiceRpiOverlay, SettingsRpiOverlay, and SystemUIRpiOverlay have
moved to device/pawlet/rpi (pawlet_rpi_common). Module names are
unchanged so no PRODUCT_PACKAGES edits are needed.
On RPi 4/CM4 the density override (wm density 160) makes smallestScreenWidthDp
exceed 600 dp, which causes NavigationBarControllerImpl to route navigation
through TaskbarDelegate instead of creating a traditional NavigationBar window.
Lawnchair's Taskbar is not active, so no navigation buttons are shown at all.
Setting config_taskbarEnabled=false in the SystemUI overlay (backed by the
sysui-taskbar-navfix.patch in vendor/pawlet) makes supportsTaskbar() return
false, falling back to the traditional 3-button navigation bar.
On Android 16, config_isDesktopModeSupported=true on a large screen
triggers desktop windowing mode, which skips navigation bar creation
entirely (expecting the taskbar to handle it). With config_enableTaskbar
also false, the result is no navigation at all.
Disabling desktop mode restores the standard nav bar. Freeform windows
remain available via developer options without this flag.
Switch all build variants to inherit vendor/pawlet/config/default-vendor-config.mk
for the common vendor.cfg. Per-device vendor.cfg copy is wired up and commented
out, ready to activate when device-specific config is needed.
Update configs/provisioner/vendor.cfg to new ConfigProvisioner key names
(enable_configapk_service, device_provisioned, enable_setupwizard) and
point config_apk_url to https://oxmc.me/aosp_apis/data/default-config.apk.