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 org.ros.android;
00018
00019 import com.google.common.base.Preconditions;
00020
00021 import android.app.Notification;
00022 import android.app.PendingIntent;
00023 import android.app.Service;
00024 import android.content.Intent;
00025 import android.net.wifi.WifiManager;
00026 import android.net.wifi.WifiManager.WifiLock;
00027 import android.os.Binder;
00028 import android.os.IBinder;
00029 import android.os.PowerManager;
00030 import android.os.PowerManager.WakeLock;
00031 import android.util.Log;
00032 import org.ros.RosCore;
00033 import org.ros.android.android_gingerbread_mr1.R;
00034 import org.ros.concurrent.ListenerGroup;
00035 import org.ros.concurrent.SignalRunnable;
00036 import org.ros.exception.RosRuntimeException;
00037 import org.ros.node.DefaultNodeMainExecutor;
00038 import org.ros.node.NodeConfiguration;
00039 import org.ros.node.NodeListener;
00040 import org.ros.node.NodeMain;
00041 import org.ros.node.NodeMainExecutor;
00042
00043 import java.net.URI;
00044 import java.util.Collection;
00045 import java.util.concurrent.ScheduledExecutorService;
00046
00050 public class NodeMainExecutorService extends Service implements NodeMainExecutor {
00051
00052 private static final String TAG = "NodeMainExecutorService";
00053
00054
00055 private static final int ONGOING_NOTIFICATION = 1;
00056
00057 static final String ACTION_START = "org.ros.android.ACTION_START_NODE_RUNNER_SERVICE";
00058 static final String ACTION_SHUTDOWN = "org.ros.android.ACTION_SHUTDOWN_NODE_RUNNER_SERVICE";
00059 static final String EXTRA_NOTIFICATION_TITLE = "org.ros.android.EXTRA_NOTIFICATION_TITLE";
00060 static final String EXTRA_NOTIFICATION_TICKER = "org.ros.android.EXTRA_NOTIFICATION_TICKER";
00061
00062 private final NodeMainExecutor nodeMainExecutor;
00063 private final IBinder binder;
00064 private final ListenerGroup<NodeMainExecutorServiceListener> listeners;
00065
00066 private WakeLock wakeLock;
00067 private WifiLock wifiLock;
00068 private RosCore rosCore;
00069 private URI masterUri;
00070
00075 class LocalBinder extends Binder {
00076 NodeMainExecutorService getService() {
00077 return NodeMainExecutorService.this;
00078 }
00079 }
00080
00081 public NodeMainExecutorService() {
00082 super();
00083 nodeMainExecutor = DefaultNodeMainExecutor.newDefault();
00084 binder = new LocalBinder();
00085 listeners =
00086 new ListenerGroup<NodeMainExecutorServiceListener>(
00087 nodeMainExecutor.getScheduledExecutorService());
00088 }
00089
00090 @Override
00091 public void onCreate() {
00092 PowerManager powerManager = (PowerManager) getSystemService(POWER_SERVICE);
00093 wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
00094 wakeLock.acquire();
00095 int wifiLockType = WifiManager.WIFI_MODE_FULL;
00096 try {
00097 wifiLockType = WifiManager.class.getField("WIFI_MODE_FULL_HIGH_PERF").getInt(null);
00098 } catch (Exception e) {
00099
00100 Log.w(TAG, "Unable to acquire high performance wifi lock.");
00101 }
00102 WifiManager wifiManager = (WifiManager) getSystemService(WIFI_SERVICE);
00103 wifiLock = wifiManager.createWifiLock(wifiLockType, TAG);
00104 wifiLock.acquire();
00105 }
00106
00107 @Override
00108 public void execute(NodeMain nodeMain, NodeConfiguration nodeConfiguration,
00109 Collection<NodeListener> nodeListeneners) {
00110 nodeMainExecutor.execute(nodeMain, nodeConfiguration, nodeListeneners);
00111 }
00112
00113 @Override
00114 public void execute(NodeMain nodeMain, NodeConfiguration nodeConfiguration) {
00115 execute(nodeMain, nodeConfiguration, null);
00116 }
00117
00118 @Override
00119 public ScheduledExecutorService getScheduledExecutorService() {
00120 return nodeMainExecutor.getScheduledExecutorService();
00121 }
00122
00123 @Override
00124 public void shutdownNodeMain(NodeMain nodeMain) {
00125 nodeMainExecutor.shutdownNodeMain(nodeMain);
00126 }
00127
00128 @Override
00129 public void shutdown() {
00130 signalOnShutdown();
00131
00132
00133
00134 nodeMainExecutor.shutdown();
00135 if (rosCore != null) {
00136 rosCore.shutdown();
00137 }
00138 if (wakeLock.isHeld()) {
00139 wakeLock.release();
00140 }
00141 if (wifiLock.isHeld()) {
00142 wifiLock.release();
00143 }
00144 stopForeground(true);
00145 stopSelf();
00146 }
00147
00148 public void addListener(NodeMainExecutorServiceListener listener) {
00149 listeners.add(listener);
00150 }
00151
00152 private void signalOnShutdown() {
00153 listeners.signal(new SignalRunnable<NodeMainExecutorServiceListener>() {
00154 @Override
00155 public void run(NodeMainExecutorServiceListener nodeMainExecutorServiceListener) {
00156 nodeMainExecutorServiceListener.onShutdown(NodeMainExecutorService.this);
00157 }
00158 });
00159 }
00160
00161 @Override
00162 public void onDestroy() {
00163 shutdown();
00164 super.onDestroy();
00165 }
00166
00167 @Override
00168 public int onStartCommand(Intent intent, int flags, int startId) {
00169 if (intent.getAction() == null) {
00170 return START_NOT_STICKY;
00171 }
00172 if (intent.getAction().equals(ACTION_START)) {
00173 Preconditions.checkArgument(intent.hasExtra(EXTRA_NOTIFICATION_TICKER));
00174 Preconditions.checkArgument(intent.hasExtra(EXTRA_NOTIFICATION_TITLE));
00175 Notification notification =
00176 new Notification(R.drawable.icon, intent.getStringExtra(EXTRA_NOTIFICATION_TICKER),
00177 System.currentTimeMillis());
00178 Intent notificationIntent = new Intent(this, NodeMainExecutorService.class);
00179 notificationIntent.setAction(NodeMainExecutorService.ACTION_SHUTDOWN);
00180 PendingIntent pendingIntent = PendingIntent.getService(this, 0, notificationIntent, 0);
00181 notification.setLatestEventInfo(this, intent.getStringExtra(EXTRA_NOTIFICATION_TITLE),
00182 "Tap to shutdown.", pendingIntent);
00183 startForeground(ONGOING_NOTIFICATION, notification);
00184 }
00185 if (intent.getAction().equals(ACTION_SHUTDOWN)) {
00186 shutdown();
00187 }
00188 return START_NOT_STICKY;
00189 }
00190
00191 @Override
00192 public IBinder onBind(Intent intent) {
00193 return binder;
00194 }
00195
00196 public URI getMasterUri() {
00197 return masterUri;
00198 }
00199
00200 public void setMasterUri(URI uri) {
00201 masterUri = uri;
00202 }
00203
00209 @Deprecated
00210 public void startMaster() {
00211 startMaster(true);
00212 }
00213
00214 public void startMaster(Boolean isPrivate) {
00215 if (isPrivate) {
00216 rosCore = RosCore.newPrivate();
00217 } else {
00218 rosCore = RosCore.newPublic(11311);
00219 }
00220 rosCore.start();
00221 try {
00222 rosCore.awaitStart();
00223 } catch (Exception e) {
00224 throw new RosRuntimeException(e);
00225 }
00226 masterUri = rosCore.getUri();
00227 }
00228 }