Android Open Source - commotion-android Mesh Tether App






From Project

Back to project page commotion-android.

License

The source code is released under:

GNU General Public License

If you think the Android project commotion-android listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

/*
 *  This file is part of Commotion Mesh Tether
 *  Copyright (C) 2010 by Szymon Jakubczak
 */*  w ww .j a v a2 s .  c  om*/
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package net.commotionwireless.meshtether;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArraySet;

import net.commotionwireless.olsrinfo.JsonInfo;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.net.Uri;
import android.net.wifi.WifiManager;
import android.preference.PreferenceManager;
import android.util.Log;
import android.widget.Toast;


/**
 * Manages preferences, activities and prepares the service
 */
public class MeshTetherApp extends android.app.Application {
  final static String TAG = "MeshTetherApp";

  final static String FILE_INI    = "brncl.ini";

  final static String ACTION_CLIENTS = "net.commotionwireless.meshtether.SHOW_CLIENTS";
  final static String ACTION_TOGGLE = "net.commotionwireless.meshtether.TOGGLE_STATE";
  final static String ACTION_CHECK = "net.commotionwireless.meshtether.CHECK_STATE";
  final static String ACTION_CHANGED = "net.commotionwireless.meshtether.STATE_CHANGED";

  final static int ERROR_ROOT = 1;
  final static int ERROR_OTHER = 2;
  final static int ERROR_SUPPLICANT = 3;

  SharedPreferences prefs;
  StatusActivity  statusActivity = null;
  LinksActivity linksActivity = null;
  InfoActivity infoActivity = null;
  private Toast toast;

  WifiManager wifiManager;

  // notifications
  private NotificationManager notificationManager;
  private Notification notification;
  private Notification notificationClientAdded;
  private Notification notificationError;
  final static int NOTIFY_RUNNING = 0;
  final static int NOTIFY_CLIENT = 1;
  final static int NOTIFY_ERROR = 2;

  JsonInfo mJsonInfo = null;
  Set<String> profiles;
  Map<String, String> profileProperties;
  String activeProfile;

  public MeshService service = null;
  public Util.StyledStringBuilder log = null; // == service.log, unless service is dead

  @Override
  public void onCreate() {
    super.onCreate();
    Log.d(TAG, "onCreate");
    NativeHelper.setup(this);

    // initialize default values if not done this in the past
    PreferenceManager.setDefaultValues(this, R.xml.preferences, false);
    prefs = PreferenceManager.getDefaultSharedPreferences(this);

    // if IP address isn't set, generate one
    if (prefs.getString(getString(R.string.adhoc_ip), "").equals("")) {
      SharedPreferences.Editor e = prefs.edit();
      String myIP = "10." + String.valueOf((int)(Math.random() * 254))
      + "." + String.valueOf((int)(Math.random() * 254))
      + "." + String.valueOf((int)(Math.random() * 254));
      e.putString(getString(R.string.adhoc_ip), myIP);
      e.commit();
      Log.i(TAG, "Generated IP: " + myIP);
    }

    notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
    toast = Toast.makeText(this, "", Toast.LENGTH_SHORT);
    notification = new Notification(R.drawable.comlogo_sm_on, getString(R.string.notify_running), 0);
    notification.flags |= Notification.FLAG_ONGOING_EVENT;
    notificationClientAdded = new Notification(android.R.drawable.stat_sys_warning,
        getString(R.string.notify_client), 0);
    notificationClientAdded.flags = Notification.FLAG_AUTO_CANCEL;
    notificationError = new Notification(R.drawable.barnacle_error,
        getString(R.string.notify_error), 0);
    notificationError.setLatestEventInfo(this,
        getString(R.string.app_name),
        getString(R.string.notify_error),
        PendingIntent.getActivity(this, 0, new Intent(this, StatusActivity.class), 0));
    notificationError.flags = Notification.FLAG_AUTO_CANCEL;

    activeProfile = getString(R.string.defaultprofile);

    mJsonInfo = new JsonInfo();
    profiles = new CopyOnWriteArraySet<String>();
    profiles.add(activeProfile);
    profileProperties = new HashMap<String, String>();

    wifiManager = (WifiManager) getSystemService(Context.WIFI_SERVICE);
  }

