fdf044c579b368c32051b65dc440e387f6018fb7
[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 "CustomHeaderFields.h"
31 #include "DocumentLoader.h"
32 #include "Frame.h"
33 #include "FrameLoader.h"
34 #include "InspectorPageAgent.h"
35 #include "InstrumentingAgents.h"
36 #include "LoaderStrategy.h"
37 #include "Page.h"
38 #include "PlatformStrategies.h"
39 #include <wtf/text/StringBuilder.h>
40
41 namespace WebCore {
42
43 using namespace Inspector;
44
45 InspectorApplicationCacheAgent::InspectorApplicationCacheAgent(PageAgentContext& context)
46     : InspectorAgentBase("ApplicationCache"_s, context)
47     , m_frontendDispatcher(makeUnique<Inspector::ApplicationCacheFrontendDispatcher>(context.frontendRouter))
48     , m_backendDispatcher(Inspector::ApplicationCacheBackendDispatcher::create(context.backendDispatcher, this))
49     , m_inspectedPage(context.inspectedPage)
50 {
51 }
52
53 void InspectorApplicationCacheAgent::didCreateFrontendAndBackend(FrontendRouter*, BackendDispatcher*)
54 {
55 }
56
57 void InspectorApplicationCacheAgent::willDestroyFrontendAndBackend(Inspector::DisconnectReason)
58 {
59     ErrorString unused;
60     disable(unused);
61 }
62
63 void InspectorApplicationCacheAgent::enable(ErrorString& errorString)
64 {
65     if (m_instrumentingAgents.inspectorApplicationCacheAgent() == this) {
66         errorString = "ApplicationCacheAgent already enabled"_s;
67         return;
68     }
69
70     m_instrumentingAgents.setInspectorApplicationCacheAgent(this);
71
72     // We need to pass initial navigator.onOnline.
73     networkStateChanged();
74 }
75
76 void InspectorApplicationCacheAgent::disable(ErrorString& errorString)
77 {
78     if (m_instrumentingAgents.inspectorApplicationCacheAgent() != this) {
79         errorString = "ApplicationCacheAgent already disabled"_s;
80         return;
81     }
82
83     m_instrumentingAgents.setInspectorApplicationCacheAgent(nullptr);
84 }
85
86 void InspectorApplicationCacheAgent::updateApplicationCacheStatus(Frame* frame)
87 {
88     if (!frame)
89         return;
90
91     auto* documentLoader = frame->loader().documentLoader();
92     if (!documentLoader)
93         return;
94
95     auto& host = documentLoader->applicationCacheHost();
96     int status = host.status();
97     auto manifestURL = host.applicationCacheInfo().manifest.string();
98
99     m_frontendDispatcher->applicationCacheStatusUpdated(m_instrumentingAgents.inspectorPageAgent()->frameId(frame), manifestURL, status);
100 }
101
102 void InspectorApplicationCacheAgent::networkStateChanged()
103 {
104     m_frontendDispatcher->networkStateUpdated(platformStrategies()->loaderStrategy()->isOnLine());
105 }
106
107 void InspectorApplicationCacheAgent::getFramesWithManifests(ErrorString&, RefPtr<JSON::ArrayOf<Inspector::Protocol::ApplicationCache::FrameWithManifest>>& result)
108 {
109     result = JSON::ArrayOf<Inspector::Protocol::ApplicationCache::FrameWithManifest>::create();
110
111     for (Frame* frame = &m_inspectedPage.mainFrame(); frame; frame = frame->tree().traverseNext()) {
112         auto* documentLoader = frame->loader().documentLoader();
113         if (!documentLoader)
114             continue;
115
116         auto& host = documentLoader->applicationCacheHost();
117         String manifestURL = host.applicationCacheInfo().manifest.string();
118         if (!manifestURL.isEmpty()) {
119             result->addItem(Inspector::Protocol::ApplicationCache::FrameWithManifest::create()
120                 .setFrameId(m_instrumentingAgents.inspectorPageAgent()->frameId(frame))
121                 .setManifestURL(manifestURL)
122                 .setStatus(static_cast<int>(host.status()))
123                 .release());
124         }
125     }
126 }
127
128 DocumentLoader* InspectorApplicationCacheAgent::assertFrameWithDocumentLoader(ErrorString& errorString, const String& frameId)
129 {
130     Frame* frame = m_instrumentingAgents.inspectorPageAgent()->assertFrame(errorString, frameId);
131     if (!frame)
132         return nullptr;
133
134     return InspectorPageAgent::assertDocumentLoader(errorString, frame);
135 }
136
137 void InspectorApplicationCacheAgent::getManifestForFrame(ErrorString& errorString, const String& frameId, String* manifestURL)
138 {
139     DocumentLoader* documentLoader = assertFrameWithDocumentLoader(errorString, frameId);
140     if (!documentLoader)
141         return;
142
143     *manifestURL = documentLoader->applicationCacheHost().applicationCacheInfo().manifest.string();
144 }
145
146 void InspectorApplicationCacheAgent::getApplicationCacheForFrame(ErrorString& errorString, const String& frameId, RefPtr<Inspector::Protocol::ApplicationCache::ApplicationCache>& applicationCache)
147 {
148     auto* documentLoader = assertFrameWithDocumentLoader(errorString, frameId);
149     if (!documentLoader)
150         return;
151
152     auto& host = documentLoader->applicationCacheHost();
153     applicationCache = buildObjectForApplicationCache(host.resourceList(), host.applicationCacheInfo());
154 }
155
156 Ref<Inspector::Protocol::ApplicationCache::ApplicationCache> InspectorApplicationCacheAgent::buildObjectForApplicationCache(const Vector<ApplicationCacheHost::ResourceInfo>& applicationCacheResources, const ApplicationCacheHost::CacheInfo& applicationCacheInfo)
157 {
158     return Inspector::Protocol::ApplicationCache::ApplicationCache::create()
159         .setManifestURL(applicationCacheInfo.manifest.string())
160         .setSize(applicationCacheInfo.size)
161         .setCreationTime(applicationCacheInfo.creationTime)
162         .setUpdateTime(applicationCacheInfo.updateTime)
163         .setResources(buildArrayForApplicationCacheResources(applicationCacheResources))
164         .release();
165 }
166
167 Ref<JSON::ArrayOf<Inspector::Protocol::ApplicationCache::ApplicationCacheResource>> InspectorApplicationCacheAgent::buildArrayForApplicationCacheResources(const Vector<ApplicationCacheHost::ResourceInfo>& applicationCacheResources)
168 {
169     auto result = JSON::ArrayOf<Inspector::Protocol::ApplicationCache::ApplicationCacheResource>::create();
170     for (auto& info : applicationCacheResources)
171         result->addItem(buildObjectForApplicationCacheResource(info));
172     return result;
173 }
174
175 Ref<Inspector::Protocol::ApplicationCache::ApplicationCacheResource> InspectorApplicationCacheAgent::buildObjectForApplicationCacheResource(const ApplicationCacheHost::ResourceInfo& resourceInfo)
176 {
177     StringBuilder types;
178
179     if (resourceInfo.isMaster)
180         types.appendLiteral("Master ");
181
182     if (resourceInfo.isManifest)
183         types.appendLiteral("Manifest ");
184
185     if (resourceInfo.isFallback)
186         types.appendLiteral("Fallback ");
187
188     if (resourceInfo.isForeign)
189         types.appendLiteral("Foreign ");
190
191     if (resourceInfo.isExplicit)
192         types.appendLiteral("Explicit ");
193
194     return Inspector::Protocol::ApplicationCache::ApplicationCacheResource::create()
195         .setUrl(resourceInfo.resource.string())
196         .setSize(static_cast<int>(resourceInfo.size))
197         .setType(types.toString())
198         .release();
199 }
200
201 } // namespace WebCore