/*
Copyright 2013 The MITRE Corporation, All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this work except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package org.mitre.svmp.performance;
import android.content.Context;
import org.mitre.svmp.activities.AppRTCActivity;
import org.mitre.svmp.apprtc.AppRTCClient;
import org.mitre.svmp.common.DatabaseHandler;
import org.mitre.svmp.common.Utility;
import org.mitre.svmp.client.R;
import java.util.Date;
import java.util.Timer;
/**
* @author Joe Portner
* Runs tasks on intervals to gather and record performance data
* Runs all timer tasks on a single background thread
* Runs CPU measurement task on a separate thread
*/
public class PerformanceTimer extends Timer {
// common variables
private Context context;
private AppRTCClient binder;
private int connectionID;
private boolean active;
// objects that record performance measurements
private SpanPerformanceData spanPerformanceData;
private PointPerformanceData pointPerformanceData;
// threads/tasks that take performance measurements
private MeasureCpuThread measureCpuThread;
private MeasureTask measureTask;
private PingTask pingTask;
public PerformanceTimer(Context context, AppRTCClient binder, int connectionID) {
this.context = context;
this.binder = binder;
this.connectionID = connectionID;
// find out if we should take measurements (set in Preferences)
this.active = Utility.getPrefBool(context,
R.string.preferenceKey_performance_takeMeasurements,
R.string.preferenceValue_performance_takeMeasurements);
// create objects to record performance measurements
this.spanPerformanceData = new SpanPerformanceData();
this.pointPerformanceData = new PointPerformanceData();
}
// getters
public SpanPerformanceData getSpanPerformanceData() {
return spanPerformanceData;
}
public PointPerformanceData getPointPerformanceData() {
return pointPerformanceData;
}
// called when connection handshaking is complete and state is RUNNING
public void start() {
if (active) {
// find out how often to take measurements (set in Preferences)
int pingInterval = Utility.getPrefInt(context,
R.string.preferenceKey_performance_pingInterval,
R.string.preferenceValue_performance_pingInterval);
int measureInterval = Utility.getPrefInt(context,
R.string.preferenceKey_performance_measureInterval,
R.string.preferenceValue_performance_measureInterval);
// find the current time
long startDate = System.currentTimeMillis();
// add the current time, connection ID, and measure interval to the database (MeasurementInfo table)
DatabaseHandler databaseHandler = new DatabaseHandler(context);
databaseHandler.insertMeasurementInfo(
new MeasurementInfo(new Date(startDate), connectionID, measureInterval, pingInterval));
databaseHandler.close();
// create a MeasureCpuThread and run it on an interval (start immediately)
measureCpuThread = new MeasureCpuThread(pointPerformanceData, context.getPackageName());
measureCpuThread.start();
// create a PingTask and run it on an interval (start immediately)
pingTask = new PingTask(binder);
scheduleAtFixedRate(this.pingTask, 0, pingInterval);
// create a MeasureTask and run it on an interval
measureTask = new MeasureTask(context, spanPerformanceData, pointPerformanceData, startDate);
scheduleAtFixedRate(this.measureTask, measureInterval, measureInterval);
}
else
cancel();
}
@Override
public void cancel() {
if (active) {
if (measureCpuThread != null)
measureCpuThread.cancel();
if (pingTask != null)
pingTask.cancel();
if (measureTask != null)
measureTask.cancel();
}
measureCpuThread = null;
pingTask = null;
measureTask = null;
super.cancel();
}
}