  @Override
  public void onTerminate() {
    if (service != null) {
      Log.e(TAG, "The app is terminated while the service is running!");
      service.stopRequest();
    }
    super.onTerminate();
  }

  public void startService() {
    if (service == null) {
      showProgressMessage(R.string.servicestarting);
      startService(new Intent(this, MeshService.class));
    }
  }

  public void stopService() {
    if (service != null)
      service.stopRequest();
  }

  public int getState() {
    if (service != null)
      return service.getState();
    return MeshService.STATE_STOPPED;
  }

  public boolean isChanging() {
    return getState() == MeshService.STATE_STARTING;
  }

  public boolean isRunning() {
    return getState() == MeshService.STATE_RUNNING;
  }

  public boolean isStopped() {
    return getState() == MeshService.STATE_STOPPED;
  }

  void setStatusActivity(StatusActivity a) { // for updates
    statusActivity = a;
  }

  void setLinksActivity(LinksActivity a) { // for updates
    linksActivity = a;
  }

  void setInfoActivity(InfoActivity a) { // for updates
    infoActivity = a;
  }

  void serviceStarted(MeshService s) {
    Log.w(TAG, "serviceStarted");
    service = s;
    log = service.log;
    service.startRequest();
    if (linksActivity != null)
      linksActivity.update();
    if (infoActivity != null)
      infoActivity.update();
  }

  static void broadcastState(Context ctx, int state) {
    Intent intent = new Intent(ACTION_CHANGED);
    intent.putExtra("state", state);
    ctx.sendBroadcast(intent, "net.commotionwireless.meshtether.ACCESS_STATE");
  }

  void updateStatus() {
    if (statusActivity != null)
      statusActivity.update();
    // TODO: only broadcast state if changed or stale, using a sticky intent broadcast
    broadcastState(this, getState());
  }

  void updateToast(String msg, boolean islong) {
    toast.setText(msg);
    toast.setDuration(islong ? Toast.LENGTH_LONG : Toast.LENGTH_SHORT);
    toast.show();
  }

  void clientAdded(MeshService.ClientData cd) {
    if (prefs.getBoolean("client_notify", false)) {
      notificationClientAdded.defaults = 0;
      if (prefs.getBoolean("client_light", false)) {
        notificationClientAdded.flags |= Notification.FLAG_SHOW_LIGHTS;
        notificationClientAdded.ledARGB = 0xffffff00; // yellow
        notificationClientAdded.ledOnMS = 500;
        notificationClientAdded.ledOffMS = 1000;
      } else {
        notificationClientAdded.flags &= ~Notification.FLAG_SHOW_LIGHTS;
      }
      String sound = prefs.getString("client_sound", null);
      if (sound == null) {
        notificationClientAdded.defaults |= Notification.DEFAULT_SOUND;
        // | Notification.DEFAULT_VIBRATE // requires permission
      } else {
        if (sound.length() > 0)
          notificationClientAdded.sound = Uri.parse(sound);
      }
      Intent notificationIntent = new Intent(this, StatusActivity.class);
      notificationIntent.setAction(ACTION_CLIENTS);
      PendingIntent contentIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);
      notificationClientAdded.setLatestEventInfo(this, getString(R.string.app_name),
          getString(R.string.notify_client) + " " + cd.toNiceString(), contentIntent);
      notificationManager.notify(NOTIFY_CLIENT, notificationClientAdded);
    }

