k-9/src/com/fsck/k9/service/CoreService.java

188 lines
6.2 KiB
Java
Raw Normal View History

package com.fsck.k9.service;
import java.util.concurrent.ConcurrentHashMap;
2010-01-12 09:09:30 -05:00
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.RejectedExecutionException;
import java.util.concurrent.atomic.AtomicInteger;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.os.IBinder;
import android.os.PowerManager;
import android.util.Log;
import com.fsck.k9.K9;
import com.fsck.k9.helper.power.TracingPowerManager;
import com.fsck.k9.helper.power.TracingPowerManager.TracingWakeLock;
public abstract class CoreService extends Service
{
public static String WAKE_LOCK_ID = "com.fsck.k9.service.CoreService.wakeLockId";
private static ConcurrentHashMap<Integer, TracingWakeLock> wakeLocks = new ConcurrentHashMap<Integer, TracingWakeLock>();
private static AtomicInteger wakeLockSeq = new AtomicInteger(0);
private ExecutorService threadPool = null;
private final String className = getClass().getName();
private volatile boolean mShutdown = false;
@Override
public void onCreate()
{
if (K9.DEBUG)
Log.i(K9.LOG_TAG, "CoreService: " + className + ".onCreate()");
threadPool = Executors.newFixedThreadPool(1); // Must be single threaded
super.onCreate();
}
protected static void addWakeLockId(Intent i, Integer wakeLockId)
{
if (wakeLockId != null)
{
i.putExtra(BootReceiver.WAKE_LOCK_ID, wakeLockId);
}
}
protected static void addWakeLock(Context context, Intent i)
{
TracingPowerManager pm = TracingPowerManager.getPowerManager(context);
TracingWakeLock wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "CoreService addWakeLock");
wakeLock.setReferenceCounted(false);
wakeLock.acquire(K9.MAIL_SERVICE_WAKE_LOCK_TIMEOUT);
2010-01-02 20:50:51 -05:00
Integer tmpWakeLockId = wakeLockSeq.getAndIncrement();
wakeLocks.put(tmpWakeLockId, wakeLock);
2010-01-02 20:50:51 -05:00
i.putExtra(WAKE_LOCK_ID, tmpWakeLockId);
}
2010-01-02 20:50:51 -05:00
@Override
public void onStart(Intent intent, int startId)
{
TracingPowerManager pm = TracingPowerManager.getPowerManager(this);
TracingWakeLock wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "CoreService onStart");
wakeLock.setReferenceCounted(false);
wakeLock.acquire(K9.MAIL_SERVICE_WAKE_LOCK_TIMEOUT);
2010-01-02 20:50:32 -05:00
if (K9.DEBUG)
Log.i(K9.LOG_TAG, "CoreService: " + className + ".onStart(" + intent + ", " + startId);
int wakeLockId = intent.getIntExtra(BootReceiver.WAKE_LOCK_ID, -1);
if (wakeLockId != -1)
{
BootReceiver.releaseWakeLock(this, wakeLockId);
}
Integer coreWakeLockId = intent.getIntExtra(WAKE_LOCK_ID, -1);
if (coreWakeLockId != null && coreWakeLockId != -1)
{
if (K9.DEBUG)
Log.d(K9.LOG_TAG, "Got core wake lock id " + coreWakeLockId);
TracingWakeLock coreWakeLock = wakeLocks.remove(coreWakeLockId);
if (coreWakeLock != null)
{
if (K9.DEBUG)
Log.d(K9.LOG_TAG, "Found core wake lock with id " + coreWakeLockId + ", releasing");
coreWakeLock.release();
}
}
try
{
super.onStart(intent, startId);
startService(intent, startId);
}
finally
{
wakeLock.release();
}
}
2010-01-12 09:09:30 -05:00
public void execute(Context context, final Runnable runner, int wakeLockTime, final Integer startId)
{
TracingPowerManager pm = TracingPowerManager.getPowerManager(context);
final TracingWakeLock wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "CoreService execute");
2010-01-12 09:09:30 -05:00
wakeLock.setReferenceCounted(false);
wakeLock.acquire(wakeLockTime);
2010-01-12 09:09:30 -05:00
Runnable myRunner = new Runnable()
{
public void run()
{
try
{
if (K9.DEBUG)
Log.d(K9.LOG_TAG, "CoreService (" + className + ") running Runnable " + runner.hashCode() + " with startId " + startId);
2010-01-12 09:09:30 -05:00
runner.run();
}
finally
{
if (K9.DEBUG)
Log.d(K9.LOG_TAG, "CoreService (" + className + ") completed Runnable " + runner.hashCode() + " with startId " + startId);
2010-01-12 09:09:30 -05:00
wakeLock.release();
if (startId != null)
{
stopSelf(startId);
}
}
}
};
if (threadPool == null)
{
Log.e(K9.LOG_TAG, "CoreService.execute (" + className + ") called with no threadPool available; running Runnable " + runner.hashCode() + " in calling thread", new Throwable());
synchronized (this)
{
myRunner.run();
}
}
else
{
if (K9.DEBUG)
Log.d(K9.LOG_TAG, "CoreService (" + className + ") queueing Runnable " + runner.hashCode() + " with startId " + startId);
try
{
threadPool.execute(myRunner);
}
catch (RejectedExecutionException e)
{
if (!mShutdown)
{
throw e;
}
Log.i(K9.LOG_TAG, "CoreService: " + className + " is shutting down, ignoring rejected execution exception: " + e.getMessage());
}
}
2010-01-12 09:09:30 -05:00
}
public abstract void startService(Intent intent, int startId);
@Override
public IBinder onBind(Intent arg0)
{
// TODO Auto-generated method stub
return null;
}
@Override
public void onLowMemory()
{
Log.w(K9.LOG_TAG, "CoreService: " + className + ".onLowMemory() - Running low on memory");
}
@Override
public void onDestroy()
{
2010-01-02 20:50:32 -05:00
if (K9.DEBUG)
Log.i(K9.LOG_TAG, "CoreService: " + className + ".onDestroy()");
mShutdown = true;
threadPool.shutdown();
super.onDestroy();
// MessagingController.getInstance(getApplication()).removeListener(mListener);
}
}