/*
Copyright (C) 2011 The University of Michigan
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Please send inquiries to powertutor@umich.edu
*/
package edu.umich.PowerTutor.components;
import edu.umich.PowerTutor.PowerNotifications;
import edu.umich.PowerTutor.service.IterationData;
import edu.umich.PowerTutor.service.PowerData;
import edu.umich.PowerTutor.util.NotificationService;
import edu.umich.PowerTutor.util.Recycler;
import android.content.Context;
import android.media.AudioManager;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.util.TreeSet;
/**This class aims to log the audio device status once per log interval*/
public class Audio extends PowerComponent {
/**This class is the logger data file corresponding to Audio*/
public static class AudioData extends PowerData {
private static Recycler<AudioData> recycler = new Recycler<AudioData>();
public static AudioData obtain() {
AudioData result = recycler.obtain();
if(result != null) return result;
return new AudioData();
}
@Override
public void recycle() {
recycler.recycle(this);
}
public boolean musicOn;
private AudioData() {
}
public void init(boolean musicOn) {
this.musicOn = musicOn;
}
public void writeLogDataInfo(OutputStreamWriter out) throws IOException {
out.write("Audio-on " + musicOn + "\n");
}
}
private static class MediaData implements Comparable {
private static Recycler<MediaData> recycler = new Recycler<MediaData>();
public static MediaData obtain() {
MediaData result = recycler.obtain();
if(result != null) return result;
return new MediaData();
}
public void recycle() {
recycler.recycle(this);
}
public int uid;
public int id;
public int assignUid;
public int compareTo(Object obj) {
MediaData x = (MediaData)obj;
if(uid < x.uid) return -1;
if(uid > x.uid) return 1;
if(id < x.id) return -1;
if(id > x.id) return 1;
return 0;
}
public boolean equals(Object obj) {
MediaData x = (MediaData)obj;
return uid == x.uid && id == x.id;
}
}
private AudioManager audioManager;
private PowerNotifications audioNotif;
private TreeSet<MediaData> uidData;
public Audio(Context context) {
if(NotificationService.available()) {
uidData = new TreeSet<MediaData>();
audioNotif = new NotificationService.DefaultReceiver() {
private int sysUid = -1;
@Override
public void noteSystemMediaCall(int uid) {
sysUid = uid;
}
@Override
public void noteStartMedia(int uid, int id) {
MediaData data = MediaData.obtain();
data.uid = uid;
data.id = id;
if(uid == 1000 && sysUid != -1) {
data.assignUid = sysUid;
sysUid = -1;
} else {
data.assignUid = uid;
}
synchronized(uidData) {
if(!uidData.add(data)) {
data.recycle();
}
}
}
@Override
public void noteStopMedia(int uid, int id) {
MediaData data = MediaData.obtain();
data.uid = uid;
data.id = id;
synchronized(uidData) {
uidData.remove(data);
}
data.recycle();
}
};
NotificationService.addHook(audioNotif);
}
audioManager = (AudioManager)context.getSystemService(
Context.AUDIO_SERVICE);
}
@Override
protected void onExit() {
if(audioNotif != null) {
NotificationService.removeHook(audioNotif);
}
}
@Override
public IterationData calculateIteration(long iteration) {
IterationData result = IterationData.obtain();
AudioData data = AudioData.obtain();
data.init(uidData != null && !uidData.isEmpty() ||
audioManager.isMusicActive());
result.setPowerData(data);
if(uidData != null) synchronized(uidData) {
int last_uid = -1;
for(MediaData dat : uidData) {
if(dat.uid != last_uid) {
AudioData audioPower = AudioData.obtain();
audioPower.init(true);
result.addUidPowerData(dat.assignUid, audioPower);
}
last_uid = dat.uid;
}
}
return result;
}
@Override
public boolean hasUidInformation() {
return audioNotif != null;
}
@Override
public String getComponentName() {
return "Audio";
}
}