Implemented explicit stop feature - stops the service until it is

started manually

Signed-off-by: Balint Kovacs <blint@blint.hu>
This commit is contained in:
Balint Kovacs 2011-10-19 11:44:43 +02:00
parent d59aa907a8
commit 8e3cd92b69
12 changed files with 130 additions and 78 deletions

View File

@ -12,6 +12,7 @@
<activity android:name=".SSLDroidTunnelDetails"
android:windowSoftInputMode="stateVisible|adjustResize" />
<activity android:name=".SSLDroidReadLogs" />
<activity android:name=".SSLDroidProvisioning" />
<service android:enabled="true" android:name="SSLDroid">
<intent-filter>
<action android:name="hu.blint.ssldroid.SSLDroid" />

View File

@ -8,4 +8,4 @@
# project structure.
# Project target.
target=android-7
target=android-8

View File

@ -1,8 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<menu
xmlns:android="http://schemas.android.com/apk/res/android">
<item android:enabled="true" android:title="@string/add_tunnel" android:id="@+id/addtunnel" android:icon="@android:drawable/ic_menu_add"></item>
<item android:enabled="true" android:id="@+id/startservice" android:title="@string/start_service" android:icon="@android:drawable/ic_menu_manage"></item><item android:title="@string/stop_service" android:enabled="true" android:id="@+id/stopservice" android:icon="@android:drawable/ic_menu_close_clear_cancel"></item>
<item android:enabled="true" android:title="@string/add_tunnel" android:id="@+id/addtunnel" android:icon="@android:drawable/ic_menu_add"></item>
<item android:enabled="true" android:id="@+id/startservice" android:title="@string/start_service" android:icon="@android:drawable/ic_menu_manage"></item>
<item android:title="@string/stop_service" android:enabled="true" android:id="@+id/stopservice" android:icon="@android:drawable/ic_menu_close_clear_cancel"></item>
<item android:title="@string/stop_service_for_good" android:enabled="true" android:id="@+id/stopserviceforgood" android:icon="@android:drawable/ic_menu_close_clear_cancel"></item>
<item android:title="@string/menu_readlogs" android:id="@+id/readlogs" android:icon="@android:drawable/ic_menu_agenda" android:enabled="true"></item>
<!-- <item android:title="@string/menu_provision" android:id="@+id/provision" android:icon="@android:drawable/ic_menu_mapmode" android:enabled="true"></item> -->
</menu>

View File

@ -1,57 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="tunnels">
<xs:complexType>
<xs:sequence>
<xs:element name="tunnel" type="tunnelType" minOccurs="0" maxOccurs="unbounded">
<xs:annotation>
<xs:documentation>
A container to group tunnel settings.
</xs:documentation>
</xs:annotation>
</xs:element>
</xs:sequence>
<xs:attribute name="version" type="xs:NMTOKEN" use="required" fixed="1">
<xs:annotation>
<xs:documentation>
The schema version of the tunnel setting.
The current version is '1'.
</xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:complexType>
<xs:unique name="tunnel_name">
<xs:selector xpath="tunnel"/>
<xs:field xpath="@name"/>
</xs:unique>
<xs:unique name="localports">
<xs:selector xpath="tunnel/localport"/>
<xs:field xpath="."/>
</xs:unique>
</xs:element>
<xs:complexType name="tunnelType">
<xs:all>
<xs:element name="localport" minOccurs="1">
<xs:simpleType>
<xs:restriction base="xs:integer">
<xs:minExclusive value="1024"/>
<xs:maxInclusive value="65535"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
<xs:element name="remotehost" type="xs:string" minOccurs="1" />
<xs:element name="remoteport" type="xs:unsignedShort" minOccurs="1" />
<xs:element name="pkcsfile" type="xs:string" minOccurs="1" />
<xs:element name="pkcspass" type="xs:string" minOccurs="0" />
</xs:all>
<xs:attribute name="name" type="xs:string" use="required">
<xs:annotation>
<xs:documentation>
The name of the tunnel.
</xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:complexType>
</xs:schema>

