Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 package com.github.rosjava.android_apps.application_management;
00018
00019 import java.net.URI;
00020 import java.net.URISyntaxException;
00021
00022 import android.app.AlertDialog;
00023 import android.content.DialogInterface;
00024 import android.content.Intent;
00025 import android.os.AsyncTask;
00026 import android.os.Bundle;
00027 import android.util.Log;
00028 import android.view.Window;
00029 import android.view.WindowManager;
00030 import android.widget.LinearLayout;
00031
00032 import org.ros.address.InetAddressFactory;
00033 import org.ros.android.RosActivity;
00034 import org.ros.exception.RemoteException;
00035 import org.ros.exception.RosRuntimeException;
00036 import org.ros.namespace.NameResolver;
00037 import org.ros.node.NodeConfiguration;
00038 import org.ros.node.NodeMainExecutor;
00039 import org.ros.node.service.ServiceResponseListener;
00040
00041 import com.github.rosjava.android_apps.application_management.rapp_manager.PairingApplicationNamePublisher;
00042
00043 import rocon_app_manager_msgs.StartAppResponse;
00044 import rocon_app_manager_msgs.StopAppResponse;
00045
00049 public abstract class RosAppActivity extends RosActivity {
00050
00051 private String robotAppName = null;
00052 private String defaultRobotAppName = null;
00053 private String defaultRobotName = null;
00054 private String androidApplicationName;
00055
00056
00057
00058
00059
00060 private boolean managedApplication = false;
00061 private String managedApplicationActivity = null;
00062 private PairingApplicationNamePublisher managedPairingApplicationNamePublisher;
00063
00064 private int dashboardResourceId = 0;
00065 private int mainWindowId = 0;
00066 private Dashboard dashboard = null;
00067 private NodeConfiguration nodeConfiguration;
00068 private NodeMainExecutor nodeMainExecutor;
00069 private URI uri;
00070 protected RobotNameResolver robotNameResolver;
00071 protected RobotDescription robotDescription;
00072
00073 protected void setDashboardResource(int resource) {
00074 dashboardResourceId = resource;
00075 }
00076
00077 protected void setMainWindowResource(int resource) {
00078 mainWindowId = resource;
00079 }
00080
00081 protected void setDefaultRobotName(String name) {
00082 defaultRobotName = name;
00083 }
00084
00085 protected void setDefaultAppName(String name) {
00086 defaultRobotAppName = name;
00087 }
00088
00089 protected void setCustomDashboardPath(String path) {
00090 dashboard.setCustomDashboardPath(path);
00091 }
00092
00093 protected RosAppActivity(String notificationTicker, String notificationTitle) {
00094 super(notificationTicker, notificationTitle);
00095 this.androidApplicationName = notificationTitle;
00096 }
00097
00098 @Override
00099 public void onCreate(Bundle savedInstanceState) {
00100 super.onCreate(savedInstanceState);
00101
00102 if (mainWindowId == 0) {
00103 Log.e("ApplicationManagement",
00104 "You must set the dashboard resource ID in your RosAppActivity");
00105 return;
00106 }
00107 if (dashboardResourceId == 0) {
00108 Log.e("ApplicationManagement",
00109 "You must set the dashboard resource ID in your RosAppActivity");
00110 return;
00111 }
00112
00113 requestWindowFeature(Window.FEATURE_NO_TITLE);
00114 getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
00115 WindowManager.LayoutParams.FLAG_FULLSCREEN);
00116 setContentView(mainWindowId);
00117
00118 robotNameResolver = new RobotNameResolver();
00119
00120 if (defaultRobotName != null) {
00121 robotNameResolver.setRobotName(defaultRobotName);
00122 }
00123
00124 robotAppName = getIntent().getStringExtra(AppManager.PACKAGE + ".robot_app_name");
00125 if (robotAppName == null) {
00126 robotAppName = defaultRobotAppName;
00127 } else {
00128 managedApplicationActivity = getIntent().getStringExtra("PairedManagerActivity");
00129 managedPairingApplicationNamePublisher = new PairingApplicationNamePublisher(this.androidApplicationName);
00130 managedApplication = true;
00131 }
00132
00133 if (dashboard == null) {
00134 dashboard = new Dashboard(this);
00135 dashboard.setView((LinearLayout) findViewById(dashboardResourceId),
00136 new LinearLayout.LayoutParams(
00137 LinearLayout.LayoutParams.WRAP_CONTENT,
00138 LinearLayout.LayoutParams.WRAP_CONTENT));
00139 }
00140
00141 }
00142
00143 @Override
00144 protected void init(NodeMainExecutor nodeMainExecutor) {
00145 this.nodeMainExecutor = nodeMainExecutor;
00146 nodeConfiguration = NodeConfiguration.newPublic(InetAddressFactory
00147 .newNonLoopback().getHostAddress(), getMasterUri());
00148
00149 if ( managedApplication ) {
00150 if (getIntent().hasExtra(RobotDescription.UNIQUE_KEY)) {
00151 robotDescription = (RobotDescription) getIntent()
00152 .getSerializableExtra(RobotDescription.UNIQUE_KEY);
00153 }
00154 nodeMainExecutor.execute(managedPairingApplicationNamePublisher,
00155 nodeConfiguration.setNodeName("pairingApplicationNamePublisher"));
00156 }
00157 if (robotDescription != null) {
00158 robotNameResolver.setRobot(robotDescription);
00159 dashboard.setRobotName(robotDescription.getRobotType());
00160 }
00161 nodeMainExecutor.execute(robotNameResolver,
00162 nodeConfiguration.setNodeName("robotNameResolver"));
00163 robotNameResolver.waitForResolver();
00164
00165 if (robotDescription == null) {
00166 dashboard.setRobotName(getRobotNameSpace().getNamespace()
00167 .toString());
00168 }
00169
00170 nodeMainExecutor.execute(dashboard,
00171 nodeConfiguration.setNodeName("dashboard"));
00172
00173
00174
00175
00176
00177
00178 if ( managePairedRobotApplication() ) {
00179 Log.w("ApplicationManagement", "starting a rapp");
00180 startApp();
00181 }
00182 }
00183
00184 protected NameResolver getAppNameSpace() {
00185 return robotNameResolver.getAppNameSpace();
00186 }
00187
00188 protected NameResolver getRobotNameSpace() {
00189 return robotNameResolver.getRobotNameSpace();
00190 }
00191
00192 protected void onAppTerminate() {
00193 RosAppActivity.this.runOnUiThread(new Runnable() {
00194 @Override
00195 public void run() {
00196 new AlertDialog.Builder(RosAppActivity.this)
00197 .setTitle("App Termination")
00198 .setMessage(
00199 "The application has terminated on the server, so the client is exiting.")
00200 .setCancelable(false)
00201 .setNeutralButton("Exit",
00202 new DialogInterface.OnClickListener() {
00203 public void onClick(DialogInterface dialog,
00204 int which) {
00205 RosAppActivity.this.finish();
00206 }
00207 }).create().show();
00208 }
00209 });
00210 }
00211
00212 @Override
00213 public void startMasterChooser() {
00214 if (!managedApplication) {
00215 super.startMasterChooser();
00216 } else {
00217 Intent intent = new Intent();
00218 intent.putExtra(AppManager.PACKAGE + ".robot_app_name",
00219 "AppChooser");
00220 try {
00221 uri = new URI(getIntent().getStringExtra("ChooserURI"));
00222 } catch (URISyntaxException e) {
00223 throw new RosRuntimeException(e);
00224 }
00225
00226 nodeMainExecutorService.setMasterUri(uri);
00227 new AsyncTask<Void, Void, Void>() {
00228 @Override
00229 protected Void doInBackground(Void... params) {
00230 RosAppActivity.this.init(nodeMainExecutorService);
00231 return null;
00232 }
00233 }.execute();
00234 }
00235
00236 }
00237
00238 private void restartApp() {
00239 Log.i("RosAndroid", "Restarting application");
00240 AppManager appManager = new AppManager("*", getRobotNameSpace());
00241 appManager.setFunction("stop");
00242
00243 appManager
00244 .setStopService(new ServiceResponseListener<StopAppResponse>() {
00245 @Override
00246 public void onSuccess(StopAppResponse message) {
00247 Log.i("RosAndroid", "App stopped successfully");
00248 try {
00249 Thread.sleep(1000);
00250 } catch (Exception e) {
00251
00252 }
00253 startApp();
00254 }
00255
00256 @Override
00257 public void onFailure(RemoteException e) {
00258 Log.e("RosAndroid", "App failed to stop!");
00259 }
00260 });
00261 nodeMainExecutor.execute(appManager,
00262 nodeConfiguration.setNodeName("start_app"));
00263
00264 }
00265
00270 private void startApp() {
00271 Log.i("ApplicationManagement", "android application starting a rapp [" + robotAppName + "]");
00272
00273 AppManager appManager = new AppManager(robotAppName,
00274 getRobotNameSpace());
00275 appManager.setFunction("start");
00276
00277 appManager
00278 .setStartService(new ServiceResponseListener<StartAppResponse>() {
00279 @Override
00280 public void onSuccess(StartAppResponse message) {
00281 if (message.getStarted()) {
00282 Log.i("ApplicationManagement", "rapp started successfully [" + robotAppName + "]");
00283 } else {
00284 Log.e("ApplicationManagement", "rapp failed to start! [" + message.getMessage() + "]");
00285 }
00286 }
00287
00288 @Override
00289 public void onFailure(RemoteException e) {
00290 Log.e("ApplicationManagement", "rapp failed to start - no response!");
00291 }
00292 });
00293
00294 nodeMainExecutor.execute(appManager,
00295 nodeConfiguration.setNodeName("start_app"));
00296 }
00297
00298 protected void stopApp() {
00299 Log.i("ApplicationManagement", "android application stopping a rapp [" + robotAppName + "]");
00300 AppManager appManager = new AppManager(robotAppName,
00301 getRobotNameSpace());
00302 appManager.setFunction("stop");
00303
00304 appManager
00305 .setStopService(new ServiceResponseListener<StopAppResponse>() {
00306 @Override
00307 public void onSuccess(StopAppResponse message) {
00308 if ( message.getStopped() ) {
00309 Log.i("ApplicationManagement", "App stopped successfully");
00310 } else {
00311 Log.i("ApplicationManagement", "Stop app request rejected [" + message.getMessage() + "]");
00312 }
00313 }
00314
00315 @Override
00316 public void onFailure(RemoteException e) {
00317 Log.e("ApplicationManagement", "App failed to stop when requested!");
00318 }
00319 });
00320 nodeMainExecutor.execute(appManager,
00321 nodeConfiguration.setNodeName("stop_app"));
00322 }
00323
00324 protected void releaseRobotNameResolver() {
00325 nodeMainExecutor.shutdownNodeMain(robotNameResolver);
00326 }
00327
00328 protected void releaseDashboardNode() {
00329 nodeMainExecutor.shutdownNodeMain(dashboard);
00330 }
00331
00342 private boolean managePairedRobotApplication() {
00343 return (!managedApplication && (robotAppName != null));
00344 }
00345
00346 @Override
00347 protected void onDestroy() {
00348 if ( ( getRobotNameSpace() != null ) && managePairedRobotApplication() ) {
00349 stopApp();
00350 }
00351 super.onDestroy();
00352 }
00353
00354 @Override
00355 public void onBackPressed() {
00356 if (managedApplication) {
00357 Log.i("ApplicationManagement", "app terminating and returning control to the remocon.");
00358
00359 Intent intent = new Intent();
00360 intent.putExtra(AppManager.PACKAGE + ".robot_app_name",
00361 "AppChooser");
00362 intent.putExtra(RobotDescription.UNIQUE_KEY, robotDescription);
00363 intent.putExtra("ChooserURI", uri.toString());
00364
00365
00366 intent.setAction(managedApplicationActivity);
00367
00368 intent.addCategory("android.intent.category.DEFAULT");
00369 startActivity(intent);
00370 finish();
00371 } else {
00372 Log.i("ApplicationManagement", "backpress processing for RosAppActivity");
00373 }
00374 super.onBackPressed();
00375 }
00376 }