package com.fsck.k9.mail.power;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.atomic.AtomicInteger;
import android.content.Context;
import android.os.PowerManager;
import android.os.PowerManager.WakeLock;
import android.os.SystemClock;
import com.fsck.k9.mail.K9MailLib;
import timber.log.Timber;
public class TracingPowerManager {
private final static boolean TRACE = false;
public static AtomicInteger wakeLockId = new AtomicInteger(0);
PowerManager pm = null;
private static TracingPowerManager tracingPowerManager;
private Timer timer = null;
public static synchronized TracingPowerManager getPowerManager(Context context) {
Context appContext = context.getApplicationContext();
if (tracingPowerManager == null) {
if (K9MailLib.isDebug()) {
Timber.v("Creating TracingPowerManager");
}
tracingPowerManager = new TracingPowerManager(appContext);
}
return tracingPowerManager;
}
private TracingPowerManager(Context context) {
pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
if (TRACE) {
timer = new Timer();
}
}
public TracingWakeLock newWakeLock(int flags, String tag) {
return new TracingWakeLock(flags, tag);
}
public class TracingWakeLock {
final WakeLock wakeLock;
final int id;
final String tag;
volatile TimerTask timerTask;
volatile Long startTime = null;
volatile Long timeout = null;
public TracingWakeLock(int flags, String ntag) {
tag = ntag;
wakeLock = pm.newWakeLock(flags, tag);
id = wakeLockId.getAndIncrement();
if (K9MailLib.isDebug()) {
Timber.v("TracingWakeLock for tag %s / id %d: Create", tag, id);
}
}
public void acquire(long timeout) {
synchronized (wakeLock) {
wakeLock.acquire(timeout);
}
if (K9MailLib.isDebug()) {
Timber.v("TracingWakeLock for tag %s / id %d for %d ms: acquired", tag, id, timeout);
}
raiseNotification();
if (startTime == null) {
startTime = SystemClock.elapsedRealtime();
}
this.timeout = timeout;
}
public void acquire() {
synchronized (wakeLock) {
wakeLock.acquire();
}
raiseNotification();
if (K9MailLib.isDebug()) {
Timber.w("TracingWakeLock for tag %s / id %d: acquired with no timeout. K-9 Mail should not do this",
tag, id);
}
if (startTime == null) {
startTime = SystemClock.elapsedRealtime();
}
timeout = null;
}
public void setReferenceCounted(boolean counted) {
synchronized (wakeLock) {
wakeLock.setReferenceCounted(counted);
}
}
public void release() {
if (startTime != null) {
Long endTime = SystemClock.elapsedRealtime();
if (K9MailLib.isDebug()) {
Timber.v("TracingWakeLock for tag %s / id %d: releasing after %d ms, timeout = %d ms",
tag, id, endTime - startTime, timeout);
}
} else {
if (K9MailLib.isDebug()) {
Timber.v("TracingWakeLock for tag %s / id %d, timeout = %d ms: releasing", tag, id, timeout);
}
}
cancelNotification();
synchronized (wakeLock) {
wakeLock.release();
}
startTime = null;
}
private void cancelNotification() {
if (timer != null) {
synchronized (timer) {
if (timerTask != null) {
timerTask.cancel();
}
}
}
}
private void raiseNotification() {
if (timer != null) {
synchronized (timer) {
if (timerTask != null) {
timerTask.cancel();
timerTask = null;
}
timerTask = new TimerTask() {
@Override
public void run() {
if (startTime != null) {
Long endTime = SystemClock.elapsedRealtime();
Timber.i("TracingWakeLock for tag %s / id %d: has been active for %d ms, timeout = %d ms",
tag, id, endTime - startTime, timeout);
} else {
Timber.i("TracingWakeLock for tag %s / id %d: still active, timeout = %d ms",
tag, id, timeout);
}
}
};
timer.schedule(timerTask, 1000, 1000);
}
}
}
}
}