View File

@ -11,6 +11,7 @@
<string name="connection_name">Tunnel name</string>
<string name="add_tunnel">Add tunnel</string>
<string name="stop_service">Stop service</string>
<string name="stop_service_for_good">Stop service until started</string>
<string name="start_service">Start service</string>
<string name="no_tunnels">No tunnels configured yet</string>
<string name="menu_delete">Delete tunnel</string>
@ -18,6 +19,8 @@
<string name="alert_sdcard_absent">No SD card present, please insert one to continue</string>
<string name="menu_readlogs">Read logs</string>
<string name="reading_logs">Reading log messages...</string>
<string name="menu_provision">Provisioning</string>
<string name="provision">Please enter the URL for remote XML configuration</string>
<string name="back">Back</string>
<string name="refresh">Refresh</string>
</resources>

View File

@ -1,16 +1,44 @@
package hu.blint.ssldroid;
import hu.blint.ssldroid.db.SSLDroidDbAdapter;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.util.Log;
public class BootStartupReceiver extends BroadcastReceiver {
private boolean isStopped(Context context){
Boolean stopped = false;
SSLDroidDbAdapter dbHelper;
dbHelper = new SSLDroidDbAdapter(context);
dbHelper.open();
Cursor cursor = dbHelper.getStopStatus();
int tunnelcount = cursor.getCount();
Log.d("SSLDroid", "Tunnelcount: "+tunnelcount);
//don't start if the stop status field is available
if (tunnelcount != 0){
stopped = true;
}
cursor.close();
dbHelper.close();
return stopped;
}
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Intent.ACTION_BOOT_COMPLETED)) {
Intent i = new Intent();
i.setAction("hu.blint.ssldroid.SSLDroid");
context.startService(i);
if (!isStopped(context))
context.startService(i);
else
Log.w("SSLDroid", "Not starting service as directed by explicit stop");
}
}
}

View File

@ -1,14 +1,37 @@
package hu.blint.ssldroid;
import hu.blint.ssldroid.db.SSLDroidDbAdapter;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.util.Log;
public class NetworkChangeReceiver extends BroadcastReceiver {
private boolean isStopped(Context context){
Boolean stopped = false;
SSLDroidDbAdapter dbHelper;
dbHelper = new SSLDroidDbAdapter(context);
dbHelper.open();
Cursor cursor = dbHelper.getStopStatus();
int tunnelcount = cursor.getCount();
Log.d("SSLDroid", "Tunnelcount: "+tunnelcount);
//don't start if the stop status field is available
if (tunnelcount != 0){
stopped = true;
}
cursor.close();
dbHelper.close();
return stopped;
}
@Override
public void onReceive(Context context, Intent intent) {
ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService( Context.CONNECTIVITY_SERVICE );
@ -24,7 +47,10 @@ public class NetworkChangeReceiver extends BroadcastReceiver {
Intent i = new Intent();
i.setAction("hu.blint.ssldroid.SSLDroid");
context.stopService(i);
context.startService(i);
if (!isStopped(context))
context.startService(i);
else
Log.w("SSLDroid", "Not starting service as directed by explicit stop");
}
}
}

View File