    if (linksActivity != null)
      linksActivity.update();
  }

  void cancelClientNotify() {
    notificationManager.cancel(NOTIFY_CLIENT);
  }

  void processStarted() {
    Log.w(TAG, "processStarted");
    Intent notificationIntent = new Intent(this, StatusActivity.class);
    PendingIntent contentIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);
    notification.setLatestEventInfo(this, getString(R.string.app_name),
        getString(R.string.notify_running), contentIntent);
    notificationManager.notify(NOTIFY_RUNNING, notification);
    service.startForegroundCompat(NOTIFY_RUNNING, notification);
  }

  void processStopped() {
    Log.w(TAG, "processStopped");
    notificationManager.cancel(NOTIFY_RUNNING);
    notificationManager.cancel(NOTIFY_CLIENT);
    if (service != null) service.stopSelf();
    service = null;
    updateStatus();
  }

  void failed(int err) {
    if (statusActivity != null) {
      if (err == ERROR_ROOT) {
        statusActivity.showDialog(StatusActivity.DLG_ROOT);
      } else if (err == ERROR_SUPPLICANT) {
        statusActivity.showDialog(StatusActivity.DLG_SUPPLICANT);
      } else if (err == ERROR_OTHER) {
        statusActivity.getTabHost().setCurrentTab(0); // show links
        statusActivity.showDialog(StatusActivity.DLG_ERROR);
      }
    }
    if ((statusActivity == null) || !statusActivity.hasWindowFocus()) {
      Log.d(TAG, "notifying error");
      notificationManager.notify(NOTIFY_ERROR, notificationError);
    }
  }

  /** find default route interface */
  protected boolean findIfWan() {
    // TODO move to Util.java and actually detect if there is a GSM/CDMA net connection
    String if_wan = prefs.getString(getString(R.string.if_wan), "");
    if (if_wan.length() != 0) return true;

    // must find mobile data interface
    ArrayList<String> routes = Util.readLinesFromFile("/proc/net/route");
    for (int i = 1; i < routes.size(); ++i) {
      String line = routes.get(i);
      String[] tokens = line.split("\\s+");
      if (tokens[1].equals("00000000")) {
        // this is our default route
        if_wan = tokens[0];
        break;
      }
    }
    if (if_wan.length() != 0) {
      updateToast(getString(R.string.wanok) + if_wan, false);
      prefs.edit().putString(getString(R.string.if_wan), if_wan).commit();
      return true;
    }
    // it might be okay in local mode
    return prefs.getBoolean("wan_nowait", false);
  }

  protected void foundIfLan(String found_if_lan) {
    String if_lan = prefs.getString(getString(R.string.if_lan), "");
    if (if_lan.length() == 0) {
      updateToast(getString(R.string.lanok) + found_if_lan, false);
    }
    // NOTE: always use the name found by the process
    if_lan = found_if_lan;
    prefs.edit().putString(getString(R.string.if_lan), if_lan).commit();
  }

  void cleanUpNotifications() {
    if ((service != null) && (service.getState() == MeshService.STATE_STOPPED))
      processStopped(); // clean up notifications
  }

  void showProgressMessage(int resId) {
    showProgressMessage(getString(resId));
  }

  void showProgressMessage(String messageText) {
    Log.i(TAG, "MSG_PROGRESSDIALOG");
    if (messageText == null) messageText = "(null)";
    // TODO remove these null check and fix the actual bug! these should
    // always exist when this is called
    if (statusActivity == null) {
      Log.e(TAG, "statusActivity is null!");
      return;
    }
    if (statusActivity.mProgressDialog == null) {
      Log.e(TAG, "statusActivity.mProgressDialog is null!");
      return;
    }
    statusActivity.mProgressDialog.setMessage(messageText);
    if ( !statusActivity.mProgressDialog.isShowing())
      statusActivity.mProgressDialog.show();
  }

  void hideProgressDialog() {
    Log.i(TAG, "MSG_PROGRESSDIALOG_DISMISS");
    statusActivity.mProgressDialog.dismiss();
  }
}




Java Source Code List

net.commotionwireless.meshtether.IPPreference.java
net.commotionwireless.meshtether.InfoActivity.java
net.commotionwireless.meshtether.LinksActivity.java
net.commotionwireless.meshtether.MACPreference.java
net.commotionwireless.meshtether.MeshIPPreference.java
net.commotionwireless.meshtether.MeshService.java
net.commotionwireless.meshtether.MeshTetherApp.java
net.commotionwireless.meshtether.NativeHelper.java
net.commotionwireless.meshtether.SettingsActivity.java
net.commotionwireless.meshtether.StatusActivity.java
net.commotionwireless.meshtether.ToggleReceiver.java
net.commotionwireless.meshtether.Util.java