/* * CCNx Android Helper Library. * * Copyright (C) 2010, 2011 Palo Alto Research Center, Inc. * * This library is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License version 2.1 * as published by the Free Software Foundation. * This library 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 * Lesser General Public License for more details. You should have received * a copy of the GNU Lesser General Public License along with this library; * if not, write to the Free Software Foundation, Inc., 51 Franklin Street, * Fifth Floor, Boston, MA 02110-1301 USA. */ package org.ccnx.android.ccnlib; import org.ccnx.android.ccnlib.CCNxServiceStatus.SERVICE_STATUS; import org.ccnx.android.ccnlib.CcndWrapper.CCND_OPTIONS; import org.ccnx.android.ccnlib.RepoWrapper.REPO_OPTIONS; import android.content.Context; import android.util.Log; /** * This is a helper class to access the ccnd and repo services. It provides * abstractions so that the programs can start and stop the services as well * as interact with them for configuration and monitoring. */ public final class CCNxServiceControl { private final static String TAG = "CCNxServiceControl"; CcndWrapper ccndInterface; RepoWrapper repoInterface; Context _ctx; CCNxServiceCallback _cb = null; SERVICE_STATUS ccndStatus = SERVICE_STATUS.SERVICE_OFF; SERVICE_STATUS repoStatus = SERVICE_STATUS.SERVICE_OFF; CCNxServiceCallback ccndCallback = new CCNxServiceCallback(){ @Override public void newCCNxStatus(SERVICE_STATUS st) { Log.i(TAG,"ccndCallback ccndStatus = " + st.toString()); ccndStatus = st; switch(ccndStatus){ case SERVICE_OFF: newCCNxAPIStatus(SERVICE_STATUS.CCND_OFF); break; case SERVICE_INITIALIZING: newCCNxAPIStatus(SERVICE_STATUS.CCND_INITIALIZING); break; case SERVICE_TEARING_DOWN: newCCNxAPIStatus(SERVICE_STATUS.CCND_TEARING_DOWN); break; case SERVICE_RUNNING: newCCNxAPIStatus(SERVICE_STATUS.CCND_RUNNING); break; } } }; CCNxServiceCallback repoCallback = new CCNxServiceCallback(){ @Override public void newCCNxStatus(SERVICE_STATUS st) { Log.i(TAG,"repoCallback repoStatus = " + st.toString()); repoStatus = st; switch(repoStatus){ case SERVICE_OFF: newCCNxAPIStatus(SERVICE_STATUS.REPO_OFF); break; case SERVICE_INITIALIZING: newCCNxAPIStatus(SERVICE_STATUS.REPO_INITIALIZING); break; case SERVICE_TEARING_DOWN: newCCNxAPIStatus(SERVICE_STATUS.REPO_TEARING_DOWN); break; case SERVICE_RUNNING: newCCNxAPIStatus(SERVICE_STATUS.REPO_RUNNING); break; } } }; public CCNxServiceControl(Context ctx) { _ctx = ctx; ccndInterface = new CcndWrapper(_ctx); ccndInterface.setCallback(ccndCallback); ccndStatus = ccndInterface.getStatus(); repoInterface = new RepoWrapper(_ctx); repoInterface.setCallback(repoCallback); repoStatus = repoInterface.getStatus(); } public void registerCallback(CCNxServiceCallback cb){ _cb = cb; } public void unregisterCallback(){ _cb = null; } /** * Start the CCN daemon and Repo * If configuration parameters have been set these will be used * This is a BLOCKING call * * @return true if everything started correctly, false otherwise */ public boolean startAll(){ newCCNxAPIStatus(SERVICE_STATUS.START_ALL_INITIALIZING); Log.i(TAG,"startAll waitng for startService"); ccndInterface.startService(); Log.i(TAG,"startAll waitng for waitForReady"); ccndInterface.waitForReady(); newCCNxAPIStatus(SERVICE_STATUS.START_ALL_CCND_DONE); if(!ccndInterface.isReady()){ newCCNxAPIStatus(SERVICE_STATUS.START_ALL_ERROR); return false; } repoInterface.startService(); repoInterface.waitForReady(); if(!repoInterface.isReady()){ newCCNxAPIStatus(SERVICE_STATUS.START_ALL_ERROR); return false; } newCCNxAPIStatus(SERVICE_STATUS.START_ALL_DONE); return true; } /** * Start the CCN daemon and Repo * If configuration parameters have been set these will be used * This is a non-blocking call. If you want to be notified when everything * has started then you should register a callback before issuing this call. */ public void startAllInBackground(){ Runnable r = new Runnable(){ public void run() { startAll(); } }; Thread thd = new Thread(r); thd.start(); } public void connect(){ ccndInterface.bindIfRunning(); repoInterface.bindIfRunning(); } /** * Disconnect from the services. This is needed for a clean exit from an application. It leaves the services running. */ public void disconnect(){ ccndInterface.unbindService(); repoInterface.unbindService(); } /** * Stop the CCN daemon and Repo * This call will unbind from the service and stop it. There is no need to issue a disconnect(). */ public void stoptAll(){ repoInterface.stopService(); ccndInterface.stopService(); } public boolean isCcndRunning(){ return ccndInterface.isRunning(); } public boolean isRepoRunning(){ return repoInterface.isRunning(); } public void startCcnd(){ ccndInterface.startService(); } public void stopCcnd(){ ccndInterface.stopService(); } public void startRepo(){ repoInterface.startService(); } public void stopRepo(){ repoInterface.stopService(); } public void newCCNxAPIStatus(SERVICE_STATUS s){ Log.d(TAG,"newCCNxAPIStatus sending " + s.toString()); try { if(_cb != null) { _cb.newCCNxStatus(s); } } catch(Exception e){ // Did the callback just throw an exception?? // We're going to ignore it, it's not our problem (right?) Log.e(TAG,"The client callback has thrown an exception"); e.printStackTrace(); } } public void setCcndOption(CCND_OPTIONS option, String value) { ccndInterface.setOption(option, value); } public void setRepoOption(REPO_OPTIONS option, String value) { repoInterface.setOption(option, value); } /** * Are ccnd and the repo running and ready? * @return true if BOTH ccnd and the repo are in state Running */ public boolean allReady(){ return(SERVICE_STATUS.SERVICE_RUNNING.equals(ccndStatus) && SERVICE_STATUS.SERVICE_RUNNING.equals(repoStatus)); } public SERVICE_STATUS getCcndStatus(){ return ccndStatus; } public SERVICE_STATUS getRepoStatus(){ return repoStatus; } }