android MTP读写权限单独控制
前言
最近有一个需求,需要从手机端这边单独控制手机的读写权限,也就是adb 的pull 和push 权限,MTP 文件管理的copy delet 等操作。
禁止或允许adb 和MTP 的方法我知道。从插上usb 线弹出的那个选择框的源码入手,就可以看到。设置个参数就可以了。方法如下:
private final static int ADB_DISABLE_ALL = 0;
private final static int ADB_ENABLE_ADB = 1;
private final static int ADB_ENABLE_MTP = 2;
Settings.Global.putInt(getContext().getContentResolver(), "usb_per_settings", ADB_DISABLE_ALL);
但是分别控制,那肯定就得改这两个实现的源码了。首先来看下MTP。
MTP 源码解析
1. MTP 简介
MTP,全称 Media Transfer Protocol(媒体传输协议),是微软的一个为计算机和便携式设备间传输图像,音乐等所定制的协议。
Android 从3.0 开始支持MTP,MTP 的应用分为两种,一个是Initiator(PC 端),另一个是Responder(移动端)
-
Initiator(PC 端):
在MTP中所有的请求都有Initiator发起。例如,PC请求获取Android平板电脑上的文件数据。
-
Responder(移动端)
它会处理Initiator的请求;除此之外,Responder也会发送Event事件。
2. MTP 核心类
-
1.MtpReceiver:
这个类是一个广播接受器,接收"开机完成"和”USB“是否插入的广播
-
2.MtpService:
提供管理MTP 的服务,它会启动MtpSercer,以及将本地存储内容和MTP 的内容同步,初始化MTP 设备名称等。
-
3.MediaProvider:
媒体数据库的封装,对外提供RUI 实现对数据库的增删改查功能。
-
4.MtpServer:
核心类,本文也是针对此问题修改。MtpServer.cpp中主要提供了一些对文件操作的接口方法,例如:添加,删除,重命名文件,MtpServier.java 中也是提供了此方法。但是是属于上层。
3. MTP 主要类路径
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/andorid/mtp/MtpServer.java
frameworks/base/media/java/andorid/mtp/MtpDatabase.java
frameworks/base/media/java/andorid/mtp/MtpStorage.java
frameworks/base/media/jni/android_mtp_MtpServer.cpp
frameworks/base/media/jni/android_mtp_MtpDatabase.cpp
framewords/av/media/mtp/MtpServer.h
framewords/av/media/mtp/MtpServer.cpp
framewords/av/media/mtp/MtpDatabse.h
MTP 权限单独控制
可以看到以下是处理我们在PC 端执行删除,查找,添加等的命令的分发控制。所以我们只要找到对应的case定义,然后做特殊的处理就可以了。
/frameworks/av/media/mtp/MtpServer.cpp
320bool MtpServer::handleRequest() {
321 std::lock_guard<std::mutex> lg(mMutex);
322
323 MtpOperationCode operation = mRequest.getOperationCode();
324 MtpResponseCode response;
325
326 mResponse.reset();
327
328 if (mSendObjectHandle != kInvalidObjectHandle && operation != MTP_OPERATION_SEND_OBJECT) {
329 mSendObjectHandle = kInvalidObjectHandle;
330 mSendObjectFormat = 0;
331 mSendObjectModifiedTime = 0;
332 }
333
334 int containertype = mRequest.getContainerType();
335 if (containertype != MTP_CONTAINER_TYPE_COMMAND) {
336 ALOGE("wrong container type %d", containertype);
337 return false;
338 }
339
340 ALOGV("got command %s (%x)", MtpDebug::getOperationCodeName(operation), operation);
341
342 switch (operation) {
343 case MTP_OPERATION_GET_DEVICE_INFO:
344 response = doGetDeviceInfo();
345 break;
346 case MTP_OPERATION_OPEN_SESSION:
347 response = doOpenSession();
348 break;
349 case MTP_OPERATION_RESET_DEVICE:
350 case MTP_OPERATION_CLOSE_SESSION:
351 response = doCloseSession();
352 break;
353 case MTP_OPERATION_GET_STORAGE_IDS:
354 response = doGetStorageIDs();
355 break;
356 case MTP_OPERATION_GET_STORAGE_INFO:
357 response = doGetStorageInfo();
358 break;
359 case MTP_OPERATION_GET_OBJECT_PROPS_SUPPORTED:
360 response = doGetObjectPropsSupported();
361 break;
362 case MTP_OPERATION_GET_OBJECT_HANDLES:
363 response = doGetObjectHandles();
364 break;
365 case MTP_OPERATION_GET_NUM_OBJECTS:
366 response = doGetNumObjects();
367 break;
368 case MTP_OPERATION_GET_OBJECT_REFERENCES:
369 response = doGetObjectReferences();
370 break;
371 case MTP_OPERATION_SET_OBJECT_REFERENCES:
372 response = doSetObjectReferences();
373 break;
374 case MTP_OPERATION_GET_OBJECT_PROP_VALUE:
375 response = doGetObjectPropValue();
376 break;
377 case MTP_OPERATION_SET_OBJECT_PROP_VALUE:
378 response = doSetObjectPropValue();
379 break;
380 case MTP_OPERATION_GET_DEVICE_PROP_VALUE:
381 response = doGetDevicePropValue();
382 break;
383 case MTP_OPERATION_SET_DEVICE_PROP_VALUE:
384 response = doSetDevicePropValue();
385 break;
386 case MTP_OPERATION_RESET_DEVICE_PROP_VALUE:
387 response = doResetDevicePropValue();
388 break;
389 case MTP_OPERATION_GET_OBJECT_PROP_LIST:
390 response = doGetObjectPropList();
391 break;
392 case MTP_OPERATION_GET_OBJECT_INFO:
393 response = doGetObjectInfo();
394 break;
395 case MTP_OPERATION_GET_OBJECT:
396 response = doGetObject();
397 break;
398 case MTP_OPERATION_GET_THUMB:
399 response = doGetThumb();
400 break;
401 case MTP_OPERATION_GET_PARTIAL_OBJECT:
402 case MTP_OPERATION_GET_PARTIAL_OBJECT_64:
403 response = doGetPartialObject(operation);
404 break;
405 case MTP_OPERATION_SEND_OBJECT_INFO: // PC 端向手机中拷贝文件
406 response = doSendObjectInfo();
407 break;
408 case MTP_OPERATION_SEND_OBJECT:
409 response = doSendObject();
410 break;
411 case MTP_OPERATION_DELETE_OBJECT:
412 response = doDeleteObject();
413 break;
414 case MTP_OPERATION_COPY_OBJECT:
415 response = doCopyObject();
416 break;
417 case MTP_OPERATION_MOVE_OBJECT:
418 response = doMoveObject();
419 break;
420 case MTP_OPERATION_GET_OBJECT_PROP_DESC:
421 response = doGetObjectPropDesc();
422 break;
423 case MTP_OPERATION_GET_DEVICE_PROP_DESC:
424 response = doGetDevicePropDesc();
425 break;
426 case MTP_OPERATION_SEND_PARTIAL_OBJECT:
427 response = doSendPartialObject();
428 break;
429 case MTP_OPERATION_TRUNCATE_OBJECT:
430 response = doTruncateObject();
431 break;
432 case MTP_OPERATION_BEGIN_EDIT_OBJECT:
433 response = doBeginEditObject();
434 break;
435 case MTP_OPERATION_END_EDIT_OBJECT:
436 response = doEndEditObject();
437 break;
438 default:
439 ALOGE("got unsupported command %s (%x)",
440 MtpDebug::getOperationCodeName(operation), operation);
441 response = MTP_RESPONSE_OPERATION_NOT_SUPPORTED;
442 break;
443 }
444
445 if (response == MTP_RESPONSE_TRANSACTION_CANCELLED)
446 return false;
447 mResponse.setResponseCode(response);
448 return true;
449}