Saturday, April 16, 2016

usb - Why does MTP show wrong directory location?



MTP (Miserable Transfer Protocol) failed once again.


After moving a directory to a different path, it is still on the same path as before according to MTP.


I already tried re-plugging the USB port and reading it from a different computer. Same result.


Why is MTP so bogus that it shows a moved folder on its previous path?




Answer



What is Content Provider?


It seems to be a problem related to Media Providers. As the name suggests, they provide a database of available media in a more organized way to other apps as the Contacts Storage (com.android.providers.contacts) provides contacts to requesting apps. Purpose is to scan and store media file info for quick access so that individual apps don't have to scan folders manually for an up-to-date library, reducing time and effort.


Android's built-in Media Providers:


Some file explorers, media players and gallery apps depend on the files database (/data/data/com.android.providers.media/databases/external.db) built by Media Storage app for MediaStore content provider from the contents of external storage (/sdcard and external SD card; removable storage like USB isn't indexed). Apps Media Storage (com.android.providers.media under which com.process.media runs), Downloads (com.android.providers.downloads.ui), Download Manager (com.android.providers.downloads) and MTP Host (com.android.mtp) work in collaboration under same UID.


Database is built/updated as MediaScanner (android.process.media) is invoked by some app such as by sending broadcast MEDIA_SCANNER_SCAN_FILE or through scanFile. Broadcast receiver com.android.providers.media.MediaScannerReceiver is launched on boot that listens for android.intent.action.BOOT_COMPLETED, so MediaScannerService will also launch on boot. But restarting phone sometimes doesn't update whole external database (or at least delays). MediaScanner is also triggered when a new storage device is mounted i.e. on MEDIA_MOUNTED which could possibly be manually broadcasted to force updation on pre KitKat versions.
In response, apps are informed of updated databases such as by receiving broadcast MEDIA_SCANNER_FINISHED or through onScanCompleted.


Problem with Media Providers:


MtpService is also a part of Media Storage. Due to some bugs (acknowledged since 2012) in implementation of MTP, database isn't updated or is delayed or isn't properly communicated with the client as the files change, so MTP shows outdated / incomplete contents. The same can happen if an app creating or downloading a new file fails to trigger the MediaScanner or fails to receive back the updated information.


Solution:



In order to force database updation, delete the file and run some media scanner app. Non-root users can delete this file by clearing data of Media Storage app.
But be aware, it'll also clear internal.db which will make ringtones unavailable and a new database will be built from /system/media on next reboot i.e. on BOOT_COMPLETED.


PS: Note that the internal SD card we see is emulated from /data/media/ using sdcardfs (or FUSE in older versions of Android). Actual contents of internal memory can be seen directly from /data/media/ (root required). UMS used to expose the /data block device to PC but was deprecated in favor of MTP. It's a good option when larger size of data is to be transferred at high speeds. It can be enabled by some workaround.
There are also other reasonable alternatives for MTP like FTP, SFTP/SSHFS, adbfs etc.


RESOURCES:



No comments:

Post a Comment

samsung galaxy s 2 - Cannot restore Kies backup after firmware upgrade

I backed up my Samsung Galaxy S2 on Kies before updating to Ice Cream Sandwich. After the upgrade I tried to restore, but the restore fails ...