1/*
2 * Copyright (C) 2013 Apple Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 *    notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 *    notice, this list of conditions and the following disclaimer in the
11 *    documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23 * THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26WebInspector.LegacyProfileManager = function()
27{
28    WebInspector.Object.call(this);
29
30    this._javaScriptProfileType = new WebInspector.LegacyJavaScriptProfileType;
31
32    if (window.ProfilerAgent) {
33        ProfilerAgent.enable();
34        ProfilerAgent.getProfileHeaders();
35    }
36
37    WebInspector.Frame.addEventListener(WebInspector.Frame.Event.MainResourceDidChange, this._mainResourceDidChange, this);
38
39    this.initialize();
40};
41
42WebInspector.LegacyProfileManager.Event = {
43    ProfileWasAdded: "profile-manager-profile-was-added",
44    ProfileWasUpdated: "profile-manager-profile-was-updated",
45    ProfilingStarted: "profile-manager-profiling-started",
46    ProfilingEnded: "profile-manager-profiling-ended",
47    ProfilingInterrupted: "profile-manager-profiling-interrupted",
48    Cleared: "profile-manager-cleared"
49};
50
51WebInspector.LegacyProfileManager.UserInitiatedProfileName = "org.webkit.profiles.user-initiated";
52
53WebInspector.LegacyProfileManager.prototype = {
54    constructor: WebInspector.LegacyProfileManager,
55
56    // Public
57
58    initialize: function()
59    {
60        this._checkForInterruptions();
61
62        this._recordingJavaScriptProfile = null;
63
64        this._isProfiling = false;
65
66        this.dispatchEventToListeners(WebInspector.LegacyProfileManager.Event.Cleared);
67    },
68
69    isProfilingJavaScript: function()
70    {
71        return this._javaScriptProfileType.isRecordingProfile();
72    },
73
74    startProfilingJavaScript: function()
75    {
76        this._javaScriptProfileType.startRecordingProfile();
77    },
78
79    stopProfilingJavaScript: function()
80    {
81        this._javaScriptProfileType.stopRecordingProfile();
82    },
83
84    profileWasStartedFromConsole: function(title)
85    {
86        this.setRecordingJavaScriptProfile(true, true);
87
88        if (title.indexOf(WebInspector.LegacyProfileManager.UserInitiatedProfileName) === -1) {
89            this._recordingJavaScriptProfile.title = title;
90            this.dispatchEventToListeners(WebInspector.LegacyProfileManager.Event.ProfileWasUpdated, {profile: this._recordingJavaScriptProfile});
91        }
92    },
93
94    profileWasEndedFromConsole: function()
95    {
96        this.setRecordingJavaScriptProfile(false, true);
97    },
98
99    addJavaScriptProfile: function(profile)
100    {
101        console.assert(this._recordingJavaScriptProfile);
102        if (!this._recordingJavaScriptProfile)
103            return;
104
105        this._recordingJavaScriptProfile.type = profile.typeId;
106        this._recordingJavaScriptProfile.title = profile.title;
107        this._recordingJavaScriptProfile.id = profile.uid;
108        this._recordingJavaScriptProfile.recording = false;
109
110        this.dispatchEventToListeners(WebInspector.LegacyProfileManager.Event.ProfileWasUpdated, {profile: this._recordingJavaScriptProfile});
111
112        // We want to reset _recordingJavaScriptProfile so that we can identify
113        // interruptions, but we also want to keep track of the last profile
114        // we've recorded so that we can provide it as data to the ProfilingEnded event
115        // we'll dispatch in setRecordingJavaScriptProfile().
116        this._lastJavaScriptProfileAdded = this._recordingJavaScriptProfile;
117        this._recordingJavaScriptProfile = null;
118    },
119
120    setRecordingJavaScriptProfile: function(isProfiling, fromConsole)
121    {
122        if (this._isProfiling === isProfiling)
123            return;
124
125        this._isProfiling = isProfiling;
126
127        // We've interrupted the current JS profile due to a page reload. Return
128        // now and _attemptToResumeProfiling will pick things up after the reload.
129        if (!isProfiling && !!this._recordingJavaScriptProfile)
130            return;
131
132        if (isProfiling && !this._recordingJavaScriptProfile)
133            this._recordingJavaScriptProfile = new WebInspector.LegacyJavaScriptProfileObject(WebInspector.LegacyProfileManager.UserInitiatedProfileName, -1, true);
134
135        if (isProfiling) {
136            this.dispatchEventToListeners(WebInspector.LegacyProfileManager.Event.ProfileWasAdded, {profile: this._recordingJavaScriptProfile});
137            if (!fromConsole)
138                this.dispatchEventToListeners(WebInspector.LegacyProfileManager.Event.ProfilingStarted);
139        } else {
140            this.dispatchEventToListeners(WebInspector.LegacyProfileManager.Event.ProfilingEnded, {
141                profile: this._lastJavaScriptProfileAdded,
142                fromConsole: fromConsole
143            });
144            this._lastJavaScriptProfileAdded = null;
145        }
146    },
147
148    // Private
149
150    _mainResourceDidChange: function(event)
151    {
152        console.assert(event.target instanceof WebInspector.Frame);
153
154        if (!event.target.isMainFrame())
155            return;
156
157        var oldMainResource = event.data.oldMainResource;
158        var newMainResource = event.target.mainResource;
159        if (oldMainResource.url !== newMainResource.url)
160            this.initialize();
161        else
162            this._attemptToResumeProfiling();
163    },
164
165    _checkForInterruptions: function()
166    {
167        if (this._recordingJavaScriptProfile) {
168            this.dispatchEventToListeners(WebInspector.LegacyProfileManager.Event.ProfilingInterrupted, {profile: this._recordingJavaScriptProfile});
169            this._javaScriptProfileType.setRecordingProfile(false);
170        }
171    },
172
173    _attemptToResumeProfiling: function()
174    {
175        this._checkForInterruptions();
176
177        if (this._recordingJavaScriptProfile)
178            this.startProfilingJavaScript();
179    }
180};
181
182WebInspector.LegacyProfileManager.prototype.__proto__ = WebInspector.Object.prototype;
183