NodeMainExecutorService.java
Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2011 Google Inc.
00003  *
00004  * Licensed under the Apache License, Version 2.0 (the "License"); you may not
00005  * use this file except in compliance with the License. You may obtain a copy of
00006  * the License at
00007  *
00008  * http://www.apache.org/licenses/LICENSE-2.0
00009  *
00010  * Unless required by applicable law or agreed to in writing, software
00011  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
00012  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
00013  * License for the specific language governing permissions and limitations under
00014  * the License.
00015  */
00016 
00017 package org.ros.android;
00018 
00019 import com.google.common.base.Preconditions;
00020 
00021 import android.app.AlertDialog;
00022 import android.app.Notification;
00023 import android.app.PendingIntent;
00024 import android.app.Service;
00025 import android.content.DialogInterface;
00026 import android.content.DialogInterface.OnClickListener;
00027 import android.content.Intent;
00028 import android.net.wifi.WifiManager;
00029 import android.net.wifi.WifiManager.WifiLock;
00030 import android.os.AsyncTask;
00031 import android.os.Binder;
00032 import android.os.Handler;
00033 import android.os.IBinder;
00034 import android.os.PowerManager;
00035 import android.os.PowerManager.WakeLock;
00036 import android.util.Log;
00037 import android.view.WindowManager;
00038 import android.widget.Toast;
00039 import org.ros.RosCore;
00040 import org.ros.android.android_10.R;
00041 import org.ros.address.InetAddressFactory;
00042 import org.ros.concurrent.ListenerGroup;
00043 import org.ros.concurrent.SignalRunnable;
00044 import org.ros.exception.RosRuntimeException;
00045 import org.ros.node.DefaultNodeMainExecutor;
00046 import org.ros.node.NodeConfiguration;
00047 import org.ros.node.NodeListener;
00048 import org.ros.node.NodeMain;
00049 import org.ros.node.NodeMainExecutor;
00050 
00051 import java.net.URI;
00052 import java.util.Collection;
00053 import java.util.concurrent.ExecutionException;
00054 import java.util.concurrent.ScheduledExecutorService;
00055 
00059 public class NodeMainExecutorService extends Service implements NodeMainExecutor {
00060 
00061   private static final String TAG = "NodeMainExecutorService";
00062 
00063   // NOTE(damonkohler): If this is 0, the notification does not show up.
00064   private static final int ONGOING_NOTIFICATION = 1;
00065 
00066   public static final String ACTION_START = "org.ros.android.ACTION_START_NODE_RUNNER_SERVICE";
00067   public static final String ACTION_SHUTDOWN = "org.ros.android.ACTION_SHUTDOWN_NODE_RUNNER_SERVICE";
00068   public static final String EXTRA_NOTIFICATION_TITLE = "org.ros.android.EXTRA_NOTIFICATION_TITLE";
00069   public static final String EXTRA_NOTIFICATION_TICKER = "org.ros.android.EXTRA_NOTIFICATION_TICKER";
00070 
00071   private final NodeMainExecutor nodeMainExecutor;
00072   private final IBinder binder;
00073   private final ListenerGroup<NodeMainExecutorServiceListener> listeners;
00074 
00075   private Handler handler;
00076   private WakeLock wakeLock;
00077   private WifiLock wifiLock;
00078   private RosCore rosCore;
00079   private URI masterUri;
00080   private String rosHostname;
00081 
00086   public class LocalBinder extends Binder {
00087     public NodeMainExecutorService getService() {
00088       return NodeMainExecutorService.this;
00089     }
00090   }
00091 
00092   public NodeMainExecutorService() {
00093     super();
00094     rosHostname = null;
00095     nodeMainExecutor = DefaultNodeMainExecutor.newDefault();
00096     binder = new LocalBinder();
00097     listeners =
00098         new ListenerGroup<NodeMainExecutorServiceListener>(
00099             nodeMainExecutor.getScheduledExecutorService());
00100   }
00101 
00102   @Override
00103   public void onCreate() {
00104     handler = new Handler();
00105     PowerManager powerManager = (PowerManager) getSystemService(POWER_SERVICE);
00106     wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
00107     wakeLock.acquire();
00108     int wifiLockType = WifiManager.WIFI_MODE_FULL;
00109     try {
00110       wifiLockType = WifiManager.class.getField("WIFI_MODE_FULL_HIGH_PERF").getInt(null);
00111     } catch (Exception e) {
00112       // We must be running on a pre-Honeycomb device.
00113       Log.w(TAG, "Unable to acquire high performance wifi lock.");
00114     }
00115     WifiManager wifiManager = (WifiManager) getSystemService(WIFI_SERVICE);
00116     wifiLock = wifiManager.createWifiLock(wifiLockType, TAG);
00117     wifiLock.acquire();
00118   }
00119 
00120   @Override
00121   public void execute(NodeMain nodeMain, NodeConfiguration nodeConfiguration,
00122       Collection<NodeListener> nodeListeneners) {
00123     nodeMainExecutor.execute(nodeMain, nodeConfiguration, nodeListeneners);
00124   }
00125 
00126   @Override
00127   public void execute(NodeMain nodeMain, NodeConfiguration nodeConfiguration) {
00128     execute(nodeMain, nodeConfiguration, null);
00129   }
00130 
00131   @Override
00132   public ScheduledExecutorService getScheduledExecutorService() {
00133     return nodeMainExecutor.getScheduledExecutorService();
00134   }
00135 
00136   @Override
00137   public void shutdownNodeMain(NodeMain nodeMain) {
00138     nodeMainExecutor.shutdownNodeMain(nodeMain);
00139   }
00140 
00141   @Override
00142   public void shutdown() {
00143     handler.post(new Runnable() {
00144       @Override
00145       public void run() {
00146         AlertDialog.Builder builder = new AlertDialog.Builder(NodeMainExecutorService.this);
00147         builder.setMessage("Continue shutting down?");
00148         builder.setPositiveButton("Shutdown", new OnClickListener() {
00149           @Override
00150           public void onClick(DialogInterface dialog, int which) {
00151             forceShutdown();
00152           }
00153         });
00154         builder.setNegativeButton("Cancel", new OnClickListener() {
00155           @Override
00156           public void onClick(DialogInterface dialog, int which) {
00157           }
00158         });
00159         AlertDialog alertDialog = builder.create();
00160         alertDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
00161         alertDialog.show();
00162       }
00163     });
00164   }
00165 
00166   public void forceShutdown() {
00167     signalOnShutdown();
00168     stopForeground(true);
00169     stopSelf();
00170   }
00171 
00172   public void addListener(NodeMainExecutorServiceListener listener) {
00173     listeners.add(listener);
00174   }
00175 
00176   public void removeListener(NodeMainExecutorServiceListener listener)
00177   {
00178     listeners.remove(listener);
00179   }
00180 
00181   private void signalOnShutdown() {
00182     listeners.signal(new SignalRunnable<NodeMainExecutorServiceListener>() {
00183       @Override
00184       public void run(NodeMainExecutorServiceListener nodeMainExecutorServiceListener) {
00185         nodeMainExecutorServiceListener.onShutdown(NodeMainExecutorService.this);
00186       }
00187     });
00188   }
00189 
00190   @Override
00191   public void onDestroy() {
00192     toast("Shutting down...");
00193     nodeMainExecutor.shutdown();
00194     if (rosCore != null) {
00195       rosCore.shutdown();
00196     }
00197     if (wakeLock.isHeld()) {
00198       wakeLock.release();
00199     }
00200     if (wifiLock.isHeld()) {
00201       wifiLock.release();
00202     }
00203     super.onDestroy();
00204   }
00205 
00206   @Override
00207   public int onStartCommand(Intent intent, int flags, int startId) {
00208     if (intent.getAction() == null) {
00209       return START_NOT_STICKY;
00210     }
00211     if (intent.getAction().equals(ACTION_START)) {
00212       Preconditions.checkArgument(intent.hasExtra(EXTRA_NOTIFICATION_TICKER));
00213       Preconditions.checkArgument(intent.hasExtra(EXTRA_NOTIFICATION_TITLE));
00214       Notification notification =
00215           new Notification(R.mipmap.icon, intent.getStringExtra(EXTRA_NOTIFICATION_TICKER),
00216               System.currentTimeMillis());
00217       Intent notificationIntent = new Intent(this, NodeMainExecutorService.class);
00218       notificationIntent.setAction(NodeMainExecutorService.ACTION_SHUTDOWN);
00219       PendingIntent pendingIntent = PendingIntent.getService(this, 0, notificationIntent, 0);
00220       notification.setLatestEventInfo(this, intent.getStringExtra(EXTRA_NOTIFICATION_TITLE),
00221           "Tap to shutdown.", pendingIntent);
00222       startForeground(ONGOING_NOTIFICATION, notification);
00223     }
00224     if (intent.getAction().equals(ACTION_SHUTDOWN)) {
00225       shutdown();
00226     }
00227     return START_NOT_STICKY;
00228   }
00229 
00230   @Override
00231   public IBinder onBind(Intent intent) {
00232     return binder;
00233   }
00234 
00235   public URI getMasterUri() {
00236     return masterUri;
00237   }
00238 
00239   public void setMasterUri(URI uri) {
00240     masterUri = uri;
00241   }
00242 
00243   public void setRosHostname(String hostname) {
00244     rosHostname = hostname;
00245   }
00246 
00247   public String getRosHostname() {
00248     return rosHostname;
00249   }
00255   @Deprecated
00256   public void startMaster() {
00257     startMaster(true);
00258   }
00259 
00264   public void startMaster(boolean isPrivate) {
00265     AsyncTask<Boolean, Void, URI> task = new AsyncTask<Boolean, Void, URI>() {
00266       @Override
00267       protected URI doInBackground(Boolean[] params) {
00268         NodeMainExecutorService.this.startMasterBlocking(params[0]);
00269         return NodeMainExecutorService.this.getMasterUri();
00270       }
00271     };
00272     task.execute(isPrivate);
00273     try {
00274       task.get();
00275     } catch (InterruptedException e) {
00276       throw new RosRuntimeException(e);
00277     } catch (ExecutionException e) {
00278       throw new RosRuntimeException(e);
00279     }
00280   }
00281 
00286   private void startMasterBlocking(boolean isPrivate) {
00287     if (isPrivate) {
00288       rosCore = RosCore.newPrivate();
00289     } else if (rosHostname != null) {
00290       rosCore = RosCore.newPublic(rosHostname, 11311);
00291     } else {
00292       rosCore = RosCore.newPublic(11311);
00293     }
00294     rosCore.start();
00295     try {
00296       rosCore.awaitStart();
00297     } catch (Exception e) {
00298       throw new RosRuntimeException(e);
00299     }
00300     masterUri = rosCore.getUri();
00301   }
00302 
00303   public void toast(final String text) {
00304     handler.post(new Runnable() {
00305       @Override
00306       public void run() {
00307         Toast.makeText(NodeMainExecutorService.this, text, Toast.LENGTH_SHORT).show();
00308       }
00309     });
00310   }
00311 }


android_core
Author(s): Damon Kohler
autogenerated on Thu Jun 6 2019 21:20:07