package org.ccnx.android.examples.startup; import java.io.File; import java.io.IOException; import java.security.InvalidKeyException; import java.util.concurrent.CountDownLatch; import org.ccnx.android.ccnlib.CCNxConfiguration; import org.ccnx.android.ccnlib.CCNxServiceCallback; import org.ccnx.android.ccnlib.CCNxServiceControl; 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 org.ccnx.ccn.config.ConfigurationException; import org.ccnx.ccn.config.UserConfiguration; import org.ccnx.ccn.profiles.ccnd.CCNDaemonException; import android.content.Context; import android.os.Bundle; import android.util.Log; import android.widget.TextView; public class BlockingStartup extends StartupBase { protected String TAG="BlockingStartup"; // =========================================================================== // Process control Methods /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); TextView title = (TextView) findViewById(R.id.tvTitle); title.setText("BlockingStartup"); } @Override public void onStart() { super.onStart(); Log.i(TAG,"onStart"); _worker = new BlockingWorker(); _thd = new Thread(_worker); _thd.start(); } @Override public void onResume() { super.onResume(); Log.i(TAG,"onResume"); } @Override public void onPause() { super.onPause(); Log.i(TAG,"onPause"); } @Override public void onStop() { super.onPause(); Log.i(TAG,"onStop"); _worker.stop(); } @Override public void onDestroy() { Log.i(TAG, "onDestroy()"); _worker.stop(); super.onDestroy(); } // =========================================================================== // UI Methods @Override void doExit() { } @Override void doShutdown() { _worker.shutdown(); } // ==================================================================== // Internal implementation protected BlockingWorker _worker = null; protected Thread _thd = null; // =============================================== protected class BlockingWorker implements Runnable, CCNxServiceCallback { protected final static String TAG="BlockingWorker"; /** * Create a worker thread to handle all the CCNx calls. */ public BlockingWorker() { _context = BlockingStartup.this.getBaseContext(); postToUI("Setting CCNxConfiguration"); // Use a shared key directory CCNxConfiguration.config(_context, false); File ff = getDir("storage", Context.MODE_WORLD_READABLE); postToUI("Setting setUserConfigurationDirectory: " + ff.getAbsolutePath()); Log.i(TAG,"getDir = " + ff.getAbsolutePath()); UserConfiguration.setUserConfigurationDirectory( ff.getAbsolutePath() ); // Do these CCNx operations after we created ChatWorker ScreenOutput("User name = " + UserConfiguration.userName()); ScreenOutput("ccnDir = " + UserConfiguration.userConfigurationDirectory()); ScreenOutput("Waiting for CCN Services to become ready"); } /** * Exit the worker thread, but keep services running */ public synchronized void stop() { // this is called form onDestroy too, so only do something // if the user didn't select a menu option to exit or shutdown. if( _latch.getCount() > 0 ) { _latch.countDown(); _ccnxService.disconnect(); } } /** * Exit the worker thread and shutdown services */ public synchronized void shutdown() { _latch.countDown(); try { _ccnxService.stopAll(); } catch(Exception e) { e.printStackTrace(); } } /** * Runnable method */ @Override public void run() { // Startup CCNx in a blocking call postToUI("Starting CCNx in blocking mode"); if( !initializeCCNx() ) { Log.e(TAG, "Could not start CCNx services!"); } // wait for shutdown postToUI("Worker thread now blocking until exit"); while( _latch.getCount() > 0 ) { try { _latch.await(); } catch (InterruptedException e) { } } Log.i(TAG, "service_run() exits"); } // ============================================================================== // Internal implementation protected final CountDownLatch _latch = new CountDownLatch(1); protected final Context _context; protected CCNxServiceControl _ccnxService; /*********************************************/ // These are all run in the CCN thread private boolean initializeCCNx() { _ccnxService = new CCNxServiceControl(_context); _ccnxService.registerCallback(this); _ccnxService.setCcndOption(CCND_OPTIONS.CCND_DEBUG, "1"); _ccnxService.setRepoOption(REPO_OPTIONS.REPO_DEBUG, LOG_LEVEL); postToUI("calling _ccnxService.startAll"); return _ccnxService.startAll(); } /** * Called from CCNxServiceControl */ @Override public void newCCNxStatus(SERVICE_STATUS st) { postToUI("CCNxStatus: " + st.toString()); switch(st) { case START_ALL_DONE: try { postToUI("Opening CCN key manager/handle"); openCcn(); setupFace(); postToUI("Finished CCNx Initialization"); } catch (CCNDaemonException e) { e.printStackTrace(); postToUI("SimpleFaceControl error: " + e.getMessage()); } catch (ConfigurationException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (InvalidKeyException e) { // TODO Auto-generated catch block e.printStackTrace(); } break; case START_ALL_ERROR: postToUI("CCNxStatus ERROR"); break; } } } }