/** * Copyright (C) 2013 Johannes Schnatterer * * See the NOTICE file distributed with this work for additional * information regarding copyright ownership. * * This file is part of nusic. * * nusic 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. * * nusic 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 nusic. If not, see <http://www.gnu.org/licenses/>. */ package info.schnatterer.nusic.android.service; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import roboguice.service.RoboService; import android.app.IntentService; import android.content.Context; import android.content.Intent; import android.os.PowerManager; /** * {@link Service} that locks the CPU before running the service. * * Similar to <a href="https://github.com/commonsguy/cwac-wakeful">common * ware'</a> Wakeful {@link IntentService}. * * To use it, just derive your service from this class and override * {@link #onStartCommandWakeful(Intent, int, int)} instead of * {@link #onStartCommand(Intent, int, int)}. * * @author schnatterer * */ public abstract class WakefulService extends RoboService { private static final Logger LOG = LoggerFactory .getLogger(WakefulService.class); private static final String LOCK_NAME = "info.schnatterer.nusic.android.service.WakefulService"; private static volatile PowerManager.WakeLock lockStatic = null; /** * Keeps the lock after {@link #onStartCommand(Intent, int, int)} has been * finished. <b> Note: </b> The derived class that sets this to * <code>true</code> is responsible for calling {@link #releaseLock()} * itself! */ protected boolean keepLock = false; @Override public void onCreate() { super.onCreate(); } abstract protected int onStartCommandWakeful(Intent intent, int flags, int startId); synchronized protected static PowerManager.WakeLock getLock(Context context) { if (lockStatic == null) { PowerManager mgr = (PowerManager) context .getSystemService(Context.POWER_SERVICE); lockStatic = mgr.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, LOCK_NAME); lockStatic.setReferenceCounted(true); } return lockStatic; } @Override public int onStartCommand(Intent intent, int flags, int startId) { acquireLock(this.getApplicationContext()); try { LOG.debug("Calling service method"); return onStartCommandWakeful(intent, flags, startId); } finally { if (!keepLock) { releaseLock(this.getApplicationContext()); } } } /** * Tries to acquire the lock, if not held. */ protected static void acquireLock(Context context) { PowerManager.WakeLock lock = getLock(context); if (!lock.isHeld()) { lock.acquire(); LOG.debug("Lock acquired"); } } /** * Releases the lock, if held. */ protected static void releaseLock(Context context) { PowerManager.WakeLock lock = getLock(context); if (lock.isHeld()) { lock.release(); LOG.debug("Lock released"); } } }