Testing Android Device-to-Device Transfer
Trudy Firestone
Reading time: about 6 min
Topics:
autoBackup=false
. This also allowed apps to configure device-to-device transfer (D2D transfer), which provided users a way to easily transfer their data between their old and new phones. Since these processes were governed by the same rules, it was easy to control both, but apps couldn’t take advantage of device-to-device transfer’s differences to transfer more data than would be allowed by the 25MB cloud storage limit. Once an app starts targeting Android 12 or above, however, Android introduces the ability to configure device-to-device transfer separately from Google Drive backup and removes the ability to turn off device-to-device transfer using autoBackup=false
. With these changes, it’s important to test both types of backup separately since their behavior no longer matches.
Testing the different kinds of backup
Testing cloud backup is fairly simple. The Android developer’s website has clear documentation that makes it easy to backup and restore your app usingadb
. However, it’s less clear how device-to-device transfer can be tested. Fortunately, the command mentioned in Android’s documentation for making sure the device has the transport for cloud backup enabled provides a hint.
When I run adb shell bmgr list transports
on my phone it returns this:
android/com.android.internal.backup.LocalTransport
com.google.android.gms/.backup.migrate.service.D2dTransport
* com.google.android.gms/.backup.BackupTransportService
By changing the transport, testing device-to-device transport is possible. Unfortunately, it’s not as smooth as testing cloud backup because you can’t directly restore. Logcat displays the warning W/Backup: [D2dTransport] Can't restore from D2d Transport
. Still, this approach allows you to at least see which files are being backed up without actually using device-to-device transfer to transfer all your data to a new device.
Commands for testing device-to-device transfer
- List transports to make sure you have device-to-device transfer available
adb shell bmgr list transports
- Switch to the D2D transport listed
adb shell bmgr transport com.google.android.gms/.backup.migrate.service.D2dTransport
- The output of
adb shell bmgr list transports
should change to:android/com.android.internal.backup.LocalTransport * com.google.android.gms/.backup.migrate.service.D2dTransport com.google.android.gms/.backup.BackupTransportService
- Make sure backup is enabled on the device as mentioned in Android’s testing backup documentation
- If you switch transports before you enable backup, you can avoid setting up a Google account to back up to on an emulator. However, if you want to test backup, you’ll still need to do that.
- Run the same backup commands you would for testing cloud backup while watching Logcat
adb shell bmgr backupnow <your-package-name>
- Assuming you have something to back up, you should see progress towards backing up just like you would for cloud backup which should complete with
Package <your-package-name> with result: Success Backup finished with result: Success
- Search for
backup
in Logcat - Make sure that the correct information was backed up and that the backup was successful. For instance, if you only wanted to transfer shared preferences, you might see something like the below output:
D/KeyValueBackupTask: Starting full backups for: [<your-package-name>] D/Backup: [D2dTransport] Moved from state 0 to 1 I/Backup: [D2dTransport] performFullBackup : PackageInfo{<your-package-info>} I/FullBackup_native: measured [/data/data/<your-package-name>/shared_prefs] at 0 I/FullBackup_native: measured [/data/data/<your-package-name>/shared_prefs/test_preferences.xml] at 1024 I/file_backup_helper: Name: apps/<your-package-name>/_manifest I/FullBackup_native: measured [/data/cache/backup_stage/_manifest] at 1536 D/BackupManagerService: Calling doFullBackup() on <your-package-name> I/FullBackup_native: measured [/data/data/<your-package-name>/shared_prefs] at 0 I/file_backup_helper: Name: apps/<your-package-name>/sp/test_preferences.xml I/FullBackup_native: measured [/data/data/<your-package-name>/shared_prefs/test_preferences.xml] at 1024 D/Backup: [D2dTransport] backup finished D/Backup: [D2dTransport] finishBackup from: 1, package: <your-package-name> D/Backup: [D2dTransport] Moved from state 1 to 0 I/PFTBT: Full backup completed with status: 0 I/PFTBT: Full data backup pass finished.
- Switch back to the cloud transport
adb shell bmgr transport com.google.android.gms/.backup.BackupTransportService
Bonus: Disabling device-to-device transfer
While it’s certainly more difficult, it’s still possible for an application to disable device-to-device transfer. Since Android 12 allows you to configure device-to-device transfer, you can simply disable all the types of data that are backed up. For example:<data-extraction-rules>
<cloud-backup disableIfNoEncryptionCapabilities="true">
<exclude domain="file" path="."/>
<exclude domain="database" path="."/>
<exclude domain="sharedpref" path="."/>
<exclude domain="external" path="."/>
<exclude domain="root" path="."/>
</cloud-backup>
<device-transfer>
<exclude domain="file" path="."/>
<exclude domain="database" path="."/>
<exclude domain="sharedpref" path="."/>
<exclude domain="external" path="."/>
<exclude domain="root" path="."/>
</device-transfer>
</data-extraction-rules>
You can test that device-to-device transfer is fully disabled by following the generic directions above. However, the results will be quite different.
Instead of seeing backup progress, you may receive this error message:
Package <your-package-name> with result: Transport rejected package because it wasn't able to process it at the time
. When you search for backup
in Logcat, you should look for something similar to the following output:
D/KeyValueBackupTask: Starting full backups for: [<your-package-name>]
D/Backup: [D2dTransport] Moved from state 0 to 1
I/Backup: [D2dTransport] performFullBackup : PackageInfo{<your-package-info>}
I/FullBackup_native: measured [/data/user_de/0/<your-package-name>] at 0
I/FullBackup_native: measured [/data/user_de/0/<your-package-name>/files] at 0
I/FullBackup_native: measured [/data/user_de/0/<your-package-name>/databases] at 0
I/FullBackup_native: measured [/data/user_de/0/<your-package-name>/shared_prefs] at 0
D/Backup: [D2dTransport] Declining backup of size 0
I/Backup: [D2dTransport] Canceling full backup of <your-package-name>
D/Backup: [D2dTransport] finishBackup from: 1, package: <your-package-name>
I/Backup: [D2dTransport] Deleting partial backup data file: <your-package-name> due to error: 5
D/Backup: [D2dTransport] Moved from state 1 to 0
I/PFTBT: Transport rejected backup of <your-package-name>, skipping
W/ActivityManager: Unbinding backup agent with no active backup
I/PFTBT: Full backup completed with status: 0
I/PFTBT: Full data backup pass finished.
Since there’s no data to be backed up, the device-to-device transport skips the app.
Hopefully, you’ll be able to use this guide to easily test device-to-device transfer, allowing you to make sure that your config is set up correctly for both types of backup.About Lucid
Lucid Software is a pioneer and leader in visual collaboration dedicated to helping teams build the future. With its products—Lucidchart, Lucidspark, and Lucidscale—teams are supported from ideation to execution and are empowered to align around a shared vision, clarify complexity, and collaborate visually, no matter where they are. Lucid is proud to serve top businesses around the world, including customers such as Google, GE, and NBC Universal, and 99% of the Fortune 500. Lucid partners with industry leaders, including Google, Atlassian, and Microsoft. Since its founding, Lucid has received numerous awards for its products, business, and workplace culture. For more information, visit lucid.co.