用到的代码文件
/packages/apps/Bluetooth/src/:
com/android/bluetooth/opp/BluetoothOppObexServerSession.java
/frameworks/base/core/java/:
android/webkit/MimeTypeMap.java
/libcore/luni/src/main/java/:
libcore/net/MimeUtils.java
代码执行流程图
代码流程分析
下面的代码基于android O(api 27)。
本文基于MTK(MediaTek)平台基线。
这篇文章主要记录的是Bluetooth opp profile server(接收端)中 mime type判断流程。
当bt接收到一个文件传入的请求时,会进入BluetoothOppObexServerSession.java类中的onPut()方法。
这个方法进行判断当前接收文件的mimetype是否允许,如果允许就返回OBEX_HTTP_OK,如果不允许就返回其它类型的值。
@Override
public int onPut(Operation op) {
if (D) Log.d(TAG, "onPut " + op.toString());
HeaderSet request;
String name, mimeType;
Long length;
int obexResponse = ResponseCodes.OBEX_HTTP_OK;
/**
* For multiple objects, reject further objects after
* user deny the first one
*/
if (mAccepted == BluetoothShare.USER_CONFIRMATION_DENIED) {
return ResponseCodes.OBEX_HTTP_FORBIDDEN;
}
String destination;
if (mTransport instanceof BluetoothObexTransport) {
destination = ((BluetoothObexTransport)mTransport)
.getRemoteAddress();
} else {
destination = "FF:FF:FF:00:00:00";
}
boolean isWhitelisted = BluetoothOppManager
.getInstance(mContext).
isWhitelisted(destination);
try {
boolean pre_reject = false;
request = op.getReceivedHeader();
if (V) Constants.logHeader(request);
name = (String)request.getHeader(HeaderSet.NAME);
length = (Long)request.getHeader(HeaderSet.LENGTH);
/*
* 从请求头中获取发送过来的mime type
*/
mimeType = (String)request.getHeader(HeaderSet.TYPE);
if (length == 0) {
if (D) Log.w(TAG, "length is 0, reject the transfer");
pre_reject = true;
obexResponse = ResponseCodes.OBEX_HTTP_LENGTH_REQUIRED;
}
if (name == null || name.equals("")) {
if (D) Log.w(TAG, "name is null or empty, "
+ "reject the transfer");
pre_reject = true;
obexResponse = ResponseCodes.OBEX_HTTP_BAD_REQUEST;
}
if (!pre_reject) {
/* first we look for Mimetype in Android map */
String extension, type;
int dotIndex = name.lastIndexOf(".");
if (dotIndex < 0 && mimeType == null) {
if (D) Log.w(TAG, "There is no file extension "
+ "or mime type,"
+ "reject the transfer");
pre_reject = true;
obexResponse = ResponseCodes.OBEX_HTTP_BAD_REQUEST;
} else {
/*
* 从文件名中截取后缀
*/
extension = name.substring(dotIndex + 1).toLowerCase();
/*
* 根据文件名后缀尝试获取对应的mime type
*/
MimeTypeMap map = MimeTypeMap.getSingleton();
type = map.getMimeTypeFromExtension(extension);
if (V) Log.v(TAG, "Mimetype guessed from extension "
+ extension + " is " + type);
/*
* 如果从MimeTypeMap中获取的mime type不为空就使用获取的
*/
if (type != null) {
mimeType = type;
} else {
/*
* 如果从MimeTypeMap中获取的mime type为空且请求中
* 传输过来的mime type也为空那么就拒绝。
*/
if (mimeType == null) {
if (D) Log.w(TAG, "Can't get mimetype, "
+ "reject the transfer");
pre_reject = true;
obexResponse = ResponseCodes
.OBEX_HTTP_UNSUPPORTED_TYPE;
}
}
//将最终的mime type小写
if (mimeType != null) {
mimeType = mimeType.toLowerCase();
}
}
}
/*
* 判断mime type 是否处在:
* Constants.ACCEPTABLE_SHARE_INBOUND_TYPES
* Constants.UNACCEPTABLE_SHARE_INBOUND_TYPES
* 这两个字符串数组中
*/
// Reject policy: anything outside the "white list"
// plus unspecified
// MIME Types. Also reject everything in the "black list".
if (!pre_reject
&& (mimeType == null
|| (!isWhitelisted
&& !Constants.mimeTypeMatches(mimeType,
Constants.ACCEPTABLE_SHARE_INBOUND_TYPES))
|| Constants.mimeTypeMatches(mimeType,
Constants.UNACCEPTABLE_SHARE_INBOUND_TYPES))) {
if (D) Log.w(TAG, "mimeType is null or in "
+ "unacceptable list, reject the transfer");
pre_reject = true;
obexResponse = ResponseCodes.OBEX_HTTP_UNSUPPORTED_TYPE;
}
if (pre_reject
&& obexResponse != ResponseCodes.OBEX_HTTP_OK) {
// some bad implemented client won't send disconnect
return obexResponse;
}
} catch (IOException e) {
Log.e(TAG, "get getReceivedHeaders error " + e);
return ResponseCodes.OBEX_HTTP_BAD_REQUEST;
}
......(省略一大段代码)
return obexResponse;
}
下面看下MimeTypeMap.java中的getMimeTypeFromExtension()方法。
public String getMimeTypeFromExtension(String extension) {
return MimeUtils.guessMimeTypeFromExtension(extension);
}
下面进入MimeUtils.java中的guessMimeTypeFromExtension()方法。
public static String guessMimeTypeFromExtension(String extension) {
if (extension == null || extension.isEmpty()) {
return null;
}
extension = extension.toLowerCase(Locale.US);
/*
* 包含了各种各样的mime type 数组
*/
return extensionToMimeTypeMap.get(extension);
}
扩展
MimeTypeMap.java这个类在第三方应用中也可以调用。
MimeUtils.java类第三方应用不能使用。
本文由 tuzhao 创作,采用 知识共享署名4.0 国际许可协议进行许可
本站文章除注明转载/出处外,均为本站原创或翻译,转载前请务必署名
最后编辑时间为:
2018/01/03 22:43