/** * Copyright (c) 2011 Martin M Reed * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package net.hardisonbrewing.signingserver; import java.util.Hashtable; import java.util.Timer; import java.util.TimerTask; import net.hardisonbrewing.signingserver.service.OptionsProvider; import net.hardisonbrewing.signingserver.service.SigStatusService; import net.hardisonbrewing.signingserver.service.icon.IconService; import net.hardisonbrewing.signingserver.service.network.NetworkReadyListener; import net.hardisonbrewing.signingserver.service.push.PushPPGService; import net.hardisonbrewing.signingserver.service.store.ModuleHandleStore; import net.rim.blackberry.api.options.OptionsManager; import net.rim.device.api.system.Application; import net.rim.device.api.system.WLANInfo; import org.apache.commons.threadpool.DefaultThreadPool; import org.apache.commons.threadpool.ThreadPool; import org.metova.mobile.util.time.Dates; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class SigservAutorunApplication extends Application { private static final Logger log = LoggerFactory.getLogger( SigservAutorunApplication.class ); private static final int STATE_READY = 0; private static final int STATE_RUNNING = 1; private static final int STATE_RAN = 2; private static final Object lock = new Object(); private static int runState = STATE_READY; private TimerTask networkRequiredTimerTask; private NetworkReadyListener networkReadyListener; public static void mainAutoRunOnStartup( String[] args ) { log.info( "Running auto run application" ); ModuleHandleStore.put(); IconService.updateIcon(); OptionsManager.registerOptionsProvider( new OptionsProvider() ); ThreadPool threadPool = new DefaultThreadPool( 1 ); threadPool.invokeLater( new NetworkRequiredTask() ); } private static void downloadStatus() throws Exception { log.info( "Downloading SigStatus from server" ); Hashtable status = SigStatusService.downloadStatus(); SigservApplication.updateStoredStatus( status ); IconService.updateIcon(); } private static final void startup() throws Exception { boolean runStartup = false; if ( runState == STATE_READY ) { synchronized (lock) { if ( runState == STATE_READY ) { runState = STATE_RUNNING; runStartup = true; } } } if ( !runStartup ) { return; } try { runStartup(); } catch (Exception e) { runState = STATE_READY; } } private static final void runStartup() throws Exception { log.info( "Running startup" ); if ( SigservPushApplication.isSupported() ) { try { PushPPGService.registerOnStartup(); } catch (Exception e) { log.error( "Exception trying to register PUSH notifications", e ); } } try { SigservBBMApplication.registerBBMConnect(); } catch (Exception e) { log.error( "Exception trying to register BBM", e ); } downloadStatus(); runState = STATE_RAN; } private static final class NetworkRequiredTask implements Runnable { public void run() { SigservApplication.waitForStatup(); log.info( "Checking coverage for startup" ); if ( SigservApplication.hasSufficientCoverage() ) { log.info( "Sufficient coverage, running startup" ); try { startup(); } catch (Exception e) { log.error( "Exception while running network required startup" ); } } else { log.info( "Coverage not sufficient, skipping startup" ); } if ( runState != STATE_RAN ) { log.info( "Startup not completed, delaying startup" ); final SigservAutorunApplication application = new SigservAutorunApplication(); application.invokeLater( new Runnable() { public void run() { application.bootloader(); } } ); application.enterEventDispatcher(); } } } private void bootloader() { networkReadyListener = new MyNetworkReadyListener(); addRadioListener( networkReadyListener ); WLANInfo.addListener( networkReadyListener ); Timer timer = new Timer(); networkRequiredTimerTask = new NetworkRequiredTimerTask(); timer.schedule( networkRequiredTimerTask, Dates.SECOND * 15, Dates.SECOND * 15 ); } public boolean requestClose() { log.info( "Closing auto run application" ); if ( networkRequiredTimerTask != null ) { networkRequiredTimerTask.cancel(); networkRequiredTimerTask = null; } if ( networkReadyListener != null ) { WLANInfo.removeListener( networkReadyListener ); removeRadioListener( networkReadyListener ); networkReadyListener = null; } System.exit( 0 ); return true; } private final class NetworkRequiredTimerTask extends TimerTask { public void run() { if ( runState != STATE_RAN && SigservApplication.hasSufficientCoverage() ) { log.info( "Coverage is sufficient and startup is not completed, running startup" ); try { startup(); } catch (Exception e) { // do nothing } } if ( runState == STATE_RAN ) { requestClose(); } } } private final class MyNetworkReadyListener extends NetworkReadyListener { protected void onNetworkReady() throws Exception { if ( runState != STATE_RAN ) { log.info( "Network is ready and startup is not completed, running startup" ); startup(); } if ( runState == STATE_RAN ) { requestClose(); } } } }