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.
5 /** @suppress {duplicate} */
6 var remoting = remoting || {};
13 var NEW_WINDOW_MENU_ID_ = 'new-window';
16 * A class that handles application activation.
18 * @param {base.Ipc} ipc
19 * @param {remoting.V2AppLauncher} appLauncher
20 * @param {remoting.TelemetryEventWriter.Service} telemetryService
21 * @extends {base.EventSourceImpl}
22 * @implements {base.Disposable}
25 remoting.ActivationHandler = function (ipc, appLauncher, telemetryService) {
26 base.inherits(this, base.EventSourceImpl);
27 this.defineEvents(base.values(remoting.ActivationHandler.Events));
32 /** @private {remoting.V2AppLauncher} */
33 this.appLauncher_ = appLauncher;
35 /** @private {Map<string, base.Disposable>} */
36 this.windowClosedHooks_ = new Map();
39 this.telemetryService_ = telemetryService;
41 chrome.contextMenus.create({
42 id: NEW_WINDOW_MENU_ID_,
43 contexts: ['launcher'],
44 title: chrome.i18n.getMessage(/*i18n-content*/'NEW_WINDOW')
47 this.disposables_ = new base.Disposables(
48 new base.ChromeEventHook(chrome.contextMenus.onClicked,
49 this.onContextMenu_.bind(this)),
50 new base.ChromeEventHook(chrome.app.runtime.onLaunched,
51 this.onLaunched_.bind(this)));
52 ipc.register(remoting.ActivationHandler.Ipc.RESTART,
53 this.onRestart_.bind(this));
54 ipc.register(remoting.ActivationHandler.Ipc.LAUNCH,
55 this.onLaunched_.bind(this));
59 remoting.ActivationHandler.prototype.dispose = function() {
60 this.windowClosedHooks_.forEach(function(/** base.Disposable */ eventHook) {
61 base.dispose(eventHook);
63 this.windowClosedHooks_.clear();
65 base.dispose(this.disposables_);
66 this.disposables_ = null;
67 this.ipc_.unregister(remoting.ActivationHandler.Ipc.LAUNCH);
68 this.ipc_.unregister(remoting.ActivationHandler.Ipc.RESTART);
72 remoting.ActivationHandler.Ipc = {
73 LAUNCH: 'remoting.ActivationHandler.launch',
74 RESTART: 'remoting.ActivationHandler.restart'
78 * @param {OnClickData} info
81 remoting.ActivationHandler.prototype.onContextMenu_ = function(info) {
82 if (info.menuItemId == NEW_WINDOW_MENU_ID_) {
88 * Restart the window with |id|.
93 remoting.ActivationHandler.prototype.onRestart_ = function(id) {
94 this.appLauncher_.restart(id).then(this.onWindowCreated_.bind(this));
100 remoting.ActivationHandler.prototype.onLaunched_ = function() {
101 this.createWindow_();
105 * Create a new app window and register for the closed event.
109 remoting.ActivationHandler.prototype.createWindow_ = function() {
110 this.appLauncher_.launch().then(this.onWindowCreated_.bind(this));
114 * @param {string} windowId
118 remoting.ActivationHandler.prototype.onWindowCreated_ = function(
120 // Send the client heartbeat.
122 new remoting.ChromotingEvent(remoting.ChromotingEvent.Type.HEARTBEAT);
123 event.role = remoting.ChromotingEvent.Role.CLIENT;
124 this.telemetryService_.write(''/* No window Id for background page */, event);
126 // Register close handler.
127 var appWindow = chrome.app.window.get(windowId);
128 console.assert(!this.windowClosedHooks_.has(windowId),
129 'Duplicate close listener attached to window : ' + windowId);
130 this.windowClosedHooks_.set(windowId, new base.ChromeEventHook(
131 appWindow.onClosed, this.onWindowClosed_.bind(this, windowId)));
135 * @param {string} id The id of the window that is closed.
138 remoting.ActivationHandler.prototype.onWindowClosed_ = function(id) {
140 var hook = /** @type {base.Disposable} */ (this.windowClosedHooks_.get(id));
142 this.windowClosedHooks_.delete(id);
144 this.raiseEvent(remoting.ActivationHandler.Events.windowClosed, id);
149 /** @enum {string} */
150 remoting.ActivationHandler.Events = {
151 windowClosed: 'windowClosed'