1// Copyright 2014 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "config.h"
6#include "bindings/core/v8/V8DOMActivityLogger.h"
7
8#include "bindings/core/v8/V8Binding.h"
9#include "platform/weborigin/KURL.h"
10#include "wtf/HashMap.h"
11#include "wtf/MainThread.h"
12#include "wtf/text/StringHash.h"
13
14namespace blink {
15
16typedef HashMap<String, OwnPtr<V8DOMActivityLogger> > DOMActivityLoggerMapForMainWorld;
17typedef HashMap<int, OwnPtr<V8DOMActivityLogger>, WTF::IntHash<int>, WTF::UnsignedWithZeroKeyHashTraits<int> > DOMActivityLoggerMapForIsolatedWorld;
18
19static DOMActivityLoggerMapForMainWorld& domActivityLoggersForMainWorld()
20{
21    ASSERT(isMainThread());
22    DEFINE_STATIC_LOCAL(DOMActivityLoggerMapForMainWorld, map, ());
23    return map;
24}
25
26static DOMActivityLoggerMapForIsolatedWorld& domActivityLoggersForIsolatedWorld()
27{
28    ASSERT(isMainThread());
29    DEFINE_STATIC_LOCAL(DOMActivityLoggerMapForIsolatedWorld, map, ());
30    return map;
31}
32
33void V8DOMActivityLogger::setActivityLogger(int worldId, const String& extensionId, PassOwnPtr<V8DOMActivityLogger> logger)
34{
35    if (worldId)
36        domActivityLoggersForIsolatedWorld().set(worldId, logger);
37    else
38        domActivityLoggersForMainWorld().set(extensionId, logger);
39}
40
41V8DOMActivityLogger* V8DOMActivityLogger::activityLogger(int worldId, const String& extensionId)
42{
43    if (worldId) {
44        DOMActivityLoggerMapForIsolatedWorld& loggers = domActivityLoggersForIsolatedWorld();
45        DOMActivityLoggerMapForIsolatedWorld::iterator it = loggers.find(worldId);
46        return it == loggers.end() ? 0 : it->value.get();
47    }
48
49    if (extensionId.isEmpty())
50        return 0;
51
52    DOMActivityLoggerMapForMainWorld& loggers = domActivityLoggersForMainWorld();
53    DOMActivityLoggerMapForMainWorld::iterator it = loggers.find(extensionId);
54    return it == loggers.end() ? 0 : it->value.get();
55}
56
57V8DOMActivityLogger* V8DOMActivityLogger::activityLogger(int worldId, const KURL& url)
58{
59    // extension ID is ignored for worldId != 0.
60    if (worldId)
61        return activityLogger(worldId, String());
62
63    // To find an activity logger that corresponds to the main world of an
64    // extension, we need to obtain the extension ID. Extension ID is a hostname
65    // of a background page's URL.
66    if (!url.protocolIs("chrome-extension"))
67        return 0;
68
69    return activityLogger(worldId, url.host());
70}
71
72V8DOMActivityLogger* V8DOMActivityLogger::currentActivityLogger()
73{
74    v8::Isolate* isolate = v8::Isolate::GetCurrent();
75    if (!isolate->InContext())
76        return 0;
77
78    v8::HandleScope handleScope(isolate);
79    v8::Handle<v8::Context> context = isolate->GetCurrentContext();
80    if (context.IsEmpty() || !toDOMWindow(context))
81        return 0;
82
83    V8PerContextData* contextData = ScriptState::from(context)->perContextData();
84    if (!contextData)
85        return 0;
86
87    return contextData->activityLogger();
88}
89
90V8DOMActivityLogger* V8DOMActivityLogger::currentActivityLoggerIfIsolatedWorld()
91{
92    v8::Isolate* isolate = v8::Isolate::GetCurrent();
93    if (!isolate->InContext())
94        return 0;
95
96    v8::HandleScope handleScope(isolate);
97    v8::Handle<v8::Context> context = isolate->GetCurrentContext();
98    if (context.IsEmpty() || !toDOMWindow(context))
99        return 0;
100
101    ScriptState* scriptState = ScriptState::from(context);
102    if (!scriptState->world().isIsolatedWorld())
103        return 0;
104
105    V8PerContextData* contextData = scriptState->perContextData();
106    if (!contextData)
107        return 0;
108
109    return contextData->activityLogger();
110}
111
112} // namespace blink
113