1 /*
2 * Copyright (C) 2010 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 "core/inspector/InspectorApplicationCacheAgent.h"
28
29 #include "core/inspector/InspectorPageAgent.h"
30 #include "core/inspector/InspectorState.h"
31 #include "core/inspector/InstrumentingAgents.h"
32 #include "core/loader/DocumentLoader.h"
33 #include "core/loader/FrameLoader.h"
34 #include "core/frame/Frame.h"
35 #include "core/page/NetworkStateNotifier.h"
36 #include "wtf/text/StringBuilder.h"
37
38 namespace WebCore {
39
40 namespace ApplicationCacheAgentState {
41 static const char applicationCacheAgentEnabled[] = "applicationCacheAgentEnabled";
42 }
43
InspectorApplicationCacheAgent(InstrumentingAgents * instrumentingAgents,InspectorCompositeState * state,InspectorPageAgent * pageAgent)44 InspectorApplicationCacheAgent::InspectorApplicationCacheAgent(InstrumentingAgents* instrumentingAgents, InspectorCompositeState* state, InspectorPageAgent* pageAgent)
45 : InspectorBaseAgent<InspectorApplicationCacheAgent>("ApplicationCache", instrumentingAgents, state)
46 , m_pageAgent(pageAgent)
47 , m_frontend(0)
48 {
49 }
50
setFrontend(InspectorFrontend * frontend)51 void InspectorApplicationCacheAgent::setFrontend(InspectorFrontend* frontend)
52 {
53 m_frontend = frontend->applicationcache();
54 }
55
clearFrontend()56 void InspectorApplicationCacheAgent::clearFrontend()
57 {
58 m_instrumentingAgents->setInspectorApplicationCacheAgent(0);
59 m_frontend = 0;
60 }
61
restore()62 void InspectorApplicationCacheAgent::restore()
63 {
64 if (m_state->getBoolean(ApplicationCacheAgentState::applicationCacheAgentEnabled)) {
65 ErrorString error;
66 enable(&error);
67 }
68 }
69
enable(ErrorString *)70 void InspectorApplicationCacheAgent::enable(ErrorString*)
71 {
72 m_state->setBoolean(ApplicationCacheAgentState::applicationCacheAgentEnabled, true);
73 m_instrumentingAgents->setInspectorApplicationCacheAgent(this);
74
75 // We need to pass initial navigator.onOnline.
76 networkStateChanged(networkStateNotifier().onLine());
77 }
78
updateApplicationCacheStatus(Frame * frame)79 void InspectorApplicationCacheAgent::updateApplicationCacheStatus(Frame* frame)
80 {
81 DocumentLoader* documentLoader = frame->loader().documentLoader();
82 if (!documentLoader)
83 return;
84
85 ApplicationCacheHost* host = documentLoader->applicationCacheHost();
86 ApplicationCacheHost::Status status = host->status();
87 ApplicationCacheHost::CacheInfo info = host->applicationCacheInfo();
88
89 String manifestURL = info.m_manifest.string();
90 m_frontend->applicationCacheStatusUpdated(m_pageAgent->frameId(frame), manifestURL, static_cast<int>(status));
91 }
92
networkStateChanged(bool online)93 void InspectorApplicationCacheAgent::networkStateChanged(bool online)
94 {
95 m_frontend->networkStateUpdated(online);
96 }
97
getFramesWithManifests(ErrorString *,RefPtr<TypeBuilder::Array<TypeBuilder::ApplicationCache::FrameWithManifest>> & result)98 void InspectorApplicationCacheAgent::getFramesWithManifests(ErrorString*, RefPtr<TypeBuilder::Array<TypeBuilder::ApplicationCache::FrameWithManifest> >& result)
99 {
100 result = TypeBuilder::Array<TypeBuilder::ApplicationCache::FrameWithManifest>::create();
101
102 Frame* mainFrame = m_pageAgent->mainFrame();
103 for (Frame* frame = mainFrame; frame; frame = frame->tree().traverseNext(mainFrame)) {
104 DocumentLoader* documentLoader = frame->loader().documentLoader();
105 if (!documentLoader)
106 continue;
107
108 ApplicationCacheHost* host = documentLoader->applicationCacheHost();
109 ApplicationCacheHost::CacheInfo info = host->applicationCacheInfo();
110 String manifestURL = info.m_manifest.string();
111 if (!manifestURL.isEmpty()) {
112 RefPtr<TypeBuilder::ApplicationCache::FrameWithManifest> value = TypeBuilder::ApplicationCache::FrameWithManifest::create()
113 .setFrameId(m_pageAgent->frameId(frame))
114 .setManifestURL(manifestURL)
115 .setStatus(static_cast<int>(host->status()));
116 result->addItem(value);
117 }
118 }
119 }
120
assertFrameWithDocumentLoader(ErrorString * errorString,String frameId)121 DocumentLoader* InspectorApplicationCacheAgent::assertFrameWithDocumentLoader(ErrorString* errorString, String frameId)
122 {
123 Frame* frame = m_pageAgent->assertFrame(errorString, frameId);
124 if (!frame)
125 return 0;
126
127 return InspectorPageAgent::assertDocumentLoader(errorString, frame);
128 }
129
getManifestForFrame(ErrorString * errorString,const String & frameId,String * manifestURL)130 void InspectorApplicationCacheAgent::getManifestForFrame(ErrorString* errorString, const String& frameId, String* manifestURL)
131 {
132 DocumentLoader* documentLoader = assertFrameWithDocumentLoader(errorString, frameId);
133 if (!documentLoader)
134 return;
135
136 ApplicationCacheHost::CacheInfo info = documentLoader->applicationCacheHost()->applicationCacheInfo();
137 *manifestURL = info.m_manifest.string();
138 }
139
getApplicationCacheForFrame(ErrorString * errorString,const String & frameId,RefPtr<TypeBuilder::ApplicationCache::ApplicationCache> & applicationCache)140 void InspectorApplicationCacheAgent::getApplicationCacheForFrame(ErrorString* errorString, const String& frameId, RefPtr<TypeBuilder::ApplicationCache::ApplicationCache>& applicationCache)
141 {
142 DocumentLoader* documentLoader = assertFrameWithDocumentLoader(errorString, frameId);
143 if (!documentLoader)
144 return;
145
146 ApplicationCacheHost* host = documentLoader->applicationCacheHost();
147 ApplicationCacheHost::CacheInfo info = host->applicationCacheInfo();
148
149 ApplicationCacheHost::ResourceInfoList resources;
150 host->fillResourceList(&resources);
151
152 applicationCache = buildObjectForApplicationCache(resources, info);
153 }
154
buildObjectForApplicationCache(const ApplicationCacheHost::ResourceInfoList & applicationCacheResources,const ApplicationCacheHost::CacheInfo & applicationCacheInfo)155 PassRefPtr<TypeBuilder::ApplicationCache::ApplicationCache> InspectorApplicationCacheAgent::buildObjectForApplicationCache(const ApplicationCacheHost::ResourceInfoList& applicationCacheResources, const ApplicationCacheHost::CacheInfo& applicationCacheInfo)
156 {
157 return TypeBuilder::ApplicationCache::ApplicationCache::create()
158 .setManifestURL(applicationCacheInfo.m_manifest.string())
159 .setSize(applicationCacheInfo.m_size)
160 .setCreationTime(applicationCacheInfo.m_creationTime)
161 .setUpdateTime(applicationCacheInfo.m_updateTime)
162 .setResources(buildArrayForApplicationCacheResources(applicationCacheResources))
163 .release();
164 }
165
buildArrayForApplicationCacheResources(const ApplicationCacheHost::ResourceInfoList & applicationCacheResources)166 PassRefPtr<TypeBuilder::Array<TypeBuilder::ApplicationCache::ApplicationCacheResource> > InspectorApplicationCacheAgent::buildArrayForApplicationCacheResources(const ApplicationCacheHost::ResourceInfoList& applicationCacheResources)
167 {
168 RefPtr<TypeBuilder::Array<TypeBuilder::ApplicationCache::ApplicationCacheResource> > resources = TypeBuilder::Array<TypeBuilder::ApplicationCache::ApplicationCacheResource>::create();
169
170 ApplicationCacheHost::ResourceInfoList::const_iterator end = applicationCacheResources.end();
171 ApplicationCacheHost::ResourceInfoList::const_iterator it = applicationCacheResources.begin();
172 for (int i = 0; it != end; ++it, i++)
173 resources->addItem(buildObjectForApplicationCacheResource(*it));
174
175 return resources;
176 }
177
buildObjectForApplicationCacheResource(const ApplicationCacheHost::ResourceInfo & resourceInfo)178 PassRefPtr<TypeBuilder::ApplicationCache::ApplicationCacheResource> InspectorApplicationCacheAgent::buildObjectForApplicationCacheResource(const ApplicationCacheHost::ResourceInfo& resourceInfo)
179 {
180 StringBuilder builder;
181 if (resourceInfo.m_isMaster)
182 builder.append("Master ");
183
184 if (resourceInfo.m_isManifest)
185 builder.append("Manifest ");
186
187 if (resourceInfo.m_isFallback)
188 builder.append("Fallback ");
189
190 if (resourceInfo.m_isForeign)
191 builder.append("Foreign ");
192
193 if (resourceInfo.m_isExplicit)
194 builder.append("Explicit ");
195
196 RefPtr<TypeBuilder::ApplicationCache::ApplicationCacheResource> value = TypeBuilder::ApplicationCache::ApplicationCacheResource::create()
197 .setUrl(resourceInfo.m_resource.string())
198 .setSize(static_cast<int>(resourceInfo.m_size))
199 .setType(builder.toString());
200 return value;
201 }
202
203 } // namespace WebCore
204
205