DownloadProvider

来源:互联网 发布:java如何求最小公倍数 编辑:程序博客网 时间:2024/06/03 14:58

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");
                }
            }

        }
    }


原创粉丝点击