00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 package com.github.rosjava.android_remocons.robot_remocon;
00036
00037 import java.net.URI;
00038 import java.net.URISyntaxException;
00039 import java.util.ArrayList;
00040
00041 import android.app.AlertDialog;
00042 import android.app.Dialog;
00043 import android.app.ProgressDialog;
00044 import android.content.DialogInterface;
00045 import android.content.Intent;
00046 import android.net.wifi.WifiManager;
00047 import android.os.AsyncTask;
00048 import android.os.Bundle;
00049 import android.util.Log;
00050 import android.view.Menu;
00051 import android.view.MenuItem;
00052 import android.view.View;
00053 import android.widget.AdapterView;
00054 import android.widget.AdapterView.OnItemClickListener;
00055 import android.widget.Button;
00056 import android.widget.GridView;
00057 import android.widget.TextView;
00058
00059 import org.ros.address.InetAddressFactory;
00060 import org.ros.android.NodeMainExecutorService;
00061 import org.ros.exception.RemoteException;
00062 import org.ros.exception.RosRuntimeException;
00063 import org.ros.message.MessageListener;
00064 import org.ros.node.NodeConfiguration;
00065 import org.ros.node.NodeMainExecutor;
00066 import org.ros.node.service.ServiceResponseListener;
00067 import com.github.rosjava.android_apps.application_management.AppManager;
00068 import com.github.rosjava.android_apps.application_management.ControlChecker;
00069 import com.github.rosjava.android_apps.application_management.MasterChecker;
00070 import com.github.rosjava.android_apps.application_management.RobotId;
00071 import com.github.rosjava.android_apps.application_management.RobotDescription;
00072 import com.github.rosjava.android_apps.application_management.WifiChecker;
00073 import com.github.rosjava.android_apps.application_management.rapp_manager.InvitationServiceClient;
00074
00075 import rocon_app_manager_msgs.App;
00076 import rocon_app_manager_msgs.AppList;
00077 import rocon_app_manager_msgs.StartAppResponse;
00078 import rocon_app_manager_msgs.ErrorCodes;
00079 import rocon_app_manager_msgs.StopAppResponse;
00080
00081 public class RobotRemocon extends RobotActivity {
00082
00083
00084 private static final int ROBOT_MASTER_CHOOSER_REQUEST_CODE = 1;
00085
00086 private static final int MULTI_RAPP_DISABLED = 1;
00087 private static final int CLOSE_EXISTING = 0;
00088
00089 private TextView robotNameView;
00090 private ArrayList<App> availableAppsCache;
00091 private ArrayList<App> runningAppsCache;
00092 private Button deactivate;
00093 private Button stopAppsButton;
00094 private Button exchangeButton;
00095 private ProgressDialog progress;
00096 private ProgressDialogWrapper progressDialog;
00097 private AlertDialogWrapper wifiDialog;
00098 private AlertDialogWrapper evictDialog;
00099 private AlertDialogWrapper errorDialog;
00100 protected AppManager listAppsSubscriber = null;
00101 private boolean alreadyClicked = false;
00102 private boolean validatedRobot;
00103 private boolean runningNodes = false;
00104 private long availableAppsCacheTime;
00105
00106 private void stopProgress() {
00107 Log.i("RobotRemocon", "Stopping the spinner");
00108 final ProgressDialog temp = progress;
00109 progress = null;
00110 if (temp != null) {
00111 runOnUiThread(new Runnable() {
00112 public void run() {
00113 temp.dismiss();
00114 }
00115 });
00116 }
00117 }
00118
00122 private class AlertDialogWrapper {
00123 private int state;
00124 private AlertDialog dialog;
00125 private RobotActivity context;
00126
00127 public AlertDialogWrapper(RobotActivity context,
00128 AlertDialog.Builder builder, String yesButton, String noButton) {
00129 state = 0;
00130 this.context = context;
00131 dialog = builder
00132 .setPositiveButton(yesButton,
00133 new DialogInterface.OnClickListener() {
00134 public void onClick(DialogInterface dialog,
00135 int which) {
00136 state = 1;
00137 }
00138 })
00139 .setNegativeButton(noButton,
00140 new DialogInterface.OnClickListener() {
00141 public void onClick(DialogInterface dialog,
00142 int which) {
00143 state = 2;
00144 }
00145 }).create();
00146 }
00147
00148 public AlertDialogWrapper(RobotActivity context,
00149 AlertDialog.Builder builder, String okButton) {
00150 state = 0;
00151 this.context = context;
00152 dialog = builder.setNeutralButton(okButton,
00153 new DialogInterface.OnClickListener() {
00154 public void onClick(DialogInterface dialog, int which) {
00155 state = 1;
00156 }
00157 }).create();
00158 }
00159
00160 public void setTitle(String m) {
00161 dialog.setTitle(m);
00162 }
00163
00164 public void setMessage(String m) {
00165 dialog.setMessage(m);
00166 }
00167
00168 public boolean show(String m) {
00169 setMessage(m);
00170 return show();
00171 }
00172
00173 public boolean show() {
00174 state = 0;
00175 context.runOnUiThread(new Runnable() {
00176 public void run() {
00177 dialog.show();
00178 }
00179 });
00180
00181 while (state == 0) {
00182 try {
00183 Thread.sleep(1L);
00184 } catch (Exception e) {
00185 break;
00186 }
00187 }
00188 dismiss();
00189 return state == 1;
00190 }
00191
00192 public void dismiss() {
00193 if (dialog != null) {
00194 dialog.dismiss();
00195 }
00196 dialog = null;
00197 }
00198 }
00199
00203 private class ProgressDialogWrapper {
00204 private ProgressDialog progressDialog;
00205 private RobotActivity activity;
00206
00207 public ProgressDialogWrapper(RobotActivity activity) {
00208 this.activity = activity;
00209 progressDialog = null;
00210 }
00211
00212 public void dismiss() {
00213 if (progressDialog != null) {
00214 progressDialog.dismiss();
00215 }
00216 progressDialog = null;
00217 }
00218
00219 public void show(String title, String text) {
00220 if (progressDialog != null) {
00221 this.dismiss();
00222 }
00223 progressDialog = ProgressDialog.show(activity, title, text, true,
00224 true);
00225 progressDialog.setCancelable(false);
00226 progressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
00227 }
00228 }
00229
00230 public RobotRemocon() {
00231 super("RobotRemocon", "RobotRemocon");
00232 availableAppsCacheTime = 0;
00233 availableAppsCache = new ArrayList<App>();
00234 runningAppsCache = new ArrayList<App>();
00235 }
00236
00238 @Override
00239 public void onCreate(Bundle savedInstanceState) {
00240 setDashboardResource(R.id.top_bar);
00241 setMainWindowResource(R.layout.main);
00242 super.onCreate(savedInstanceState);
00243
00244 robotNameView = (TextView) findViewById(R.id.robot_name_view);
00245 deactivate = (Button) findViewById(R.id.deactivate_robot);
00246 deactivate.setVisibility(deactivate.GONE);
00247 stopAppsButton = (Button) findViewById(R.id.stop_applications);
00248 stopAppsButton.setVisibility(stopAppsButton.GONE);
00249 exchangeButton = (Button) findViewById(R.id.exchange_button);
00250 exchangeButton.setVisibility(deactivate.GONE);
00251 }
00252
00265 @Override
00266 protected void init(NodeMainExecutor nodeMainExecutor) {
00267
00268 super.init(nodeMainExecutor);
00269
00270
00271
00272 listAppsSubscriber = new AppManager("", getRobotNameSpaceResolver());
00273 listAppsSubscriber.setAppListSubscriber(new MessageListener<AppList>() {
00274 @Override
00275 public void onNewMessage(AppList message) {
00276 availableAppsCache = (ArrayList<App>) message.getAvailableApps();
00277 runningAppsCache = (ArrayList<App>) message.getRunningApps();
00278 ArrayList<String> runningAppsNames = new ArrayList<String>();
00279 int i = 0;
00280 for (i = 0; i < availableAppsCache.size(); i++) {
00281 App item = availableAppsCache.get(i);
00282 ArrayList<String> clients = new ArrayList<String>();
00283 for (int j = 0; j < item.getPairingClients().size(); j++) {
00284 clients.add(item.getPairingClients().get(j)
00285 .getClientType());
00286 }
00287 if (!clients.contains("android")
00288 && item.getPairingClients().size() != 0) {
00289 availableAppsCache.remove(i);
00290 }
00291 if (item.getPairingClients().size() == 0) {
00292 Log.i("RobotRemocon",
00293 "Item name: " + item.getName());
00294 runningAppsNames.add(item.getName());
00295 }
00296 }
00297 Log.i("RobotRemocon", "AppList Publication: "
00298 + availableAppsCache.size() + " apps");
00299 availableAppsCacheTime = System.currentTimeMillis();
00300 runOnUiThread(new Runnable() {
00301 @Override
00302 public void run() {
00303 updateAppList(availableAppsCache,
00304 runningAppsCache);
00305 }
00306 });
00307 }
00308 });
00309 listAppsSubscriber.setFunction("list_apps");
00310 nodeMainExecutor.execute(listAppsSubscriber,
00311 nodeConfiguration.setNodeName("list_apps_subscriber_node"));
00312 }
00313
00327 void init(Intent intent) {
00328 URI uri;
00329 try {
00330 robotDescription = (RobotDescription) intent
00331 .getSerializableExtra(RobotDescription.UNIQUE_KEY);
00332
00333 robotNameResolver.setRobotName(robotDescription
00334 .getRobotName());
00335
00336 validatedRobot = false;
00337 validateRobot(robotDescription.getRobotId());
00338
00339 uri = new URI(robotDescription.getRobotId()
00340 .getMasterUri());
00341 } catch (URISyntaxException e) {
00342 throw new RosRuntimeException(e);
00343 }
00344 nodeMainExecutorService.setMasterUri(uri);
00345
00346
00347
00348
00349
00350
00351 new AsyncTask<Void, Void, Void>() {
00352 @Override
00353 protected Void doInBackground(Void... params) {
00354 while (!validatedRobot) {
00355
00356 }
00357 RobotRemocon.this.init(nodeMainExecutorService);
00358 return null;
00359 }
00360 }.execute();
00361 }
00371 @Override
00372 public void onActivityResult(int requestCode, int resultCode, Intent data) {
00373 if (resultCode == RESULT_CANCELED) {
00374 finish();
00375 } else if (resultCode == RESULT_OK) {
00376 if (requestCode == ROBOT_MASTER_CHOOSER_REQUEST_CODE) {
00377 init(data);
00378 } else {
00379
00380 nodeMainExecutorService.shutdown();
00381 finish();
00382 }
00383 }
00384 }
00385
00393 @Override
00394 public void startMasterChooser() {
00395 if (!fromApplication) {
00396 super.startActivityForResult(new Intent(this,
00397 RobotMasterChooser.class),
00398 ROBOT_MASTER_CHOOSER_REQUEST_CODE);
00399 } else {
00400 if (getIntent().hasExtra(RobotDescription.UNIQUE_KEY)) {
00401 init(getIntent());
00402 Log.i("RobotRemocon", "closing remocon application and successfully retrieved the robot description via intents.");
00403 } else {
00404 Log.e("RobotRemocon", "closing remocon application didn't return the robot description - *spank*.");
00405 }
00406 }
00407 }
00408
00409 public void validateRobot(final RobotId id) {
00410 wifiDialog = new AlertDialogWrapper(this, new AlertDialog.Builder(this)
00411 .setTitle("Change Wifi?").setCancelable(false), "Yes", "No");
00412 evictDialog = new AlertDialogWrapper(this,
00413 new AlertDialog.Builder(this).setTitle("Evict User?")
00414 .setCancelable(false), "Yes", "No");
00415 errorDialog = new AlertDialogWrapper(this,
00416 new AlertDialog.Builder(this).setTitle("Could Not Connect")
00417 .setCancelable(false), "Ok");
00418 progressDialog = new ProgressDialogWrapper(this);
00419 final AlertDialogWrapper wifiDialog = new AlertDialogWrapper(this,
00420 new AlertDialog.Builder(this).setTitle("Change Wifi?")
00421 .setCancelable(false), "Yes", "No");
00422
00423
00424
00425 final MasterChecker mc = new MasterChecker(
00426 new MasterChecker.RobotDescriptionReceiver() {
00427 public void receive(RobotDescription robotDescription) {
00428 runOnUiThread(new Runnable() {
00429 public void run() {
00430 final ProgressDialogWrapper p = progressDialog;
00431 if (p != null) {
00432 p.dismiss();
00433 }
00434 }
00435 });
00436 if(!fromApplication) {
00437
00438 if ( robotDescription.getConnectionStatus() == RobotDescription.UNAVAILABLE ) {
00439 errorDialog.show("Robot is unavailable : busy serving another remote controller.");
00440 errorDialog.dismiss();
00441 startMasterChooser();
00442 } else {
00443
00444
00445 NodeMainExecutorService nodeMainExecutorService = new NodeMainExecutorService();
00446 NodeConfiguration nodeConfiguration;
00447 try {
00448 URI uri = new URI(robotDescription.getMasterUri());
00449 nodeConfiguration = NodeConfiguration.newPublic(InetAddressFactory.newNonLoopback().getHostAddress(), uri);
00450 } catch (URISyntaxException e) {
00451 return;
00452 }
00453 InvitationServiceClient client = new InvitationServiceClient(robotDescription.getGatewayName(), robotDescription.getRobotName());
00454 nodeMainExecutorService.execute(client, nodeConfiguration.setNodeName("send_invitation_node"));
00455 Boolean result = client.waitForResponse();
00456 nodeMainExecutorService.shutdownNodeMain(client);
00457 if ( !result ) {
00458 errorDialog.show("Timed out trying to invite the robot for pairing mode.");
00459 errorDialog.dismiss();
00460 startMasterChooser();
00461 } else {
00462 if ( client.getInvitationResult().equals(Boolean.TRUE) ) {
00463 validatedRobot = true;
00464 } else {
00465 startMasterChooser();
00466 }
00467 }
00468 }
00469 } else {
00470
00471
00472
00473 validatedRobot = true;
00474 }
00475 }
00476 }, new MasterChecker.FailureHandler() {
00477 public void handleFailure(String reason) {
00478 final String reason2 = reason;
00479
00480 runOnUiThread(new Runnable() {
00481 public void run() {
00482 final ProgressDialogWrapper p = progressDialog;
00483 if (p != null) {
00484 p.dismiss();
00485 }
00486 }
00487 });
00488 errorDialog.show("Cannot contact ROS master: "
00489 + reason2);
00490 errorDialog.dismiss();
00491
00492 finish();
00493 }
00494 });
00495
00496
00497 final ControlChecker cc = new ControlChecker(
00498 new ControlChecker.SuccessHandler() {
00499 public void handleSuccess() {
00500 runOnUiThread(new Runnable() {
00501 public void run() {
00502 final ProgressDialogWrapper p = progressDialog;
00503 if (p != null) {
00504 p.dismiss();
00505 p.show("Connecting...",
00506 "Connecting to ROS master");
00507 }
00508 }
00509 });
00510 mc.beginChecking(id);
00511 }
00512 }, new ControlChecker.FailureHandler() {
00513 public void handleFailure(String reason) {
00514 final String reason2 = reason;
00515 runOnUiThread(new Runnable() {
00516 public void run() {
00517 final ProgressDialogWrapper p = progressDialog;
00518 if (p != null) {
00519 p.dismiss();
00520 }
00521 }
00522 });
00523 errorDialog.show("Cannot connect to control robot: "
00524 + reason2);
00525 errorDialog.dismiss();
00526 finish();
00527
00528 }
00529 }, new ControlChecker.EvictionHandler() {
00530 public boolean doEviction(String current, String message) {
00531 runOnUiThread(new Runnable() {
00532 public void run() {
00533 final ProgressDialogWrapper p = progressDialog;
00534 if (p != null) {
00535 p.dismiss();
00536 }
00537 }
00538 });
00539 String m = "";
00540 if (message != null) {
00541 m = " The user says: \"" + message + "\"";
00542 }
00543 evictDialog
00544 .setMessage(current
00545 + " is running custom software on this robot. Do you want to evict this user?"
00546 + m);
00547 runOnUiThread(new Runnable() {
00548 public void run() {
00549 final ProgressDialogWrapper p = progressDialog;
00550 if (p != null) {
00551 p.show("Connecting...",
00552 "Deactivating robot");
00553 }
00554 }
00555 });
00556 return evictDialog.show();
00557 }
00558
00559 @Override
00560 public boolean doEviction(String user) {
00561
00562 return false;
00563 }
00564 }, new ControlChecker.StartHandler() {
00565 public void handleStarting() {
00566 runOnUiThread(new Runnable() {
00567 public void run() {
00568 final ProgressDialogWrapper p = progressDialog;
00569 if (p != null) {
00570 p.dismiss();
00571 p.show("Connecting...", "Starting robot");
00572 }
00573 }
00574 });
00575 }
00576 });
00577
00578
00579 final WifiChecker wc = new WifiChecker(
00580 new WifiChecker.SuccessHandler() {
00581 public void handleSuccess() {
00582 runOnUiThread(new Runnable() {
00583 public void run() {
00584 final ProgressDialogWrapper p = progressDialog;
00585 if (p != null) {
00586 p.dismiss();
00587 p.show("Connecting...",
00588 "Checking robot state");
00589 }
00590 }
00591 });
00592 cc.beginChecking(id);
00593 }
00594 }, new WifiChecker.FailureHandler() {
00595 public void handleFailure(String reason) {
00596 final String reason2 = reason;
00597 runOnUiThread(new Runnable() {
00598 public void run() {
00599 final ProgressDialogWrapper p = progressDialog;
00600 if (p != null) {
00601 p.dismiss();
00602 }
00603 }
00604 });
00605 errorDialog.show("Cannot connect to robot WiFi: "
00606 + reason2);
00607 errorDialog.dismiss();
00608 finish();
00609 }
00610 }, new WifiChecker.ReconnectionHandler() {
00611 public boolean doReconnection(String from, String to) {
00612 runOnUiThread(new Runnable() {
00613 public void run() {
00614 final ProgressDialogWrapper p = progressDialog;
00615 if (p != null) {
00616 p.dismiss();
00617 }
00618 }
00619 });
00620 if (from == null) {
00621 wifiDialog
00622 .setMessage("To use this robot, you must connect to a wifi network. You are currently not connected to a wifi network. Would you like to connect to the correct wireless network?");
00623 } else {
00624 wifiDialog
00625 .setMessage("To use this robot, you must switch wifi networks. Do you want to switch from "
00626 + from + " to " + to + "?");
00627 }
00628 runOnUiThread(new Runnable() {
00629 public void run() {
00630 final ProgressDialogWrapper p = progressDialog;
00631 if (p != null) {
00632 p.show("Connecting...",
00633 "Switching wifi networks");
00634 }
00635 }
00636 });
00637 return wifiDialog.show();
00638 }
00639 });
00640 progressDialog.show("Connecting...", "Checking wifi connection");
00641 wc.beginChecking(id, (WifiManager) getSystemService(WIFI_SERVICE));
00642 }
00643
00644 public void onAppClicked(final App app, final boolean isClientApp) {
00645
00646 boolean running = false;
00647 for (App i : runningAppsCache) {
00648 if (i.getName().equals(app.getName())) {
00649 running = true;
00650 }
00651 }
00652
00653 if (!running && alreadyClicked == false) {
00654 alreadyClicked = true;
00655
00656 AppManager appManager = new AppManager(app.getName(),
00657 getRobotNameSpaceResolver());
00658 appManager.setFunction("start");
00659
00660 stopProgress();
00661 runOnUiThread(new Runnable() {
00662 @Override
00663 public void run() {
00664 stopProgress();
00665 progress = ProgressDialog.show(RobotRemocon.this,
00666 "Starting Rapp",
00667 "Starting " + app.getDisplayName() + "...", true,
00668 false);
00669 progress.setProgressStyle(ProgressDialog.STYLE_SPINNER);
00670 }
00671 });
00672
00673 appManager
00674 .setStartService(new ServiceResponseListener<StartAppResponse>() {
00675 @Override
00676 public void onSuccess(StartAppResponse message) {
00677 if (message.getStarted()) {
00678 Log.i("RobotRemocon", "Rapp started successfully [" + app.getDisplayName() + "]");
00679 alreadyClicked = false;
00680
00681 } else if (message.getErrorCode() == ErrorCodes.MULTI_RAPP_NOT_SUPPORTED) {
00682 runOnUiThread(new Runnable() {
00683 @Override
00684 public void run() {
00685 showDialog(MULTI_RAPP_DISABLED);
00686 }
00687 });
00688
00689 } else {
00690 Log.w("RobotRemocon", message.getMessage());
00691
00692 }
00693 stopProgress();
00694 }
00695
00696 @Override
00697 public void onFailure(RemoteException e) {
00698
00699 stopProgress();
00700 }
00701 });
00702
00703 nodeMainExecutor.execute(appManager,
00704 nodeConfiguration.setNodeName("start_app"));
00705
00706 }
00707 }
00708
00709 protected void updateAppList(final ArrayList<App> apps,
00710 final ArrayList<App> runningApps) {
00711 Log.d("RobotRemocon", "updating app list gridview");
00712 GridView gridview = (GridView) findViewById(R.id.gridview);
00713 AppAdapter appAdapter = new AppAdapter(RobotRemocon.this, apps,
00714 runningApps);
00715 gridview.setAdapter(appAdapter);
00716 registerForContextMenu(gridview);
00717 gridview.setOnItemClickListener(new OnItemClickListener() {
00718 @Override
00719 public void onItemClick(AdapterView<?> parent, View v,
00720 int position, long id) {
00721
00722 App app = availableAppsCache.get(position);
00723
00724 if (runningAppsCache.size() > 0) {
00725 runningNodes = true;
00726 Log.i("RobotRemocon", "RunningAppsCache greater than zero.");
00727 }
00728
00729 if (AppLauncher.launch(RobotRemocon.this, apps.get(position),
00730 getMasterUri(), robotDescription, runningNodes) == true) {
00731 if (progress != null) {
00732 progress.dismiss();
00733 }
00734 finish();
00735 } else
00736 onAppClicked(app, true);
00737 }
00738 });
00739 if (runningApps != null) {
00740 if (runningApps.toArray().length != 0) {
00741 stopAppsButton.setVisibility(stopAppsButton.VISIBLE);
00742 } else {
00743 stopAppsButton.setVisibility(stopAppsButton.GONE);
00744 }
00745 }
00746 Log.d("RobotRemocon", "app list gridview updated");
00747 }
00748
00749 public void chooseNewMasterClicked(View view) {
00750
00751 InvitationServiceClient client = new InvitationServiceClient(robotDescription.getGatewayName(), robotDescription.getRobotName(), Boolean.TRUE);
00752 nodeMainExecutorService.execute(client, nodeConfiguration.setNodeName("send_uninvitation_node"));
00753 Boolean result = client.waitForResponse();
00754 nodeMainExecutorService.shutdownNodeMain(client);
00755 if ( !result ) {
00756 errorDialog.show("Timed out trying to invite the robot for pairing mode.");
00757 errorDialog.dismiss();
00758 }
00759 returnToRobotMasterChooser();
00760 }
00761
00767 private void returnToRobotMasterChooser() {
00768 if (pairingApplicationNamePublisher != null) {
00769 nodeMainExecutor.shutdownNodeMain(pairingApplicationNamePublisher);
00770 }
00771 if (listAppsSubscriber != null) {
00772 nodeMainExecutor.shutdownNodeMain(listAppsSubscriber);
00773 }
00774 releaseRobotNameResolver();
00775 releaseDashboardNode();
00776 availableAppsCache.clear();
00777 runningAppsCache.clear();
00778 startActivityForResult(new Intent(this, RobotMasterChooser.class),
00779 ROBOT_MASTER_CHOOSER_REQUEST_CODE);
00780 }
00781
00782 public void exchangeButtonClicked(View view) {
00783 }
00784
00785 public void deactivateRobotClicked(View view) {
00786 }
00787
00793 public void stopRobotApplication() {
00794
00795
00796
00797 AppManager appManager = new AppManager("*", getRobotNameSpaceResolver());
00798 appManager.setFunction("stop");
00799 appManager
00800 .setStopService(new ServiceResponseListener<StopAppResponse>() {
00801 @Override
00802 public void onSuccess(StopAppResponse message) {
00803 Log.i("RobotRemocon", "app stopped successfully");
00804 availableAppsCache = new ArrayList<App>();
00805 runningAppsCache = new ArrayList<App>();
00806 runOnUiThread(new Runnable() {
00807 @Override
00808 public void run() {
00809 updateAppList(availableAppsCache,
00810 runningAppsCache);
00811 }
00812 });
00813 progressDialog.dismiss();
00814
00815 }
00816
00817 @Override
00818 public void onFailure(RemoteException e) {
00819 Log.e("RobotRemocon", "app failed to stop!");
00820 }
00821 });
00822 nodeMainExecutor.execute(appManager,
00823 nodeConfiguration.setNodeName("stop_app"));
00824 }
00825
00834 public void stopApplicationsClicked(View view) {
00835
00836
00837
00838
00839
00840
00841
00842
00843
00844
00845 progressDialog = new ProgressDialogWrapper(this);
00846 progressDialog.show("Stopping Applications",
00847 "Stopping all applications...");
00848 stopRobotApplication();
00849 }
00850
00851 @Override
00852 public boolean onCreateOptionsMenu(Menu menu) {
00853 menu.add(0, 0, 0, R.string.exit);
00854 return super.onCreateOptionsMenu(menu);
00855 }
00856
00857 @Override
00858 public boolean onOptionsItemSelected(MenuItem item) {
00859 super.onOptionsItemSelected(item);
00860 switch (item.getItemId()) {
00861 case 0:
00862 finish();
00863 break;
00864 }
00865 return true;
00866 }
00867
00868 @Override
00869 protected Dialog onCreateDialog(int id) {
00870
00871 final Dialog dialog;
00872 Button button;
00873 AlertDialog.Builder builder = new AlertDialog.Builder(this);
00874 switch (id) {
00875 case CLOSE_EXISTING:
00876 builder.setTitle("Stop Current Application?");
00877 builder.setMessage("There is an application already running. You cannot run two applications at once. Would you like to stop the current application?");
00878
00879
00880
00881
00882 dialog = builder.create();
00883 break;
00884 case MULTI_RAPP_DISABLED:
00885 builder.setTitle("Multi-App Disabled on Robot");
00886 builder.setMessage("The mode for running multiple apps is disabled on the robot. If you would like to enable it then you can change the arguments that the App Manager gets in its launch file.");
00887
00888 dialog = builder.create();
00889 break;
00890 default:
00891 dialog = null;
00892
00893 }
00894 return dialog;
00895 }
00896
00897 @Override
00898 public void onBackPressed() {
00899
00900
00901 finish();
00902 }
00903 }