MapPackageDownloader
Class used for downloading property, download base map layer and map data for a property.
Native venuepackages DB serialization (#68).MapPackageManager is a native (JNI) object that owns an on-disk SQLite holding the venuepackages / map tables. Every method here that touches packageManager (or the static getMapTilesFilePath) reaches into that same native SQLite. The SDK drives it from several threads with no ordering guarantee: initialize() runs on the map setup thread and is the FIRST writer (its updateMapTiles(..) CREATEs the tables), while updatePackage(..) runs on filer-download callback threads (per-property tile downloads triggered from property selection), and reads (getPackage(..), getMapTilesFilePath()) fire from the UI/base-map thread.
When a read raced the first write, native SQLite saw an empty / half-created DB ("no such table: venuepackages: SQL logic error") and, worse, a native read against a DB whose page map was being swapped underneath it faulted with SIGBUS
(BUS_ADRALN) on a JNI pool thread (misaligned read of a racing pointer) during post-login map load. To make the SDK-driven access safe, ALL native package-manager calls below are serialized on mNativePackageLock: no read is ever issued concurrently with a write/create, and the table-creating first updateMapTiles completes before any getPackage observes the DB.
Residual engine-side requirement. This guard only serializes the calls the SDK makes. The core engine ALSO opens/reads the same venuepackages SQLite directly on its own JNI pool threads during post-login property load — outside this class and this lock. A complete fix requires the engine to (a) open the venuepackages DB with its schema asserted (run CREATE TABLE IF NOT EXISTS / migration before any query rather than failing "no such table"), and (b) hold an internal reader/writer lock inside MapPackageManager around the DB connection so a native read can never observe a connection whose page map is mid-swap. Until the engine does so, the SDK guard removes the SDK-triggered half of the race and avoids issuing a native read against an empty/half-written table.