Chromium compilation and debugging

Chromium Android compiler only supports Linux, so I made an Ubuntu virtual machine (Parallels Desktop, actually Mvware is also very useful, I don’t know why I can’t access the Internet behind)

  1. Git clone chromium.googlesource.com/chromium/to…
  2. Configure the environment variables depot_tools corresponding download directory, or execute the export PATH = “$PATH: / home/test/Donloads depot_tools”
  3. Pull the source code, first switch to the Chromium directory mkdir ~/chromium && CD ~/chromium, then execute fetch –nohooks Android, a total of more than 60 G content to download, There are all kinds of third party libraries in addition to Chromium source code (it is best to download one time, broken, will start again to download, and there will be various problems)
  4. Gclient file is configured with target_OS = [“android”] in the Chromium directory. Generally, after the third step, it will be automatically added. If not, it will be added at the end
  5. After the source code is downloaded, the SRC directory will be generated under chromium. CD to this directory to execute build/install-build-deps-android.sh
  6. gclient runhooks
  7. To set compilation parameters, run the gn args out/Default command and open the out/Default/args.gn file to set compilation parameters, for example
target_os = "android"
target_cpu = "arm"  # See "Figuring out target_cpu" below
is_component_build=true
symbol_level=2
enable_nacl=false
is_debug=true
v8_android_log_stdout=true
Copy the code
  1. Run ninja -C out/Default chrome_public_apk, start compiling, verify python3 is installed, install dataclasses pip3 install dataclasses
  2. The compilation process was lengthy, taking more than 14 hours on my side
  3. Install the apk (out/Default/apks ChromePublic. Apk)
  4. Open chromuim, run./out/Default/bin/chrome_public_apk GDB, you can enter GDB debugging!!

Network Request Process

Network requests from HttpCache: : Transaction: : Start to begin

