Summary
This contribution adds one module, samsungSmartSwitch.py, with eight artifacts for Samsung Smart Switch (com.sec.android.easyMover): transfer sessions, transferred data categories, the other device's app and category list, its accounts, its message and contact counts, the transferred history list, and the backup media index. It produces one set of rows per Android user and reads the duplicate storage views of one file once.
On four Android 16 images the numbers were uneven: 2, 0, 1 and 1 sessions. One image held the app but no history folder. Among the other research images, ten Samsung images carry some Smart Switch data and none holds a history folder, a transfer list or a backup media database, so all eight artifacts report no rows on them. The rows described here come from Android 16 only.
- 8New artifacts
- 5Source file kinds
- +1,594Lines added in 21 files
- 8New synthetic test cases
The issue
A phone that arrived by transfer rather than by a fresh set-up raises a question: where did its contents come from? Samsung's Smart Switch is the app that moves data between phones, and it keeps notes about each session in its own data folder. ALEAPP had no artifact for them, so a report said nothing either way.
The notes are not hard to open by hand, but there are many of them: one folder per session with up to three JSON files, a list of transferred entries, and a database with thousands of rows. Reading raw JSON for categories, counts and peer fields is slow, and two properties make it error-prone. Newer files drop keys that older files held, so a reader written against one image shows blank columns on another. And a phone with more than one Android user holds a copy of the app data per user.
There is also a trap on the empty side. The app was present on some phones without any history at all, so an absent folder is not evidence that no transfer took place. Figure 1 shows where the records sit and which artifact reads which file.
Show this figure as a table
| File | Artifact or artifacts |
|---|---|
| files/History/ | Transfer Sessions |
| files/History/ | Transfer Sessions (device fields), Peer App Categories, Peer Accounts, Peer Message Counts, Peer Contact Accounts |
| files/History/ | Transferred Data Categories (and Item Count in Transfer Sessions) |
| files/TransferredHistory/List.json | Transferred History |
| files/SmartSwitch/SmartSwitchBackup/backup_media.db | Backup Media Table |
The essence
The module reads each Smart Switch file into its own artifact and keeps the values as stored. A session is one history folder, identified by the Android user and the folder name, which is a number that reads as epoch milliseconds and is shown as UTC. The other device's description, its lists of apps and accounts, and its message and contact counts come from the peer file in the same folder, exactly as that file wrote them. They are not checked against the other device.
| Artifact | Source in the app folder | One row per | Notable fields |
|---|---|---|---|
| Transfer Sessions | the three JSON files of a history folder | history folder | session state values as stored; peer device description; account and item counts |
| Transferred Data Categories | objItems.json, ItemList | data category | status, view and content counts, sizes, restore and backup results |
| Peer App Categories | peerDeviceInfo.json, CategoryInfoExtra | listed app or component | package, version, last time used in UTC, runtime permission count |
| Peer Accounts | peerDeviceInfo.json, AccountInfos | account entry | type and name as stored |
| Peer Message Counts | peerDeviceInfo.json, MessagePeriods | period | SMS, MMS and RCS counts and sizes as stored |
| Peer Contact Accounts | peerDeviceInfo.json, two contact lists | contact account | account, type, counts and sizes |
| Transferred History | TransferredHistory/List.json | entry | identifier, display name, time in UTC |
| Backup Media Table | backup_media.db, table bkmedia | row | name, file path, backup file path, size, unique id, count |
Our methodology
We began by mapping the files. Across the Android 16 images that held data, the same JSON files carried different keys: Connect Type, Product Code, Predicted Backup Time, Restore Step, Backup Result, Backup Step, Backup Error and, on one image, the message counts were absent from newer files. So the parser treats every key as optional and reads a missing one as blank. A folder that lacks one of its three files is still reported, with that file's columns empty.
Keys were next. A session is the pair of Android user and History ID. The user comes from the path: data/data counts as user 0, and the user, user_de and mirror forms carry their own numbers. Duplicate storage views of one file are read once. Times are converted from milliseconds to UTC and blank when absent or zero, and the time columns are moved to the front of each report.
Checking took five forms. An independent script, with no ALEAPP code, parsed the JSON files and counted the bkmedia rows and gave the same numbers as the artifacts. Figures in the notes, such as 32 and 11 categories in two sessions, 29 with a status of COMPLETED and 3 with NODATA, 118 apps, 8 accounts and 6 message periods per session, were re-derived from the raw JSON. The tool's output checker found columns that held one value on every row, for example Android User on a single-user image, and Restore Error and Backup Error that were identical because the file stores the same text in both objects. We wrote these into the notes instead of leaving the reader to wonder. A synthetic tree built by a fixture script, with invented values, an all-zero IMEI and a placeholder identifier, covers user 0, its mirror and user 10, with six new unit tests that pass. And a doubling test on a tree built from the real files read all eight artifacts exactly double.
One check failed, and we kept it. On the synthetic tree, seven of eight artifacts doubled, but Transfer Sessions went from 3 rows to 4 instead of 6, because the fixture already holds a user 10 folder with the same History ID, so the restaged copy lands on it. The pull request records this as a known failure with the arithmetic. The suite otherwise passed 140 cases with no failure.
We also left things out on purpose. Galaxy Wearable data was examined and not built, because its databases were empty. Newer images carry result fields that this module does not report, and the notes say so. Figure 2 shows the steps; Figure 3 shows the counts per image.
Show this figure as a table
| Step | What the parser does |
|---|---|
| Find the files | mainDataModel.json, peerDeviceInfo.json, objItems.json, List.json, backup_media.db |
| Set the keys | Android user from the path; data/data is user 0; a session is a user and a History ID; duplicate views are read once |
| Read defensively | absent keys read blank; a folder missing a file is still reported |
| Report | time columns first; milliseconds to UTC; booleans as Yes or No |
Show this figure as a table
| Artifact | Image 1 | Image 2 | Image 3 | Image 4 |
|---|---|---|---|---|
| Transfer Sessions | 2 | 0 | 1 | 1 |
| Transferred Data Categories | 43 | 0 | 92 | 65 |
| Peer App Categories | 236 | 0 | 97 | 66 |
| Peer Accounts | 16 | 0 | 7 | 10 |
| Peer Message Counts (rows) | 12 | 0 | 6 | 6 |
| Peer Contact Accounts (rows) | 12 | 0 | 0 | 6 |
| Transferred History | 1 | 0 | 1 | 1 |
| Backup Media Table | 5,169 | 0 | 0 | 0 |
The value
For an examiner the module turns a folder tree into answers to concrete questions. Was a Smart Switch session recorded on this phone, and how many? Which data categories did it list, with what status and counts? What did the other device describe itself as, and which apps and accounts did it list? Is there a media index, and how large? A session folder is an indicator that the app recorded a transfer session. It does not prove that a category moved in full, and a category missing from the list is not evidence that its data was absent from the other device.
The records carry personal identifiers, including an identifier, a display name, an account and a device number. The Lab publishes the structure and the counts, never a value. Figure 4 shows, with invented times, how an examiner can line up a folder name with the transferred list entry; on one real image the later folder name fell within one second of the entry's time. The parser does not make that match, and what event a folder name marks is not established.
Show this figure as a table
| Record | Time (synthetic) |
|---|---|
| History folder 1 | 09:12:40 |
| History folder 2 | 10:41:02.9 |
| TransferredHistory entry | 10:41:03.4 |
Where this sits in the Lab's research
No Lab report is devoted to this store; the method above comes from the pull request. It is one of five case studies in Lab Technical Report LAB-TR-0006, Section 7.1 and Table 8, which gives the same counts per image (sessions 2, 0, 1, 1; categories 43, 0, 92, 65; backup media 5,169, 0, 0, 0) and lists as not verified the One UI versions before 7. That report also describes the doubling test used here.
Cite as: Addai, D. (2026). Empty Is Not Absent: Silent Failure Modes in Open-Source Mobile Forensic Parsers on iOS 26 and Android 16. LAB-TR-0006, version 1.0, preprint. doi:10.5281/zenodo.23717929.
Sources
Every number and claim on this page, and where it comes from. Figures marked synthetic example use invented values.
| Number or claim | Where it comes from |
|---|---|
| Merged 25 October 2026; 21 files, +1,594 and -1 lines | Pull request 1783 metadata (mergedAt, files, additions, deletions) |
| Eight artifacts, five source file kinds | PR body, What this changes; diff, __artifacts_v2__ in samsungSmartSwitch.py |
| Sessions 2 / 0 / 1 / 1; categories 43 / 0 / 92 / 65; peer apps 236 / 0 / 97 / 66; accounts 16 / 0 / 7 / 10; message rows 12 / 0 / 6 / 6; contact rows 12 / 0 / 0 / 6; history 1 / 0 / 1 / 1; backup media 5,169 / 0 / 0 / 0 | PR body, first checklist item; LAB-TR-0006 Table 8 |
| Image 2 holds the app but no History folder | PR body, first checklist item |
| Seven Samsung images with the app folder (Android 10, 13, 14, 15), three with only the Agent package (Android 11, 13); none has History, List.json or backup_media.db | Diff, notes of smartswitch_sessions |
| One UI versions before 7 not verified | PR body, first checklist item; LAB-TR-0006 Table 8 |
| Keys absent from newer files: Connect Type, Product Code, Predicted Backup Time, Restore Step, Backup Result, Backup Step, Backup Error | PR body, second checklist item; diff notes |
| 32 and 11 categories, 29 COMPLETED and 3 NODATA, 118 apps, 8 accounts, 6 periods per session, re-derived from raw JSON | PR body, fourth checklist item; diff notes |
| Independent script gives the same counts; doubling test reads all eight artifacts exactly double | PR body, first and third checklist items |
| Synthetic tree: invented values, all-zero IMEI, placeholder UUID; user 0, mirror, user 10; six new tests | PR body, Anything reviewers should know and test record |
| Sessions 3 rows to 4 instead of 6 on the synthetic tree; KNOWN_FAIL=4; PASS=140, upstream 132, eight new cases | PR body, test record table |
| Later folder name within one second of the TransferredHistory entry on the tested image | Diff, notes of smartswitch_sessions and smartswitch_transferred_history |
| Galaxy Wearable databases empty and not built; ContentBnrResult fields not reported | PR body, fourth checklist item and Anything reviewers should know |
| Figure 4 times and identifier | Synthetic example, invented for illustration |