@ -4,6 +4,7 @@ import hu.blint.ssldroid.TcpProxy;
import android.app.*;
import android.content.Intent;
import android.database.Cursor;
import android.os.Bundle;
import android.os.IBinder;
import android.util.Log;
import hu.blint.ssldroid.db.SSLDroidDbAdapter;
@ -71,7 +72,7 @@ public class SSLDroid extends Service {
@Override
public IBinder onBind(Intent intent) {
return null;
return null;
}
@Override

View File

@ -54,8 +54,14 @@ public class SSLDroidGui extends ListActivity {
Log.d("SSLDroid", "Stopping service");
stopService(new Intent(this, SSLDroid.class));
return true;
case R.id.stopserviceforgood:
Log.d("SSLDroid", "Stopping service until explicitly started");
dbHelper.setStopStatus();
stopService(new Intent(this, SSLDroid.class));
return true;
case R.id.startservice:
Log.d("SSLDroid", "Starting service");
dbHelper.delStopStatus();
startService(new Intent(this, SSLDroid.class));
return true;
case R.id.readlogs:
@ -75,8 +81,14 @@ public class SSLDroidGui extends ListActivity {
Log.d("SSLDroid", "Stopping service");
stopService(new Intent(this, SSLDroid.class));
return true;
case R.id.stopserviceforgood:
Log.d("SSLDroid", "Stopping service until explicitly started");
dbHelper.setStopStatus();
stopService(new Intent(this, SSLDroid.class));
return true;
case R.id.startservice:
Log.d("SSLDroid", "Starting service");
dbHelper.delStopStatus();
startService(new Intent(this, SSLDroid.class));
return true;
case R.id.readlogs:
@ -124,7 +136,6 @@ public class SSLDroidGui extends ListActivity {
Intent i = new Intent(this, SSLDroidTunnelDetails.class);
i.putExtra(SSLDroidDbAdapter.KEY_ROWID, id);
// Activity returns an result if called with startActivityForResult
startActivityForResult(i, ACTIVITY_EDIT);
}
@ -159,4 +170,12 @@ public class SSLDroidGui extends ListActivity {
super.onCreateContextMenu(menu, v, menuInfo);
menu.add(0, DELETE_ID, 0, R.string.menu_delete);
}
@Override
public void onDestroy (){
cursor.close();
dbHelper.close();
super.onDestroy();
}
}

View File

@ -83,12 +83,12 @@ public class SSLDroidTunnelDetails extends Activity {
confirmButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
if (name.getText().length() == 0) {
Toast.makeText(getBaseContext(), "Required tunnel name parameter not setup, skipping save", Toast.LENGTH_LONG).show();
Toast.makeText(getBaseContext(), "Required tunnel name parameter not set up, skipping save", Toast.LENGTH_LONG).show();
return;
}
//local port validation
if (localport.getText().length() == 0) {
Toast.makeText(getBaseContext(), "Required local port parameter not setup, skipping save", Toast.LENGTH_LONG).show();
Toast.makeText(getBaseContext(), "Required local port parameter not set up, skipping save", Toast.LENGTH_LONG).show();
return;
}
else {
@ -120,7 +120,7 @@ public class SSLDroidTunnelDetails extends Activity {
}
//remote host validation
if (remotehost.getText().length() == 0) {
Toast.makeText(getBaseContext(), "Required remote host parameter not setup, skipping save", Toast.LENGTH_LONG).show();
Toast.makeText(getBaseContext(), "Required remote host parameter not set up, skipping save", Toast.LENGTH_LONG).show();
return;
}
else {
@ -137,7 +137,7 @@ public class SSLDroidTunnelDetails extends Activity {
}
//remote port validation
if (remoteport.getText().length() == 0) {
Toast.makeText(getBaseContext(), "Required remote port parameter not setup, skipping save", Toast.LENGTH_LONG).show();
Toast.makeText(getBaseContext(), "Required remote port parameter not set up, skipping save", Toast.LENGTH_LONG).show();
return;
}
else {
@ -155,7 +155,7 @@ public class SSLDroidTunnelDetails extends Activity {
}
}
if (pkcsfile.getText().length() == 0) {
Toast.makeText(getBaseContext(), "Required PKCS12 file parameter not setup, skipping save", Toast.LENGTH_LONG).show();
Toast.makeText(getBaseContext(), "Required PKCS12 file parameter not set up, skipping save", Toast.LENGTH_LONG).show();
return;
}
else {

View File

@ -16,7 +16,10 @@ public class SSLDroidDbAdapter {
public static final String KEY_REMOTEPORT = "remoteport";
public static final String KEY_PKCSFILE = "pkcsfile";
public static final String KEY_PKCSPASS = "pkcspass";
public static final String KEY_STATUS_NAME = "name";
public static final String KEY_STATUS_VALUE = "value";
private static final String DATABASE_TABLE = "tunnels";
private static final String STATUS_TABLE = "status";
private Context context;
private SQLiteDatabase database;
private SSLDroidDbHelper dbHelper;
@ -93,6 +96,30 @@ public class SSLDroidDbAdapter {
/**
* Return a Cursor positioned at the defined tunnel
*/
public Cursor fetchStatus(String valuename) throws SQLException {
return database.query(STATUS_TABLE, new String[] {
KEY_STATUS_NAME, KEY_STATUS_VALUE
},
KEY_STATUS_NAME + "='" + valuename + "'", null, null, null, null);
}
public Cursor getStopStatus() {
return fetchStatus("stopped");
}
public boolean setStopStatus() {
ContentValues stopStatus = new ContentValues();
stopStatus.put(KEY_STATUS_NAME, "stopped");
stopStatus.put(KEY_STATUS_VALUE, "yes");
if (getStopStatus().getCount() == 0)
database.insert(STATUS_TABLE, null, stopStatus);
return true;
}
public boolean delStopStatus() {
return database.delete(STATUS_TABLE, KEY_STATUS_NAME+"= 'stopped'", null) > 0;
}
public Cursor fetchTunnel(long rowId) throws SQLException {
Cursor mCursor = database.query(true, DATABASE_TABLE, new String[] {
KEY_ROWID, KEY_NAME, KEY_LOCALPORT, KEY_REMOTEHOST, KEY_REMOTEPORT,
@ -104,7 +131,7 @@ public class SSLDroidDbAdapter {
}
return mCursor;
}
private ContentValues createContentValues(String name, int localport, String remotehost, int remoteport,
String pkcsfile, String pkcspass) {
ContentValues values = new ContentValues();

View File

@ -3,16 +3,17 @@ package hu.blint.ssldroid.db;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;
public class SSLDroidDbHelper extends SQLiteOpenHelper {
private static final String DATABASE_NAME = "applicationdata";
private static final int DATABASE_VERSION = 1;
private static final int DATABASE_VERSION = 2;
// Database creation sql statement
private static final String DATABASE_CREATE = "create table tunnels (_id integer primary key autoincrement, "
private static final String DATABASE_CREATE = "CREATE TABLE IF NOT EXISTS tunnels (_id integer primary key autoincrement, "
+ "name text not null, localport integer not null, remotehost text not null, "
+ "remoteport integer not null, pkcsfile text not null, pkcspass text );";
private static final String STATUS_CREATE = "CREATE TABLE IF NOT EXISTS status (name text, value text);";
public SSLDroidDbHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
@ -22,6 +23,7 @@ public class SSLDroidDbHelper extends SQLiteOpenHelper {
@Override
public void onCreate(SQLiteDatabase database) {
database.execSQL(DATABASE_CREATE);
database.execSQL(STATUS_CREATE);
}
// Method is called during an update of the database, e.g. if you increase
@ -29,11 +31,11 @@ public class SSLDroidDbHelper extends SQLiteOpenHelper {
@Override
public void onUpgrade(SQLiteDatabase database, int oldVersion,
int newVersion) {
/* Log.w(SSLDroidDbHelper.class.getName(),
Log.w(SSLDroidDbHelper.class.getName(),
"Upgrading database from version " + oldVersion + " to "
+ newVersion + ", which will destroy all old data");
database.execSQL("DROP TABLE IF EXISTS todo");
onCreate(database); */
+ newVersion + ", which will add a status table");
database.execSQL("CREATE TABLE IF NOT EXISTS status (name text, value text);");
onCreate(database);
}
}