package org.primftpd.services; import android.os.Handler; import android.os.Looper; import android.os.Message; import android.os.PowerManager; import android.os.PowerManager.WakeLock; import org.primftpd.util.ServicesStartStopUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.lang.ref.WeakReference; /** * Handles starting and stopping of Servers, including {@link WakeLock}. * */ public class ServerServiceHandler extends Handler { private static final String APP_NAME = "pFTPd"; protected final Logger logger = LoggerFactory.getLogger(getClass()); private final WeakReference<AbstractServerService> serviceRef; private final String logName; private static WakeLock wakeLock; protected ServerServiceHandler( Looper looper, AbstractServerService service, String logName) { super(looper); this.serviceRef = new WeakReference<>(service); this.logName = logName; } @Override public void handleMessage(Message msg) { logger.debug("handleMessage()"); AbstractServerService service = serviceRef.get(); if (service == null) { logger.warn("serviceRef is null ({})", logName); return; } int toDo = msg.arg1; if (toDo == AbstractServerService.MSG_START) { handleStart(service); } else if (toDo == AbstractServerService.MSG_STOP) { handleStop(service); } } protected void handleStart(AbstractServerService service) { if (service.getServer() == null) { logger.debug("starting {} server", logName); // XXX set properties to prefer IPv4 to run in simulator System.setProperty("java.net.preferIPv4Stack", "true"); System.setProperty("java.net.preferIPv6Addresses", "false"); boolean started = service.launchServer(); if (started && service.getServer() != null) { PowerManager powerMgr = (PowerManager) service.getSystemService( AbstractServerService.POWER_SERVICE); obtainWakeLock(powerMgr, service.prefsBean.isWakelock()); if (service.prefsBean.isAnnounce()) { service.announceService(); } ServicesStartStopUtil.updateNonActivityUI(service, true); } else { service.stopSelf(); } } } protected void handleStop(AbstractServerService service) { if (service.getServer() != null) { logger.debug("stopping {} server", logName); service.stopServer(); if (service.prefsBean.isAnnounce()) { service.unannounceService(); } } releaseWakeLock(); logger.debug("stopSelf ({})", logName); service.stopSelf(); ServicesStartStopUtil.updateNonActivityUI(service, false); } private synchronized void obtainWakeLock( PowerManager powerMgr, boolean takeWakeLock) { // acquire wake lock for CPU to still handle requests // note: PARTIAL_WAKE_LOCK is not enough if (wakeLock == null && takeWakeLock) { logger.debug("acquiring wake lock ({})", logName); wakeLock = powerMgr.newWakeLock( PowerManager.SCREEN_DIM_WAKE_LOCK, APP_NAME); wakeLock.acquire(); } else { if (takeWakeLock) { logger.debug("wake lock already taken ({})", logName); } else { logger.debug("wake lock disabled ({})", logName); } } } private synchronized void releaseWakeLock() { if (wakeLock != null) { if (wakeLock.isHeld()) { logger.debug("releasing wake lock ({})", logName); wakeLock.release(); } else { logger.debug("wake lock not held, not releasing it ({})", logName); } wakeLock = null; } else { logger.debug("wake lock already released ({})", logName); } } }