Detailed call stack
#0  net::HttpCache::Transaction::Start(net::HttpRequestInfo const*, base::OnceCallback<void (int)>, net::NetLogWithSource const&) at ../../net/http/http_cache_transaction.cc:242
#1  0xbd8d9952 in net::URLRequestHttpJob::StartTransactionInternal (this=0xb0f11000) at ../../net/url_request/url_request_http_job.cc:484
#2  0xbd8d9636 in net::URLRequestHttpJob::StartTransaction (this=0xb0f11000) at ../../net/url_request/url_request_http_job.cc:405
#3  0xbd8d9f9c in net::URLRequestHttpJob::SetCookieHeaderAndStart (this=0x9bf7dc00, options=..., cookies_with_access_result_list=..., excluded_list=...) at ../../net/url_request/url_request_http_job.cc:694
#4  0xbd8dc31c in base::internal::InvokeHelper... at ../../base/bind_internal.h:668
#5  0xbd8dc2f6 in base::internal::Invoker... at ../../base/bind_internal.h:721
#6  0xbd7c946c in base::OnceCallback  at ../../base/callback.h:98
#7  0xbd7c4522 in (anonymous namespace)::MaybeRunCookieCallback<...>(base::OnceCallback<void (...)  at ../../net/cookies/cookie_monster.cc:134
#8  net::CookieMonster::GetCookieListWithOptions(...) at ../../net/cookies/cookie_monster.cc:628
#9  0xbd7c818a in base::internal::FunctorTraits<...>::Invoke<void (net::CookieMonster::*), net::CookieMonster*, GURL, net::CookieOptions, base::OnceCallback<void > > (...) at ../../base/bind_internal.h:509
#10 0xbd7c8162 in base::internal::InvokeHelper<false, void>::MakeItSo<void (net::CookieMonster::*)(GURL const&, net::CookieOptions const&, base::OnceCallback<void (std::__Cr::vector<net::CookieWithAccessResult, std::__Cr::allocator<net::CookieWithAccessResult> > const&, std::__Cr::vector<net::CookieWithAccessResult, std::__Cr::allocator<net::CookieWithAccessResult> > const&)>), net::CookieMonster*, GURL, net::CookieOptions, base::OnceCallback<void (std::__Cr::vector<net::CookieWithAccessResult, std::__Cr::allocator<net::CookieWithAccessResult> > const&, std::__Cr::vector<net::CookieWithAccessResult, std::__Cr::allocator<net::CookieWithAccessResult> > const&)> >(void (net::CookieMonster::*&&)(GURL const&, net::CookieOptions const&, base::OnceCallback<void (std::__Cr::vector<net::CookieWithAccessResult, std::__Cr::allocator<net::CookieWithAccessResult> > const&, std::__Cr::vector<net::CookieWithAccessResult, std::__Cr::allocator<net::CookieWithAccessResult> > const&)>), net::CookieMonster*&&, GURL&&, net::CookieOptions&&, base::OnceCallback<void (std::__Cr::vector<net::CookieWithAccessResult, std::__Cr::allocator<net::CookieWithAccessResult> > const&, std::__Cr::vector<net::CookieWithAccessResult, std::__Cr::allocator<net::CookieWithAccessResult> > const&)>&&) (functor=<optimized out>, args=..., args=..., args=..., args=...) at ../../base/bind_internal.h:648
#11 0xbd7c8148 in base::internal::Invoker<base::internal::BindState<void (net::CookieMonster::*)(GURL const&, net::CookieOptions const&, base::OnceCallback<void (std::__Cr::vector<net::CookieWithAccessResult, std::__Cr::allocator<net::CookieWithAccessResult> > const&, std::__Cr::vector<net::CookieWithAccessResult, std::__Cr::allocator<net::CookieWithAccessResult> > const&)>), base::internal::UnretainedWrapper<net::CookieMonster>, GURL, net::CookieOptions, base::OnceCallback<void (std::__Cr::vector<net::CookieWithAccessResult, std::__Cr::allocator<net::CookieWithAccessResult> > const&, std::__Cr::vector<net::CookieWithAccessResult, std::__Cr::allocator<net::CookieWithAccessResult> > const&)> >, void ()>::RunImpl<void (net::CookieMonster::*)(GURL const&, net::CookieOptions const&, base::OnceCallback<void (std::__Cr::vector<net::CookieWithAccessResult, std::__Cr::allocator<net::CookieWithAccessResult> > const&, std::__Cr::vector<net::CookieWithAccessResult, std::__Cr::allocator<net::CookieWithAccessResult> > const&)>), std::__Cr::tuple<base::internal::UnretainedWrapper<net::CookieMonster>, GURL, net::CookieOptions, base::OnceCallback<void (std::__Cr::vector<net::CookieWithAccessResult, std::__Cr::allocator<net::CookieWithAccessResult> > const&, std::__Cr::vector<net::CookieWithAccessResult, std::__Cr::allocator<net::CookieWithAccessResult> > const&)> >, 0u, 1u, 2u, 3u>(void (net::CookieMonster::*&&)(GURL const&, net::CookieOptions const&, base::OnceCallback<void (std::__Cr::vector<net::CookieWithAccessResult, std::__Cr::allocator<net::CookieWithAccessResult> > const&, std::__Cr::vector<net::CookieWithAccessResult, std::__Cr::allocator<net::CookieWithAccessResult> > const&)>), std::__Cr::tuple<base::internal::UnretainedWrapper<net::CookieMonster>, GURL, net::CookieOptions, base::OnceCallback<void (std::__Cr::vector<net::CookieWithAccessResult, std::__Cr::allocator<net::CookieWithAccessResult> > const&, std::__Cr::vector<net::CookieWithAccessResult, std::__Cr::allocator<net::CookieWithAccessResult> > const&)> >&&, std::__Cr::integer_sequence<unsigned int, 0u, 1u, 2u, 3u>) (functor=@0x9bf7dc00: &virtual table offset -1113271444, bound=...) at ../../base/bind_internal.h:721
#12 0xbd796968 in base::OnceCallback<void ()>::Run() && (this=<optimized out>) at ../../base/callback.h:98
#13 0xbd7c3dc8 in net::CookieMonster::DoCookieCallbackForHostOrDomain(base::OnceCallback<void ()>, base::BasicStringPiece<char, std::__Cr::char_traits<char> >) (this=0xc2c99c80, callback=..., host_or_domain=...) at ../../net/cookies/cookie_monster.cc:1908
#14 0xbd7c444a in net::CookieMonster::DoCookieCallbackForURL(base::OnceCallback<void ()>, GURL const&) (this=0x9bf7dc00, callback=..., url=...) at ../../net/cookies/cookie_monster.cc:1869
#15 0xbd7c4418 in net::CookieMonster::GetCookieListWithOptionsAsync(GURL const&, net::CookieOptions const&, base::OnceCallback<void (std::__Cr::vector<net::CookieWithAccessResult, std::__Cr::allocator<net::CookieWithAccessResult> > const&, std::__Cr::vector<net::CookieWithAccessResult, std::__Cr::allocator<net::CookieWithAccessResult> > const&)>) (this=0x9bf7dc00, url=..., options=..., callback=...) at ../../net/cookies/cookie_monster.cc:402
#16 0xbd8d9124 in net::URLRequestHttpJob::AddCookieHeaderAndStart (this=<optimized out>) at ../../net/url_request/url_request_http_job.cc:597
#17 0xbd8d8dce in net::URLRequestHttpJob::Start (this=0x9bf7dc00) at ../../net/url_request/url_request_http_job.cc:316
#18 0xbd8d3bb6 in net::URLRequest::StartJob (this=0xa2952c00, job=...) at ../../net/url_request/url_request.cc:685
#19 0xbd8d3908 in net::URLRequest::BeforeRequestComplete (this=0x9bf7dc00, error=0) at ../../net/url_request/url_request.cc:602
#20 0xbd8d3786 in net::URLRequest::Start (this=0x9bf7dc00) at ../../net/url_request/url_request.cc:534
#21 0xb450109c in network::URLLoader::ScheduleStart (this=0xb1b88080) at ../../services/network/url_loader.cc:914
#22 0xb44ffda0 in network::URLLoader::URLLoader(net::URLRequestContext*, network::URLLoaderFactory*, network::mojom::NetworkContextClient*, base::OnceCallback<void (network::mojom::URLLoader*)>, mojo::PendingReceiver<network::mojom::URLLoader>, int, network::ResourceRequest const&, mojo::PendingRemote<network::mojom::URLLoaderClient>, net::NetworkTrafficAnnotationTag const&, network::mojom::URLLoaderFactoryParams const*, network::mojom::CrossOriginEmbedderPolicyReporter*, unsigned int, int, bool, scoped_refptr<network::ResourceSchedulerClient>, base::WeakPtr<network::KeepaliveStatisticsRecorder>, network::mojom::TrustedURLLoaderHeaderClient*, network::mojom::OriginPolicyManager*, std::__Cr::unique_ptr<network::TrustTokenRequestHelperFactory, std::__Cr::default_delete<network::TrustTokenRequestHelperFactory> >, network::cors::OriginAccessList const&, mojo::PendingRemote<network::mojom::CookieAccessObserver>, mojo::PendingRemote<network::mojom::URLLoaderNetworkServiceObserver>, mojo::PendingRemote<network::mojom::DevToolsObserver>, mojo::PendingRemote<network::mojom::AcceptCHFrameObserver>) (this=0xb1b88080, url_request_context=<optimized out>, url_loader_factory=<optimized out>, network_context_client=<optimized out>, delete_callback=..., url_loader_receiver=..., options=0, request=..., url_loader_client=..., traffic_annotation=..., factory_params=0xa297a080, coep_reporter=0x0, request_id=0, keepalive_request_size=0, require_network_isolation_key=true, resource_scheduler_client=scoped_refptr((network::ResourceSchedulerClient *)0x0), keepalive_statistics_recorder=base::WeakPtr((uintptr_t)0), url_loader_header_client=0x0, origin_policy_manager=0xb1bd8b80, trust_token_helper_factory=..., origin_access_list=..., cookie_observer=..., url_loader_network_observer=..., devtools_observer=..., accept_ch_frame_observer=...) at ../../services/network/url_loader.cc:654
#23 0xb4509bca in std::__Cr::make_unique<network::URLLoader, net::URLRequestContext*, network::URLLoaderFactory*, network::mojom::NetworkContextClient*, base::OnceCallback<void (network::mojom::URLLoader*)>, mojo::PendingReceiver<network::mojom::URLLoader>, unsigned int&, network::ResourceRequest const&, mojo::PendingRemote<network::mojom::URLLoaderClient>, net::NetworkTrafficAnnotationTag, network::mojom::URLLoaderFactoryParams*, network::mojom::CrossOriginEmbedderPolicyReporterProxy*, int&, int&, bool, scoped_refptr<network::ResourceSchedulerClient>&, base::WeakPtr<network::KeepaliveStatisticsRecorder>, network::mojom::TrustedURLLoaderHeaderClientProxy*, network::mojom::OriginPolicyManager*, std::__Cr::unique_ptr<network::TrustTokenRequestHelperFactory, std::__Cr::default_delete<network::TrustTokenRequestHelperFactory> >, network::cors::OriginAccessList const&, mojo::PendingRemote<network::mojom::CookieAccessObserver>, mojo::PendingRemote<network::mojom::URLLoaderNetworkServiceObserver>, mojo::PendingRemote<network::mojom::DevToolsObserver>, mojo::PendingRemote<network::mojom::AcceptCHFrameObserver> >(net::URLRequestContext*&&, network::URLLoaderFactory*&&, network::mojom::NetworkContextClient*&&, base::OnceCallback<void (network::mojom::URLLoader*)>&&, mojo::PendingReceiver<network::mojom::URLLoader>&&, unsigned int&, network::ResourceRequest const&, mojo::PendingRemote<network::mojom::URLLoaderClient>&&, net::NetworkTrafficAnnotationTag&&, network::mojom::URLLoaderFactoryParams*&&, network::mojom::CrossOriginEmbedderPolicyReporterProxy*&&, int&, int&, bool&&, scoped_refptr<network::ResourceSchedulerClient>&, base::WeakPtr<network::KeepaliveStatisticsRecorder>&&, network::mojom::TrustedURLLoaderHeaderClientProxy*&&, network::mojom::OriginPolicyManager*&&, std::__Cr::unique_ptr<network::TrustTokenRequestHelperFactory, std::__Cr::default_delete<network::TrustTokenRequestHelperFactory> >&&, network::cors::OriginAccessList const&, mojo::PendingRemote<network::mojom::CookieAccessObserver>&&, mojo::PendingRemote<network::mojom::URLLoaderNetworkServiceObserver>&&, mojo::PendingRemote<network::mojom::DevToolsObserver>&&, mojo::PendingRemote<network::mojom::AcceptCHFrameObserver>&&) (__args=..., __args=..., __args=..., __args=..., __args=..., __args=..., __args=..., __args=..., __args=..., __args=..., __args=..., __args=..., __args=..., __args=..., __args=..., __args=..., __args=..., __args=..., __args=..., __args=..., __args=..., __args=..., __args=..., __args=...) at ../../buildtools/third_party/libc++/trunk/include/__memory/unique_ptr.h:725
#24 0xb4509806 in network::URLLoaderFactory::CreateLoaderAndStart (this=0xa1e4d200, receiver=..., request_id=0, options=0, url_request=..., client=..., traffic_annotation=...) at ../../services/network/url_loader_factory.cc:238
#25 0xb44b4c02 in network::cors::CorsURLLoader::StartNetworkRequest (this=0xc9432c00, error_code=<optimized out>, status=..., has_authorization_covered_by_wildcard=<optimized out>) at ../../services/network/cors/cors_url_loader.cc:545
#26 0xb44b3638 in network::cors::CorsURLLoader::StartRequest (this=0x9bf7dc00) at ../../services/network/cors/cors_url_loader.cc:490
#27 0xb44b3436 in network::cors::CorsURLLoader::Start (this=0x9bf7dc00) at ../../services/network/cors/cors_url_loader.cc:126
#28 0xb44b6c5a in network::cors::CorsURLLoaderFactory::CreateLoaderAndStart (this=<optimized out>, receiver=..., request_id=0, options=0, resource_request=..., client=..., traffic_annotation=...) at ../../services/network/cors/cors_url_loader_factory.cc:291
#29 0xb458cb38 in network::mojom::URLLoaderFactoryStubDispatch::Accept (impl=0x9bf7dc00, message=<optimized out>) at gen/services/network/public/mojom/url_loader_factory.mojom.cc:238
#30 0xbd1622f6 in mojo::InterfaceEndpointClient::HandleValidatedMessage (this=0xa2041500, message=0xa31fab28) at ../../mojo/public/cpp/bindings/lib/interface_endpoint_client.cc:898
#31 0xbd166188 in mojo::MessageDispatcher::Accept (this=0xa20415a4, message=0xa31fab28) at ../../mojo/public/cpp/bindings/lib/message_dispatcher.cc:48
#32 0xbd162f96 in mojo::InterfaceEndpointClient::HandleIncomingMessage (this=0xa2041500, message=0xa31fab28) at ../../mojo/public/cpp/bindings/lib/interface_endpoint_client.cc:655
#33 0xbd168ac0 in mojo::internal::MultiplexRouter::ProcessIncomingMessage (this=0xa297ad00, message_wrapper=0xa31fac0c, client_call_behavior=mojo::internal::MultiplexRouter::ALLOW_DIRECT_CLIENT_CALLS, current_task_runner=<optimized out>) at ../../mojo/public/cpp/bindings/lib/multiplex_router.cc:1099
#34 0xbd1687bc in mojo::internal::MultiplexRouter::Accept (this=0xa297ad00, message=0xa31fad48) at ../../mojo/public/cpp/bindings/lib/multiplex_router.cc:719
#35 0xbd1661ae in mojo::MessageDispatcher::Accept (this=0xa297ad24, message=0xa31fad48) at ../../mojo/public/cpp/bindings/lib/message_dispatcher.cc:43
#36 0xbd15e134 in mojo::Connector::DispatchMessage (this=0xa297ad3c, message=...) at ../../mojo/public/cpp/bindings/lib/connector.cc:546
#37 0xbd15e704 in mojo::Connector::ReadAllAvailableMessages (this=0xa297ad3c) at ../../mojo/public/cpp/bindings/lib/connector.cc:604
#38 0xbd15e5e0 in mojo::Connector::OnHandleReadyInternal (this=0x9bf7dc00, result=0) at ../../mojo/public/cpp/bindings/lib/connector.cc:439
#39 0xbd15f26e in base::internal::Invoker<base::internal::BindState<void (mojo::Connector::*)(unsigned int), base::internal::UnretainedWrapper<mojo::Connector> >, void (unsigned int)>::RunImpl<void (mojo::Connector::* const&)(unsigned int), std::__Cr::tuple<base::internal::UnretainedWrapper<mojo::Connector> > const&, 0u>(void (mojo::Connector::* const&)(unsigned int), std::__Cr::tuple<base::internal::UnretainedWrapper<mojo::Connector> > const&, std::__Cr::integer_sequence<unsigned int, 0u>, unsigned int&&) (functor=@0x9bf7dc00: &virtual table offset -1113271444, bound=..., unbound_args=@0xa31f90f0: 2737913856) at ../../base/bind_internal.h:721
#40 0xbd15f260 in base::internal::Invoker<base::internal::BindState<void (mojo::Connector::*)(unsigned int), base::internal::UnretainedWrapper<mojo::Connector> >, void (unsigned int)>::Run(base::internal::BindStateBase*, unsigned int) (base=<optimized out>, unbound_args=0) at ../../base/bind_internal.h:703
#41 0xbdaf3420 in mojo::SimpleWatcher::OnHandleReady (this=0xb1bf8bf8, watch_id=<optimized out>, result=0, state=...) at ../../mojo/public/cpp/system/simple_watcher.cc:278
#42 0xbdaf378e in base::internal::InvokeHelper<true, void>::MakeItSo<void (mojo::SimpleWatcher::*)(int, unsigned int, mojo::HandleSignalsState const&), base::WeakPtr<mojo::SimpleWatcher>, int, unsigned int, mojo::HandleSignalsState> (functor=@0xa1dcf69c: (void (mojo::SimpleWatcher::*)(mojo::SimpleWatcher * const, int, unsigned int, const mojo::HandleSignalsState &)) 0xbdaf33b1 <mojo::SimpleWatcher::OnHandleReady(int, unsigned int, mojo::HandleSignalsState const&)>, weak_ptr=base::WeakPtr((uintptr_t)2982120440), args=..., args=..., args=...) at ../../base/bind_internal.h:668
#43 0xbdaf3768 in base::internal::Invoker<base::internal::BindState<void (mojo::SimpleWatcher::*)(int, unsigned int, mojo::HandleSignalsState const&), base::WeakPtr<mojo::SimpleWatcher>, int, unsigned int, mojo::HandleSignalsState>, void ()>::RunImpl<void (mojo::SimpleWatcher::*)(int, unsigned int, mojo::HandleSignalsState const&), std::__Cr::tuple<base::WeakPtr<mojo::SimpleWatcher>, int, unsigned int, mojo::HandleSignalsState>, 0u, 1u, 2u, 3u>(void (mojo::SimpleWatcher::*&&)(int, unsigned int, mojo::HandleSignalsState const&), std::__Cr::tuple<base::WeakPtr<mojo::SimpleWatcher>, int, unsigned int, mojo::HandleSignalsState>&&, std::__Cr::integer_sequence<unsigned int, 0u, 1u, 2u, 3u>) (functor=@0x9bf7dc00: &virtual table offset -1113271444, bound=...) at ../../base/bind_internal.h:721
#44 0xbdd45af0 in base::OnceCallback<void ()>::Run() && (this=<optimized out>) at ../../base/callback.h:98
#45 0xbdda24ce in base::TaskAnnotator::RunTask (this=<optimized out>, trace_event_name=<optimized out>, pending_task=0x9bf7dc00) at ../../base/task/common/task_annotator.cc:178
#46 0xbddb2362 in base::sequence_manager::internal::ThreadControllerWithMessagePumpImpl::DoWorkImpl (this=0xb0e3ba40, continuation_lazy_now=<optimized out>) at ../../base/task/sequence_manager/thread_controller_with_message_pump_impl.cc:360
#47 0xbddb2156 in base::sequence_manager::internal::ThreadControllerWithMessagePumpImpl::DoWork (this=0xb0e3ba40) at ../../base/task/sequence_manager/thread_controller_with_message_pump_impl.cc:260
#48 0xbddb2624 in non-virtual thunk to base::sequence_manager::internal::ThreadControllerWithMessagePumpImpl::DoWork() () at ../../buildtools/third_party/libc++/trunk/include/__memory/unique_ptr.h:725
#49 0xbde108f0 in base::MessagePumpLibevent::Run (this=0xb1bf69d8, delegate=0xb0e3ba44) at ../../base/message_loop/message_pump_libevent.cc:207
#50 0xbddb2808 in base::sequence_manager::internal::ThreadControllerWithMessagePumpImpl::Run (this=0xb0e3ba40, application_tasks_allowed=true, timeout=...) at ../../base/task/sequence_manager/thread_controller_with_message_pump_impl.cc:467
#51 0xbdd8bc42 in base::RunLoop::Run (this=0xa31fb1bc, location=...) at ../../base/run_loop.cc:134
#52 0xbddcd084 in base::Thread::Run (this=<optimized out>, run_loop=0x9bf7dc00) at ../../base/threading/thread.cc:341
#53 0xbddcd284 in base::Thread::ThreadMain (this=0xa9ae7148 <content::(anonymous namespace)::GetNetworkServiceDedicatedThread()::thread>) at ../../base/threading/thread.cc:412
#54 0xbdde7062 in base::(anonymous namespace)::ThreadFunc (params=<optimized out>) at ../../base/threading/platform_thread_posix.cc:95
#55 0xed42709c in __pthread_start(void*) () from /tmp/adb-gdb-support-didi/23064bed-/apex/com.android.runtime/lib/bionic/libc.so
#56 0xed3de114 in __start_thread () from /tmp/adb-gdb-support-didi/23064bed-/apex/com.android.runtime/lib/bionic/libc.so

