2016년 9월 2일 금요일

Download data uri in Chromium Android

As a nice demo website shows, web developer can save a file via data uri. I am writing to explain how data uri is saved in chromium in this post.

When we open data uri, chromium starts a new blob url request job and when it finishes reading header information, then it will notify the completion of it.

Blob is handled by storage module and data response handling is done by net and browser loader modules.

|STORAGE| --> |NET| --> |CONTENT/BROWSER/LOADER|

From code level, we can start from loader module in content browser by |ThrottlingResourceHandler::OnResponseStarted|

This function iterated pre-registered throttles to be confirmed if any specific throttle wants to handle it. For example, when we see |InterceptDownloadResourceThrottle::ProcessDownloadRequest|, HTTP or HTTPS are handled by Android specific download delegate. However, as this post focuses on data uri handling, code will be interrupted by below condition.

  if (!url.SchemeIsHTTPOrHTTPS()) {
    RecordInterceptFailureReasons(NON_HTTP_OR_HTTPS);
    return;
  }


Let's go back where I described about pre-registered throttles iteration. So suppose there is no throttle want to handle response, code will flow into next handler. e.g. |DownloadRequestCore::OnResponseStarted|

From this point, we will see bunch of asynchronous operation happened in same browser process but sometimes in different thread. In my humble opinion, this prevents system from not responding status that hurts user experience. By the way, brief code flows are:

<Download>
|DownloadResourceHandler::OnStart| --> |DownloadManagerImpl::StartDownload| --> |DownloadItemImpl::Start| --> |DownloadFile::Initialize|

<Notify download started>
|DownloadFile::Initialize| --> |DownloadController::OnDownloadStarted| -> |ChromeDownloadDelegate::OnDownloadStarted| --> |ChromeDownloadDelegate#onDownloadStarted|

I also recommend to read nice sequence diagrame.

Hope this post saves your time from debugging. Happy hacking!

(Debugging was done with 53.0.2785.0 version)