DownloadProvider

DownloadProvider 中 DRM 关注。

DownloadDrmHelper


DrmConvertSession


首先 DownloadThead 中

/**
* Read HTTP response headers and take appropriate action, including setting up the destination
* file and updating the database.
*/
private void processResponseHeaders(State state, InnerState innerState, HttpResponse response)
throws StopRequestException {
// if(Constants.LOGV) Log.v(LOGTAG, "enter processResponseHeaders()");

if (state.mContinuingDownload) {
// ignore response headers on resume requests
return;
}

readResponseHeaders(state, innerState, response);
if (DownloadDrmHelper.isDrmConvertNeeded(state.mMimeType)) { // 检测 是否含有 DRM mimetype 的 数据 , 如有 创建 DrmConvertSession。
mDrmConvertSession = DrmConvertSession.open(mContext, state.mMimeType);
if (mDrmConvertSession == null) {
throw new StopRequestException(Downloads.Impl.STATUS_NOT_ACCEPTABLE, "Mimetype "
+ state.mMimeType + " can not be converted.");
}
}

state.mFilename = Helpers.generateSaveFile(
mContext,
mInfo.mUri,
mInfo.mHint,
innerState.mHeaderContentDisposition,
innerState.mHeaderContentLocation,
state.mMimeType,
mInfo.mDestination,
(innerState.mHeaderContentLength != null) ?
Long.parseLong(innerState.mHeaderContentLength) : 0,
mInfo.mIsPublicApi, mStorageManager);
checkBin(state);
try {
state.mStream = new FileOutputStream(state.mFilename);
} catch (FileNotFoundException exc) {
throw new StopRequestException(Downloads.Impl.STATUS_FILE_ERROR,
"while opening destination file: " + exc.toString(), exc);
}
if (Constants.LOGV) {
Log.v(Constants.TAG, "writing " + mInfo.mUri + " to " + state.mFilename);
}

updateDatabaseFromHeaders(state, innerState);
// check connectivity again now that we know the total size
checkConnectivity();
}



Helper 中


/**
* Creates a filename (where the file should be saved) from info about a download.
*/
static String generateSaveFile(
Context context,
String url,
String hint,
String contentDisposition,
String contentLocation,
String mimeType,
int destination,
long contentLength,
boolean isPublicApi, StorageManager storageManager) throws StopRequestException {
checkCanHandleDownload(context, mimeType, destination, isPublicApi);
String path;
File base = null;
if (destination == Downloads.Impl.DESTINATION_FILE_URI) {
path = Uri.parse(hint).getPath();
} else {
base = storageManager.locateDestinationDirectory(mimeType, destination,
contentLength);
path = chooseFilename(url, hint, contentDisposition, contentLocation,
destination);
}
storageManager.verifySpace(destination, path, contentLength);
path = getFullPath(path, mimeType, destination, base);
if (DownloadDrmHelper.isDrmConvertNeeded(mimeType)) {
path = DownloadDrmHelper.modifyDrmFwLockFileExtension(path); // 文件名的确定
}

return path;
}


DownloadThread

/**
* Write a data buffer to the destination file.
* @param data buffer containing the data to write
* @param bytesRead how many bytes to write from the buffer
*/
private void writeDataToDestination(State state, byte[] data, int bytesRead)
throws StopRequestException {
// if(Constants.LOGV) Log.v(LOGTAG, "enter writeDataToDestination()");

for (;;) {
try {
if (state.mStream == null) {
state.mStream = new FileOutputStream(state.mFilename, true);
}
mStorageManager.verifySpaceBeforeWritingToFile(mInfo.mDestination, state.mFilename,
bytesRead);
if (!DownloadDrmHelper.isDrmConvertNeeded(mInfo.mMimeType)) { //保存数据时 针对 Drm 做处理
state.mStream.write(data, 0, bytesRead);
} else {
byte[] convertedData = mDrmConvertSession.convert(data, bytesRead);
if (convertedData != null) {
state.mStream.write(convertedData, 0, convertedData.length);
} else {
throw new StopRequestException(Downloads.Impl.STATUS_FILE_ERROR,
"Error converting drm data.");
}
}

return;
} catch (IOException ex) {
// couldn't write to file. are we out of space? check.
// TODO this check should only be done once. why is this being done
// in a while(true) loop (see the enclosing statement: for(;;)
if (state.mStream != null) {
mStorageManager.verifySpace(mInfo.mDestination, state.mFilename, bytesRead);
}
} finally {
if (mInfo.mDestination == Downloads.Impl.DESTINATION_EXTERNAL) {
closeDestination(state);
}
}
}
}



Helper

private static void checkCanHandleDownload(Context context, String mimeType, int destination,
boolean isPublicApi) throws StopRequestException {
return;
if (isPublicApi) {
return;
}

if (destination == Downloads.Impl.DESTINATION_EXTERNAL
|| destination == Downloads.Impl.DESTINATION_CACHE_PARTITION_PURGEABLE) {
if (mimeType == null) {
throw new StopRequestException(Downloads.Impl.STATUS_NOT_ACCEPTABLE,
"external download with no mime type not allowed");
}
if (!DownloadDrmHelper.isDrmMimeType(context, mimeType)) { // 查看系统是否支持 DRM 数据的打开
// Check to see if we are allowed to download this file. Only files
// that can be handled by the platform can be downloaded.
// special case DRM files, which we should always allow downloading.
Intent intent = new Intent(Intent.ACTION_VIEW);

// We can provide data as either content: or file: URIs,
// so allow both. (I think it would be nice if we just did
// everything as content: URIs)
// Actually, right now the download manager's UId restrictions
// prevent use from using content: so it's got to be file: or
// nothing

PackageManager pm = context.getPackageManager();
intent.setDataAndType(Uri.fromParts("file", "", null), mimeType);
ResolveInfo ri = pm.resolveActivity(intent, PackageManager.MATCH_DEFAULT_ONLY);
//Log.i(Constants.TAG, "*** FILENAME QUERY " + intent + ": " + list);

if (ri == null) {
if (Constants.LOGV) {
Log.v(Constants.TAG, "no handler found for type " + mimeType);
}
throw new StopRequestException(Downloads.Impl.STATUS_NOT_ACCEPTABLE,
"no handler found for this download type");
}
}

}
}


你可能感兴趣的:(download)