Copy the code
int HttpCache::Transaction::Start(const HttpRequestInfo* request, CompletionOnceCallback callback, const NetLogWithSource& net_log) { ... if (! cache_.get()) return ERR_UNEXPECTED; initial_request_ = request; SetRequest(net_log); // We have to wait until the backend is initialized so we start the SM. next_state_ = STATE_GET_BACKEND; //1 int rv = DoLoop(OK); . }Copy the code

1 where the loop is turned on, the HttpCache transfer process is also the process of state changes, the so-called state machine form DoLoop comments, the description of state changes

//-----------------------------------------------------------------------------

// A few common patterns: (Foo* means Foo -> FooComplete)
//
// 1. Not-cached entry:
//   Start():
//   GetBackend* -> InitEntry -> OpenOrCreateEntry* -> AddToEntry* ->
//   SendRequest* -> SuccessfulSendRequest -> OverwriteCachedResponse ->
//   CacheWriteResponse* -> TruncateCachedData* -> PartialHeadersReceived ->
//   FinishHeaders*
//
//   Read():
//   NetworkReadCacheWrite*/CacheReadData* (if other writers are also writing to
//   the cache)
//
// 2. Cached entry, no validation:
//   Start():
//   GetBackend* -> InitEntry -> OpenOrCreateEntry* -> AddToEntry* ->
//   CacheReadResponse* -> CacheDispatchValidation ->
//   BeginPartialCacheValidation() -> BeginCacheValidation() ->
//   SetupEntryForRead() -> FinishHeaders*
//
//   Read():
//   CacheReadData*
//
// 3. Cached entry, validation (304):
//   Start():
//   GetBackend* -> InitEntry -> OpenOrCreateEntry* -> AddToEntry* ->
//   CacheReadResponse* -> CacheDispatchValidation ->
//   BeginPartialCacheValidation() -> BeginCacheValidation() -> SendRequest* ->
//   SuccessfulSendRequest -> UpdateCachedResponse -> CacheWriteUpdatedResponse*
//   -> UpdateCachedResponseComplete -> OverwriteCachedResponse ->
//   PartialHeadersReceived -> FinishHeaders*
//
//   Read():
//   CacheReadData*
//
// 4. Cached entry, validation and replace (200):
//   Start():
//   GetBackend* -> InitEntry -> OpenOrCreateEntry* -> AddToEntry* ->
//   CacheReadResponse* -> CacheDispatchValidation ->
//   BeginPartialCacheValidation() -> BeginCacheValidation() -> SendRequest* ->
//   SuccessfulSendRequest -> OverwriteCachedResponse -> CacheWriteResponse* ->
//   DoTruncateCachedData* -> PartialHeadersReceived -> FinishHeaders*
//
//   Read():
//   NetworkReadCacheWrite*/CacheReadData* (if other writers are also writing to
//   the cache)
//
// 5. Sparse entry, partially cached, byte range request:
//   Start():
//   GetBackend* -> InitEntry -> OpenOrCreateEntry* -> AddToEntry* ->
//   CacheReadResponse* -> CacheDispatchValidation ->
//   BeginPartialCacheValidation() -> CacheQueryData* ->
//   ValidateEntryHeadersAndContinue() -> StartPartialCacheValidation ->
//   CompletePartialCacheValidation -> BeginCacheValidation() -> SendRequest* ->
//   SuccessfulSendRequest -> UpdateCachedResponse -> CacheWriteUpdatedResponse*
//   -> UpdateCachedResponseComplete -> OverwriteCachedResponse ->
//   PartialHeadersReceived -> FinishHeaders*
//
//   Read() 1:
//   NetworkReadCacheWrite*
//
//   Read() 2:
//   NetworkReadCacheWrite* -> StartPartialCacheValidation ->
//   CompletePartialCacheValidation -> CacheReadData* ->
//
//   Read() 3:
//   CacheReadData* -> StartPartialCacheValidation ->
//   CompletePartialCacheValidation -> BeginCacheValidation() -> SendRequest* ->
//   SuccessfulSendRequest -> UpdateCachedResponse* -> OverwriteCachedResponse
//   -> PartialHeadersReceived -> NetworkReadCacheWrite*
//
// 6. HEAD. Not-cached entry:
//   Pass through. Don't save a HEAD by itself.
//   Start():
//   GetBackend* -> InitEntry -> OpenOrCreateEntry* -> SendRequest*
//
// 7. HEAD. Cached entry, no validation:
//   Start():
//   The same flow as for a GET request (example #2)
//
//   Read():
//   CacheReadData (returns 0)
//
// 8. HEAD. Cached entry, validation (304):
//   The request updates the stored headers.
//   Start(): Same as for a GET request (example #3)
//
//   Read():
//   CacheReadData (returns 0)
//
// 9. HEAD. Cached entry, validation and replace (200):
//   Pass through. The request dooms the old entry, as a HEAD won't be stored by
//   itself.
//   Start():
//   GetBackend* -> InitEntry -> OpenOrCreateEntry* -> AddToEntry* ->
//   CacheReadResponse* -> CacheDispatchValidation ->
//   BeginPartialCacheValidation() -> BeginCacheValidation() -> SendRequest* ->
//   SuccessfulSendRequest -> OverwriteCachedResponse -> FinishHeaders*
//
// 10. HEAD. Sparse entry, partially cached:
//   Serve the request from the cache, as long as it doesn't require
//   revalidation. Ignore missing ranges when deciding to revalidate. If the
//   entry requires revalidation, ignore the whole request and go to full pass
//   through (the result of the HEAD request will NOT update the entry).
//
//   Start(): Basically the same as example 7, as we never create a partial_
//   object for this request.
//
// 11. Prefetch, not-cached entry:
//   The same as example 1. The "unused_since_prefetch" bit is stored as true in
//   UpdateCachedResponse.
//
// 12. Prefetch, cached entry:
//   Like examples 2-4, only CacheWriteUpdatedPrefetchResponse* is inserted
//   between CacheReadResponse* and CacheDispatchValidation if the
//   unused_since_prefetch bit is unset.
//
// 13. Cached entry less than 5 minutes old, unused_since_prefetch is true:
//   Skip validation, similar to example 2.
//   GetBackend* -> InitEntry -> OpenOrCreateEntry* -> AddToEntry* ->
//   CacheReadResponse* -> CacheToggleUnusedSincePrefetch* ->
//   CacheDispatchValidation -> BeginPartialCacheValidation() ->
//   BeginCacheValidation() -> SetupEntryForRead() -> FinishHeaders*
//
//   Read():
//   CacheReadData*
//
// 14. Cached entry more than 5 minutes old, unused_since_prefetch is true:
//   Like examples 2-4, only CacheToggleUnusedSincePrefetch* is inserted between
//   CacheReadResponse* and CacheDispatchValidation.

Copy the code

Next, we’ll probably go through the noCache link

/ / nocache state machine request part int HttpCache: : Transaction: : DoLoop (int result) {do {state = next_state_; switch (state) { case STATE_GET_BACKEND: DCHECK_EQ(OK, rv); rv = DoGetBackend(); break; case STATE_INIT_ENTRY: DCHECK_EQ(OK, rv); rv = DoInitEntry(); break; case STATE_OPEN_OR_CREATE_ENTRY: DCHECK_EQ(OK, rv); rv = DoOpenOrCreateEntry(); break; case STATE_ADD_TO_ENTRY: DCHECK_EQ(OK, rv); rv = DoAddToEntry(); break; case STATE_SEND_REQUEST: DCHECK_EQ(OK, rv); rv = DoSendRequest(); break; case STATE_SUCCESSFUL_SEND_REQUEST: DCHECK_EQ(OK, rv); rv = DoSuccessfulSendRequest(); break; case STATE_OVERWRITE_CACHED_RESPONSE: DCHECK_EQ(OK, rv); rv = DoOverwriteCachedResponse(); break; case STATE_CACHE_WRITE_RESPONSE: DCHECK_EQ(OK, rv); rv = DoCacheWriteResponse(); break; case STATE_TRUNCATE_CACHED_DATA: DCHECK_EQ(OK, rv); rv = DoTruncateCachedData(); break; case STATE_PARTIAL_HEADERS_RECEIVED: DCHECK_EQ(OK, rv); rv = DoPartialHeadersReceived(); break; case STATE_FINISH_HEADERS: rv = DoFinishHeaders(rv); break; . }while (rv ! = ERR_IO_PENDING && next_state_ ! = STATE_NONE); }Copy the code

GetBackend, obtaining Disk_cache (local persistence implementation of Backend)

int HttpCache::Transaction::DoGetBackend() {
  cache_pending_ = true;
  TransitionToState(STATE_GET_BACKEND_COMPLETE);
  net_log_.BeginEvent(NetLogEventType::HTTP_CACHE_GET_BACKEND);
  return cache_->GetBackendForTransaction(this);
}
Copy the code

DoInitEntry (toggle state)

int HttpCache::Transaction::DoInitEntry() { ... if (mode_ == WRITE) { TransitionToState(STATE_DOOM_ENTRY); return OK; } // Switch to DoOpenOrCreateEntry TransitionToState(STATE_OPEN_OR_CREATE_ENTRY); return OK; }Copy the code

DoOpenOrCreateEntry(create a cache instance Entry)

Int HttpCache: : Transaction: : DoOpenOrCreateEntry () {/ / try to gain entry new_entry_ = cache_ - > FindActiveEntry (cache_key_); if (new_entry_) return OK; . Return cache_->OpenOrCreateEntry(cache_KEY_, &new_entry_, this); return cache_->OpenOrCreateEntry(cache_KEY_, &new_entry_, this); }Copy the code

Print the contents of cache_KEY_DoAddToEntry (set entry)

int HttpCache::Transaction::DoAddToEntry() {
  ...
  int rv = cache_->AddTransactionToEntry(new_entry_, this);
  DCHECK_EQ(rv, ERR_IO_PENDING);

  // If headers phase is already done then we are here because of validation not
  // matching and creating a new entry. This transaction should be the
  // first transaction of that new entry and thus it will not have cache lock
  // delays, thus returning early from here.
  if (done_headers_create_new_entry_) {
    DCHECK_EQ(mode_, WRITE);
    TransitionToState(STATE_DONE_HEADERS_ADD_TO_ENTRY_COMPLETE);
    return rv;
  }

  TransitionToState(STATE_ADD_TO_ENTRY_COMPLETE);

  entry_lock_waiting_since_ = TimeTicks::Now();
  AddCacheLockTimeoutHandler(new_entry_);
  return rv;
}

Copy the code

DoSendRequest Sends a request

int HttpCache::Transaction::DoSendRequest() { send_request_since_ = TimeTicks::Now(); // Create a network transaction. int rv = cache_->network_layer_->CreateTransaction(priority_, &network_trans_); / / set a callback network_trans_ - > SetBeforeNetworkStartCallback (STD: : move (before_network_start_callback_)); network_trans_->SetConnectedCallback(connected_callback_); network_trans_->SetRequestHeadersCallback(request_headers_callback_); network_trans_->SetEarlyResponseHeadersCallback( early_response_headers_callback_); network_trans_->SetResponseHeadersCallback(response_headers_callback_); // Old load timing information, if any, is now obsolete. network_transaction_info_.old_network_trans_load_timing.reset(); network_transaction_info_.old_remote_endpoint = IPEndPoint(); if (websocket_handshake_stream_base_create_helper_) network_trans_->SetWebSocketHandshakeStreamCreateHelper( websocket_handshake_stream_base_create_helper_); TransitionToState(STATE_SEND_REQUEST_COMPLETE); Rv = network_trans_->Start(request_, io_callback_, net_log_); return rv; }Copy the code

DoSuccessfulSendRequest

// We received the response headers and there is no error. int HttpCache::Transaction::DoSuccessfulSendRequest() { TRACE_EVENT0("io", "HttpCacheTransaction::DoSuccessfulSendRequest"); DCHECK(! new_response_); const HttpResponseInfo* new_response = network_trans_->GetResponseInfo(); if (new_response->headers->response_code() == 401 || new_response->headers->response_code() == 407) { SetAuthResponse(*new_response); if (! reading_) { TransitionToState(STATE_FINISH_HEADERS); return OK; } new_response_ = new_response; if (handling_206_ && mode_ == READ_WRITE && ! truncated_ && ! is_sparse_) { // We have stored the full entry, but it changed and the server is // sending a range. We have to delete the old entry. UpdateCacheEntryStatus(CacheEntryStatus::ENTRY_OTHER); DoneWithEntry(false); } if (mode_ == WRITE && cache_entry_status_ ! = CacheEntryStatus::ENTRY_CANT_CONDITIONALIZE) { UpdateCacheEntryStatus(CacheEntryStatus::ENTRY_NOT_IN_CACHE); } // Invalidate any cached GET with a successful PUT, DELETE, or PATCH. if (mode_ == WRITE && (method_ == "PUT" || method_ == "DELETE" || method_ == "PATCH")) { if (NonErrorResponse(new_response_->headers->response_code()) && (entry_ && ! entry_->doomed)) { int ret = cache_->DoomEntry(cache_key_, nullptr); DCHECK_EQ(OK, ret); } // Do not invalidate the entry if the request failed. DoneWithEntry(true); } // Invalidate any cached GET with a successful POST. If the network isolation // key isn't populated with the split cache active, there will be nothing to // invalidate in the cache. if (! (effective_load_flags_ & LOAD_DISABLE_CACHE) && method_ == "POST" && NonErrorResponse(new_response_->headers->response_code()) && (! HttpCache::IsSplitCacheEnabled() || request_->network_isolation_key.IsFullyPopulated())) { cache_->DoomMainEntryForUrl(request_->url, request_->network_isolation_key, request_->is_subframe_document_resource); } RecordNoStoreHeaderHistogram(request_->load_flags, new_response_); if (new_response_->headers->response_code() == 416 && (method_ == "GET" || method_ == "POST")) { // If there is an active entry it may be destroyed with this transaction. SetResponse(*new_response_); TransitionToState(STATE_FINISH_HEADERS); return OK; } // Are we expecting a response to a conditional query? if (mode_ == READ_WRITE || mode_ == UPDATE) { if (new_response->headers->response_code() == 304 || handling_206_) { UpdateCacheEntryStatus(CacheEntryStatus::ENTRY_VALIDATED); TransitionToState(STATE_UPDATE_CACHED_RESPONSE); return OK; } UpdateCacheEntryStatus(CacheEntryStatus::ENTRY_UPDATED); mode_ = WRITE; } TransitionToState(STATE_OVERWRITE_CACHED_RESPONSE); return OK; }Copy the code

DoCacheWriteResponse (Response persistence)

int HttpCache::Transaction::DoCacheWriteResponse() { TRACE_EVENT0("io", "HttpCacheTransaction::DoCacheWriteResponse"); TransitionToState(STATE_CACHE_WRITE_RESPONSE_COMPLETE); Response return WriteResponseInfoToEntry(response_, truncated_); } int HttpCache::Transaction::WriteResponseInfoToEntry(bool truncated) { ... Do not cache no-store content. Do not cache content with cert errors // either. This is to prevent not reporting  net errors when loading a // resource from the cache. When we load a page over HTTPS with a cert error // we show an SSL blocking page. If the user clicks proceed we reload the // resource ignoring the errors. The loaded resource is then  cached. If that // resource is subsequently loaded from the cache, no net error is reported // (even though the cert status contains the actual errors) and no SSL // blocking page is shown. An alternative would be to reverse-map the cert // status to a net error and replay the net error. if ((response.headers->HasHeaderValue("cache-control", "no-store")) || IsCertStatusError(response.ssl_info.cert_status) || ShouldDisableCaching(response.headers.get())) { if (partial_) partial_->FixResponseHeaders(response_.headers.get(), true); bool stopped = StopCachingImpl(false); DCHECK(stopped); if (net_log_.IsCapturing()) net_log_.EndEvent(NetLogEventType::HTTP_CACHE_WRITE_INFO); return OK; } io_buf_len_ = data->pickle()->size(); Return entry_->disk_entry->WriteData(kResponseInfoIndex, 0, data.get(), io_buf_len_, io_callback_, true); } int SimpleEntryImpl::WriteData(int stream_index, int offset, net::IOBuffer* buf, int buf_len, CompletionOnceCallback callback, bool truncate) { ... // Write data, Default Max cache size 209715200 // Stream 0 data is kept in memory, so can be written immediatly if there are // no IO operations pending. if (stream_index == 0 && state_ == STATE_READY &&  pending_operations_.size() == 0) return SetStream0Data(buf, offset, buf_len, truncate); . }Copy the code

An HttpCache::Transaction corresponds to the processing of a request, and the entire network request process is implemented internally through a state switch.