相关代码
- packages/providers/MediaProvider/src/com/android/providers/media/MtpReceiver.java
- packages/providers/MediaProvider/src/com/android/providers/media/MtpService.java
- packages/providers/MediaProvider/src/com/android/providers/media/MediaProvider.java
- frameworks/base/media/java/android/mtp/MtpServer.java
- frameworks/base/media/java/android/mtp/MtpDatabase.java
- frameworks/base/media/java/android/mtp/MtpStorage.java
- frameworks/base/media/jni/android_mtp_MtpServer.cpp
- frameworks/base/media/jni/android_mtp_MtpDatabase.cpp
- frameworks/av/media/mtp/MtpServer.h
- frameworks/av/media/mtp/MtpServer.cpp
- frameworks/av/media/mtp/MtpDatabase.h
MTP主要处理逻辑
一、UsbDevicemanager发送usb状态广播
UsbDevicemanager发送ACTION_USB_STATE的广播,来通知usb状态的变化
private void updateUsbStateBroadcast() {
// send a sticky broadcast containing current USB state
boolean UsbDataUnlocked = isUsbTransferAllowed() && mUsbDataUnlocked ;
Intent intent = new Intent(UsbManager.ACTION_USB_STATE);
intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING
| Intent.FLAG_RECEIVER_FOREGROUND);
intent.putExtra(UsbManager.USB_CONNECTED, mConnected);
intent.putExtra(UsbManager.USB_CONFIGURED, mConfigured);
intent.putExtra(UsbManager.USB_DATA_UNLOCKED, UsbDataUnlocked);
if (mCurrentFunctions != null) {
String[] functions = mCurrentFunctions.split(",");
for (int i = 0; i < functions.length; i++) {
intent.putExtra(functions[i], true);//这里是各个functions的状态
}
}
if (DEBUG) Slog.d(TAG, "broadcasting " + intent + " , connected: " + mConnected
+ " , configured: " + mConfigured + " , UsbDataUnlocked: " + UsbDataUnlocked
+ " , CurrentFunctions: " + mCurrentFunctions);
mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
MtpReceiver.java
这个属于应用的代码,先监听开机广播,然后注册ACTION_USB_STATE广播,最后在handleUsbState的时候会启动MtpService
private void handleUsbState(Context context, Intent intent) {
Bundle extras = intent.getExtras();
boolean connected = extras.getBoolean(UsbManager.USB_CONFIGURED);
boolean mtpEnabled = extras.getBoolean(UsbManager.USB_FUNCTION_MTP);
boolean ptpEnabled = extras.getBoolean(UsbManager.USB_FUNCTION_PTP);
boolean unlocked = extras.getBoolean(UsbManager.USB_DATA_UNLOCKED);
// Start MTP service if USB is connected and either the MTP or PTP function is enabled
if (connected && (mtpEnabled || ptpEnabled)) {
intent = new Intent(context, MtpService.class);
intent.putExtra(UsbManager.USB_DATA_UNLOCKED, unlocked);
if (ptpEnabled) {
intent.putExtra(UsbManager.USB_FUNCTION_PTP, true);
}
if (DEBUG) { Log.d(TAG, "handleUsbState startService"); }
context.startService(intent);
// tell MediaProvider MTP is connected so it can bind to the service
context.getContentResolver().insert(Uri.parse(
"content://media/none/mtp_connected"), null);
} else {
boolean status = context.stopService(new Intent(context, MtpService.class));
if (DEBUG) { Log.d(TAG, "handleUsbState stopService status=" + status); }
// tell MediaProvider MTP is disconnected so it can unbind from the service
context.getContentResolver().delete(Uri.parse(
"content://media/none/mtp_connected"), null, null);
}
}
MtpService.java
public int onStartCommand(Intent intent, int flags, int startId) {
mUnlocked = intent.getBooleanExtra(UsbManager.USB_DATA_UNLOCKED, false);//该值为true默认MTP显示文件,否则就算默认MTP也是不显示磁盘内容的
if (LOGD) { Log.d(TAG, "onStartCommand intent=" + intent + " mUnlocked=" + mUnlocked); }
synchronized (mBinder) {
updateDisabledStateLocked();
mPtpMode = (intent == null ? false
: intent.getBooleanExtra(UsbManager.USB_FUNCTION_PTP, false));
String[] subdirs = null;
if (mPtpMode) {
int count = PTP_DIRECTORIES.length;
subdirs = new String[count];
for (int i = 0; i < count; i++) {
File file =
Environment.getExternalStoragePublicDirectory(PTP_DIRECTORIES[i]);
// make sure this directory exists
file.mkdirs();
subdirs[i] = file.getPath();
}
}
final StorageVolume primary = StorageManager.getPrimaryVolume(mVolumes);
if (mDatabase != null) {
mDatabase.setServer(null);
}
mDatabase = new MtpDatabase(this, MediaProvider.EXTERNAL_VOLUME,
primary.getPath(), subdirs);
manageServiceLocked();
}
return START_REDELIVER_INTENT;
}
private void manageServiceLocked() {
final boolean isCurrentUser = UserHandle.myUserId() == ActivityManager.getCurrentUser();
if (mServer == null && isCurrentUser) {
Log.d(TAG, "starting MTP server in " + (mPtpMode ? "PTP mode" : "MTP mode"));
Log.d(TAG,"mMtpDisabled " + mMtpDisabled);
mServer = new MtpServer(mDatabase, mPtpMode);
mDatabase.setServer(mServer);
if (!mMtpDisabled) {
addStorageDevicesLocked();
}
mServer.start();
} else if (mServer != null && !isCurrentUser) {
Log.d(TAG, "no longer current user; shutting down MTP server");
// Internally, kernel will close our FD, and server thread will
// handle cleanup.
mServer = null;
mDatabase.setServer(null);
}
}
private void addStorageDevicesLocked() {
if (mPtpMode) {
// In PTP mode we support only primary storage
final StorageVolume primary = StorageManager.getPrimaryVolume(mVolumes);
final String path = primary.getPath();
if (path != null) {
String state = mStorageManager.getVolumeState(path);
if (Environment.MEDIA_MOUNTED.equals(state)) {
addStorageLocked(mVolumeMap.get(path));
}
}
} else {
for (StorageVolume volume : mVolumeMap.values()) {
addStorageLocked(volume);
}
}
}