| // Copyright 2015 The Chromium OS Authors. All rights reserved. | |
| // Use of this source code is governed by a BSD-style license that can be | |
| // found in the LICENSE file. | |
| 'use strict'; | |
| /** | |
| * @fileoverview Manager class to represent and hold state for each instance. | |
| * of a shill manager for a given log being processed. | |
| */ | |
| /** | |
| * @constructor | |
| * | |
| * @param {String} id Identifier for new manager instance. | |
| * @param {long} ms Manager start time in ms. | |
| * */ | |
| function Manager(id, ms) { | |
| this.id = id; | |
| this.startTime = ms; | |
| this.services = []; | |
| this.scans = 0; | |
| this.scanDetails = []; | |
| this.endTime = -1; | |
| this.suspendDetails = []; | |
| } | |
| /** | |
| * This method is responsible for getting a service instance for the supplied | |
| * service id. If a matching instance is not found, a new service is created | |
| * and added to the services array. | |
| * | |
| * @param {String} serviceId A service identifier. | |
| * @return {Service} Service instance for the supplied identifier. | |
| */ | |
| Manager.prototype.getService = function(serviceId) { | |
| console.log('getting service ' + serviceId + ' from manager! ' , this); | |
| var services = this.services; | |
| for (var i = 0; i < services.length; i++) { | |
| if (services[i].serviceId == serviceId) { | |
| return services[i]; | |
| } | |
| } | |
| var newService = new Service(serviceId); | |
| this.services.push(newService); | |
| console.log('now the manager is: ' , this); | |
| return newService; | |
| }; | |
| /** | |
| * This menthod is responsible for getting a service instance for the current | |
| * active service. Returns null if an active service is not found. | |
| * | |
| * | |
| * @return {Service} Service instance for the active service. | |
| */ | |
| Manager.prototype.getActiveService = function() { | |
| console.log('getting active service from manager! ' , this); | |
| var services = this.services; | |
| for (var i = 0; i < services.length; i++) { | |
| if (services[i].isActive) { | |
| return services[i]; | |
| } | |
| } | |
| return null; | |
| }; | |
| /** | |
| * This method adds detailed dark suspend information. When possible, the | |
| * start time of the event is recorded. Event done messages are used | |
| * to record the completion of an event. | |
| * | |
| * @param {boolean} eventDone Boolean denoting if an event completed. | |
| * @param {long} time event detail time in ms from start of this manager. | |
| */ | |
| Manager.prototype.addDarkSuspendDetails = function(eventDone, time) { | |
| var e; | |
| var events = this.suspendDetails; | |
| if (eventDone) { | |
| e = {'end': time}; | |
| } else { | |
| e = {'start': time}; | |
| } | |
| console.log('addDarkSuspendDetails: ' + eventDone + ' ' + time); | |
| if (events.length == 0) { | |
| // first suspend event, add new suspend event first | |
| events.push({'start': null}); | |
| } | |
| var suspendEvent = events[events.length - 1]; | |
| if (suspendEvent.end != null) { | |
| // current suspend event is finished, start a new one | |
| console.log('ERROR: adding dark resume detail to finished suspend'); | |
| } else { | |
| if (suspendEvent.darkSuspends == null) { | |
| suspendEvent.darkSuspends = []; | |
| suspendEvent.darkSuspends.push(e); | |
| } else { | |
| var dsCount = suspendEvent.darkSuspends.length; | |
| var lastDS = suspendEvent.darkSuspends[dsCount - 1]; | |
| if (lastDS.end == null && eventDone) { | |
| // dark suspend is done, add to last entry | |
| lastDS.end = time; | |
| } else if (lastDS.end != null && !eventDone) { | |
| // new dark suspend event | |
| suspendEvent.darkSuspends.push(e); | |
| } else if (lastDS.end == null && !eventDone) { | |
| // error case: new dark suspend event with previous unfinished | |
| console.log('ERROR: new darkSuspend event before previous completed'); | |
| } else { | |
| //error case: dark suspned completion without new start | |
| console.log('ERROR: completed darkSuspend without starting event'); | |
| } | |
| } | |
| } | |
| }; | |
| /** | |
| * This method adds detailed event information. When possible, the | |
| * start time of the event is recorded. Event done messages are used | |
| * to record the completion of an event. | |
| * | |
| * @param {String} eventType Denotes which event type. | |
| * @param {boolean} eventDone Boolean denoting if an event completed. | |
| * @param {long} time event detail time in ms from start of this manager. | |
| */ | |
| Manager.prototype.addEventDetail = function(eventType, eventDone, time) { | |
| console.log('adding ' + eventType + ' details'); | |
| var events; | |
| if (eventType == 'suspend') { | |
| events = this.suspendDetails; | |
| } else if (eventType == 'darksuspend') { | |
| this.addDarkSuspendDetails(eventDone, time); | |
| return; | |
| } else if (eventType == 'scan') { | |
| events = this.scanDetails; | |
| } else { | |
| console.log('unsupported event type: ' + eventType); | |
| return; | |
| } | |
| var eventCount = events.length; | |
| var lastEvent = null; | |
| if (eventDone) { | |
| if (eventCount > 0) { | |
| // we can append the next time | |
| lastEvent = events[eventCount - 1]; | |
| if (lastEvent.end != null) { | |
| // last event already has an end time... create new entry | |
| events.push({'end': time}); | |
| } else { | |
| lastEvent.end = time; | |
| } | |
| } else { | |
| // create and add a new event | |
| events.push({'end': time}); | |
| } | |
| } else { | |
| // this is a new event starting | |
| events.push({'start': time}); | |
| } | |
| }; |