4972460486def3d99b6ff84584374fbf4d8296bc
[WebKit-https.git] / Source / WebCore / inspector / agents / InspectorApplicationCacheAgent.cpp
1 /*
2  * Copyright (C) 2010, 2015 Apple Inc. All rights reserved.
3  * Copyright (C) 2010 Google Inc. All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1.  Redistributions of source code must retain the above copyright
9  *     notice, this list of conditions and the following disclaimer.
10  * 2.  Redistributions in binary form must reproduce the above copyright
11  *     notice, this list of conditions and the following disclaimer in the
12  *     documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
15  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
16  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
17  * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
18  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
19  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
20  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
21  * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
23  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #include "config.h"
27 #include "InspectorApplicationCacheAgent.h"
28
29 #include "ApplicationCacheHost.h"
30 #include "DocumentLoader.h"
31 #include "Frame.h"
32 #include "FrameLoader.h"
33 #include "InspectorPageAgent.h"
34 #include "InstrumentingAgents.h"
35 #include "LoaderStrategy.h"
36 #include "Page.h"
37 #include "PlatformStrategies.h"
38 #include <wtf/text/StringBuilder.h>
39
40 namespace WebCore {
41
42 using namespace Inspector;
43
44 InspectorApplicationCacheAgent::InspectorApplicationCacheAgent(PageAgentContext& context)
45     : InspectorAgentBase("ApplicationCache"_s, context)
46     , m_frontendDispatcher(std::make_unique<Inspector::ApplicationCacheFrontendDispatcher>(context.frontendRouter))
47     , m_backendDispatcher(Inspector::ApplicationCacheBackendDispatcher::create(context.backendDispatcher, this))
48     , m_inspectedPage(context.inspectedPage)
49 {
50 }
51
52 void InspectorApplicationCacheAgent::didCreateFrontendAndBackend(FrontendRouter*, BackendDispatcher*)
53 {
54 }
55
56 void InspectorApplicationCacheAgent::willDestroyFrontendAndBackend(Inspector::DisconnectReason)
57 {
58     m_instrumentingAgents.setInspectorApplicationCacheAgent(nullptr);
59 }
60
61 void InspectorApplicationCacheAgent::enable(ErrorString&)
62 {
63     m_instrumentingAgents.setInspectorApplicationCacheAgent(this);
64
65     // We need to pass initial navigator.onOnline.
66     networkStateChanged();
67 }
68
69 void InspectorApplicationCacheAgent::updateApplicationCacheStatus(Frame* frame)
70 {
71     auto* pageAgent = m_instrumentingAgents.inspectorPageAgent();
72     if (!pageAgent)
73         return;
74
75     if (!frame)
76         return;
77
78     auto* documentLoader = frame->loader().documentLoader();
79     if (!documentLoader)
80         return;
81
82     auto& host = documentLoader->applicationCacheHost();
83     int status = host.status();
84     auto manifestURL = host.applicationCacheInfo().manifest.string();
85
86     m_frontendDispatcher->applicationCacheStatusUpdated(pageAgent->frameId(frame), manifestURL, status);
87 }
88
89 void InspectorApplicationCacheAgent::networkStateChanged()
90 {
91     m_frontendDispatcher->networkStateUpdated(platformStrategies()->loaderStrategy()->isOnLine());
92 }
93
94 void InspectorApplicationCacheAgent::getFramesWithManifests(ErrorString&, RefPtr<JSON::ArrayOf<Inspector::Protocol::ApplicationCache::FrameWithManifest>>& result)
95 {
96     result = JSON::ArrayOf<Inspector::Protocol::ApplicationCache::FrameWithManifest>::create();
97
98     auto* pageAgent = m_instrumentingAgents.inspectorPageAgent();
99
100     for (Frame* frame = &m_inspectedPage.mainFrame(); frame; frame = frame->tree().traverseNext()) {
101         auto* documentLoader = frame->loader().documentLoader();
102         if (!documentLoader)
103             continue;
104
105         auto& host = documentLoader->applicationCacheHost();
106         String manifestURL = host.applicationCacheInfo().manifest.string();
107         if (!manifestURL.isEmpty()) {
108             result->addItem(Inspector::Protocol::ApplicationCache::FrameWithManifest::create()
109                 .setFrameId(pageAgent->frameId(frame))
110                 .setManifestURL(manifestURL)
111                 .setStatus(static_cast<int>(host.status()))
112                 .release());
113         }
114     }
115 }
116
117 DocumentLoader* InspectorApplicationCacheAgent::assertFrameWithDocumentLoader(ErrorString& errorString, const String& frameId)
118 {
119     auto* pageAgent = m_instrumentingAgents.inspectorPageAgent();
120     if (!pageAgent) {
121         errorString = "Missing Page agent"_s;
122         return nullptr;
123     }
124
125     Frame* frame = pageAgent->assertFrame(errorString, frameId);
126     if (!frame)
127         return nullptr;
128
129     return InspectorPageAgent::assertDocumentLoader(errorString, frame);
130 }
131
132 void InspectorApplicationCacheAgent::getManifestForFrame(ErrorString& errorString, const String& frameId, String* manifestURL)
133 {
134     DocumentLoader* documentLoader = assertFrameWithDocumentLoader(errorString, frameId);
135     if (!documentLoader)
136         return;
137
138     *manifestURL = documentLoader->applicationCacheHost().applicationCacheInfo().manifest.string();
139 }
140
141 void InspectorApplicationCacheAgent::getApplicationCacheForFrame(ErrorString& errorString, const String& frameId, RefPtr<Inspector::Protocol::ApplicationCache::ApplicationCache>& applicationCache)
142 {
143     auto* documentLoader = assertFrameWithDocumentLoader(errorString, frameId);
144     if (!documentLoader)
145         return;
146
147     auto& host = documentLoader->applicationCacheHost();
148     applicationCache = buildObjectForApplicationCache(host.resourceList(), host.applicationCacheInfo());
149 }
150
151 Ref<Inspector::Protocol::ApplicationCache::ApplicationCache> InspectorApplicationCacheAgent::buildObjectForApplicationCache(const Vector<ApplicationCacheHost::ResourceInfo>& applicationCacheResources, const ApplicationCacheHost::CacheInfo& applicationCacheInfo)
152 {
153     return Inspector::Protocol::ApplicationCache::ApplicationCache::create()
154         .setManifestURL(applicationCacheInfo.manifest.string())
155         .setSize(applicationCacheInfo.size)
156         .setCreationTime(applicationCacheInfo.creationTime)
157         .setUpdateTime(applicationCacheInfo.updateTime)
158         .setResources(buildArrayForApplicationCacheResources(applicationCacheResources))
159         .release();
160 }
161
162 Ref<JSON::ArrayOf<Inspector::Protocol::ApplicationCache::ApplicationCacheResource>> InspectorApplicationCacheAgent::buildArrayForApplicationCacheResources(const Vector<ApplicationCacheHost::ResourceInfo>& applicationCacheResources)
163 {
164     auto result = JSON::ArrayOf<Inspector::Protocol::ApplicationCache::ApplicationCacheResource>::create();
165     for (auto& info : applicationCacheResources)
166         result->addItem(buildObjectForApplicationCacheResource(info));
167     return result;
168 }
169
170 Ref<Inspector::Protocol::ApplicationCache::ApplicationCacheResource> InspectorApplicationCacheAgent::buildObjectForApplicationCacheResource(const ApplicationCacheHost::ResourceInfo& resourceInfo)
171 {
172     StringBuilder types;
173
174     if (resourceInfo.isMaster)
175         types.appendLiteral("Master ");
176
177     if (resourceInfo.isManifest)
178         types.appendLiteral("Manifest ");
179
180     if (resourceInfo.isFallback)
181         types.appendLiteral("Fallback ");
182
183     if (resourceInfo.isForeign)
184         types.appendLiteral("Foreign ");
185
186     if (resourceInfo.isExplicit)
187         types.appendLiteral("Explicit ");
188
189     return Inspector::Protocol::ApplicationCache::ApplicationCacheResource::create()
190         .setUrl(resourceInfo.resource.string())
191         .setSize(static_cast<int>(resourceInfo.size))
192         .setType(types.toString())
193         .release();
194 }
195
196 } // namespace WebCore