diff options
Diffstat (limited to 'src/org/xapek/andiodine')
-rw-r--r-- | src/org/xapek/andiodine/FragmentList.java | 205 | ||||
-rw-r--r-- | src/org/xapek/andiodine/FragmentStatus.java | 120 | ||||
-rw-r--r-- | src/org/xapek/andiodine/IodineClient.java | 53 | ||||
-rw-r--r-- | src/org/xapek/andiodine/IodineMain.java | 112 | ||||
-rw-r--r-- | src/org/xapek/andiodine/IodinePref.java | 112 | ||||
-rw-r--r-- | src/org/xapek/andiodine/IodineVpnService.java | 350 | ||||
-rw-r--r-- | src/org/xapek/andiodine/config/ConfigDatabase.java | 124 | ||||
-rw-r--r-- | src/org/xapek/andiodine/config/IodineConfiguration.java | 132 | ||||
-rw-r--r-- | src/org/xapek/andiodine/preferences/AbstractPreference.java | 49 | ||||
-rw-r--r-- | src/org/xapek/andiodine/preferences/BooleanPreference.java | 33 | ||||
-rw-r--r-- | src/org/xapek/andiodine/preferences/PreferenceActivity.java | 104 | ||||
-rw-r--r-- | src/org/xapek/andiodine/preferences/SpinnerPreference.java | 47 | ||||
-rw-r--r-- | src/org/xapek/andiodine/preferences/TextPreference.java | 35 |
13 files changed, 0 insertions, 1476 deletions
diff --git a/src/org/xapek/andiodine/FragmentList.java b/src/org/xapek/andiodine/FragmentList.java deleted file mode 100644 index 10a0875..0000000 --- a/src/org/xapek/andiodine/FragmentList.java +++ /dev/null @@ -1,205 +0,0 @@ -package org.xapek.andiodine; - -import android.app.Activity; -import android.app.AlertDialog; -import android.app.Fragment; -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.DialogInterface; -import android.content.Intent; -import android.content.IntentFilter; -import android.database.DataSetObserver; -import android.os.Bundle; -import android.util.Log; -import android.view.LayoutInflater; -import android.view.Menu; -import android.view.MenuInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.BaseAdapter; -import android.widget.ListView; -import android.widget.TextView; - -import org.xapek.andiodine.config.ConfigDatabase; -import org.xapek.andiodine.config.IodineConfiguration; - -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -public class FragmentList extends Fragment { - public static final String TAG = "FRAGMENT_LIST"; - - private ListView mListView; - private ConfigDatabase mConfigDatabase; - private IodineConfiguration mSelectedConfiguration; - private IodineConfigurationAdapter mAdapter; - - private static final int INTENT_REQUEST_CODE_PREPARE = 0; - - private class IodineConfigurationAdapter extends BaseAdapter { - private List<IodineConfiguration> configurations; - private final Set<DataSetObserver> observers = new HashSet<DataSetObserver>(); - - public IodineConfigurationAdapter() { - reload(); - } - - @Override - public int getCount() { - return configurations.size(); - } - - @Override - public IodineConfiguration getItem(int position) { - return configurations.get(position); - } - - @Override - public long getItemId(int position) { - return 0; - } - - @Override - public View getView(int position, View convertView, ViewGroup parent) { - final IodineConfiguration item = getItem(position); - View view = View.inflate(parent.getContext(), R.layout.configitem, null); - ((TextView) view.findViewById(R.id.configitem_text_name)).setText(item.getName()); - ((TextView) view.findViewById(R.id.configitem_text_topdomain)).setText(item.getTopDomain()); - - view.findViewById(R.id.configitem_btn_manage) - .setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - FragmentList.this.vpnPreferences(item); - } - }); - - view.findViewById(R.id.configitem_layout_name) - .setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - FragmentList.this.vpnServiceConnect(item); - } - }); - - return view; - } - - @Override - public void registerDataSetObserver(DataSetObserver observer) { - observers.add(observer); - } - - private void reload() { - this.configurations = mConfigDatabase.selectAll(); - triggerOnChanged(); - } - - public void triggerOnChanged() { - for (DataSetObserver observer : observers) { - observer.onChanged(); - } - } - - @Override - public void unregisterDataSetObserver(DataSetObserver observer) { - observers.remove(observer); - } - } - - private final BroadcastReceiver broadcastReceiverConfigurationChanged = new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - if (IodinePref.ACTION_CONFIGURATION_CHANGED.equals(intent.getAction())) { - // CONFIGURATION_CHANGED - mAdapter.reload(); - } - } - }; - - - @Override - public void onActivityCreated(Bundle savedInstanceState) { - super.onActivityCreated(savedInstanceState); - mConfigDatabase = new ConfigDatabase(getActivity()); - mListView = (ListView) getActivity().findViewById(R.id.list_view); - mAdapter = new IodineConfigurationAdapter(); - mListView.setAdapter(mAdapter); - - IntentFilter intentFilterConfigurationChanged = new IntentFilter(); - intentFilterConfigurationChanged.addAction(IodinePref.ACTION_CONFIGURATION_CHANGED); - getActivity().registerReceiver(broadcastReceiverConfigurationChanged, intentFilterConfigurationChanged); - - setHasOptionsMenu(true); //activate onCreateOptionsMenu - } - - @Override - public void onDestroy() { - getActivity().unregisterReceiver(broadcastReceiverConfigurationChanged); - mConfigDatabase.close(); - super.onDestroy(); - } - - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { - return inflater.inflate(R.layout.fragment_list, null); - } - - @Override - public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { - super.onCreateOptionsMenu(menu, inflater); - inflater.inflate(R.menu.fragment_list, menu); - } - - private void vpnPreferences(IodineConfiguration item) { - Intent intent = new Intent(getActivity(), IodinePref.class); - intent.putExtra(IodinePref.EXTRA_CONFIGURATION_ID, item.getId()); - startActivity(intent); - } - - private void vpnServiceConnect(IodineConfiguration configuration) { - Intent intent = IodineVpnService.prepare(getActivity()); - mSelectedConfiguration = configuration; - if (intent != null) { - // Ask for permission - intent.putExtra(IodineVpnService.EXTRA_CONFIGURATION_ID, configuration.getId()); - startActivityForResult(intent, INTENT_REQUEST_CODE_PREPARE); - } else { - // Permission already granted - new AlertDialog.Builder(getActivity()) // - .setTitle(R.string.warning) // - .setCancelable(true) // - .setMessage(getString(R.string.main_create_tunnel, configuration.getName())) - .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - vpnServiceConnect2(mSelectedConfiguration); - } - }) // - .setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - dialog.dismiss(); - } - }) // - .create() // - .show(); - - } - } - - @Override - public void onActivityResult(int requestCode, int resultCode, Intent data) { - if (requestCode == INTENT_REQUEST_CODE_PREPARE && resultCode == Activity.RESULT_OK) { - vpnServiceConnect2(mSelectedConfiguration); - } - } - - private void vpnServiceConnect2(IodineConfiguration configuration) { - Log.d(TAG, "Call VPN Service for configuration: " + configuration.getId()); - Intent intent = new Intent(IodineVpnService.ACTION_CONTROL_CONNECT); - intent.putExtra(IodineVpnService.EXTRA_CONFIGURATION_ID, configuration.getId()); - getActivity().sendBroadcast(intent); - } -} diff --git a/src/org/xapek/andiodine/FragmentStatus.java b/src/org/xapek/andiodine/FragmentStatus.java deleted file mode 100644 index c1f709a..0000000 --- a/src/org/xapek/andiodine/FragmentStatus.java +++ /dev/null @@ -1,120 +0,0 @@ -package org.xapek.andiodine; - -import android.app.AlertDialog; -import android.app.Fragment; -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; -import android.content.IntentFilter; -import android.os.Bundle; -import android.text.SpannableString; -import android.text.method.LinkMovementMethod; -import android.text.util.Linkify; -import android.util.Log; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.Button; -import android.widget.ScrollView; -import android.widget.TextView; - -public class FragmentStatus extends Fragment { - public static final String TAG = "FRAGMENT_STATUS"; - - private TextView mStatus; - private TextView mLogmessages; - private ScrollView mScrollview; - private Button mClose; - - private final BroadcastReceiver broadcastReceiverStatusUpdates = new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - Log.d(TAG, "Got intent: " + intent); - if (IodineVpnService.ACTION_STATUS_ERROR.equals(intent.getAction())) { - final TextView message = new TextView(context); - final String stringMessage = intent.getStringExtra(IodineVpnService.EXTRA_ERROR_MESSAGE); - final SpannableString s = new SpannableString(stringMessage); - Linkify.addLinks(s, Linkify.WEB_URLS); - message.setText(s); - message.setMovementMethod(LinkMovementMethod.getInstance()); - new AlertDialog.Builder(FragmentStatus.this.getActivity())// - .setIcon(R.drawable.error) // - .setTitle("Error") // - .setView(message) - .create() // - .show(); - } else if (IodineVpnService.ACTION_STATUS_CONNECT.equals(intent.getAction())) { - mStatus.setText("Connect"); - } else if (IodineVpnService.ACTION_STATUS_CONNECTED.equals(intent.getAction())) { - mStatus.setText("Connected: " + IodineClient.getIp() + '/' - + IodineClient.getNetbits() + " MTU: " - + IodineClient.getMtu() + '\n'); - } else if (IodineVpnService.ACTION_STATUS_DISCONNECT.equals(intent.getAction())) { - mStatus.setText("Disconnect"); - } - } - }; - - private final BroadcastReceiver broadcastReceiverLogMessages = new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - if (IodineClient.ACTION_LOG_MESSAGE.equals(intent.getAction())) { - final String newLogEntry = intent.getStringExtra(IodineClient.EXTRA_MESSAGE); - if (!".".equals(newLogEntry)) // Suppress newline for progress indicator'.' - mLogmessages.append("\n"); - mLogmessages.append(newLogEntry); - mScrollview.fullScroll(View.FOCUS_DOWN); - } - } - }; - - @Override - public void onActivityCreated(Bundle savedInstanceState) { - super.onActivityCreated(savedInstanceState); - mStatus = (TextView) getActivity().findViewById(R.id.status_message); - mLogmessages = (TextView) getActivity().findViewById(R.id.status_logmessages); - mScrollview = (ScrollView) getActivity().findViewById(R.id.status_scrollview); - mClose = (Button) getActivity().findViewById(R.id.status_cancel); - mClose.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View view) { - requestDisconnect(); - } - }); - } - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - IntentFilter intentFilterStatusUpdates = new IntentFilter(); - intentFilterStatusUpdates.addAction(IodineVpnService.ACTION_STATUS_CONNECT); - intentFilterStatusUpdates.addAction(IodineVpnService.ACTION_STATUS_CONNECTED); - intentFilterStatusUpdates.addAction(IodineVpnService.ACTION_STATUS_DISCONNECT); - intentFilterStatusUpdates.addAction(IodineVpnService.ACTION_STATUS_ERROR); - getActivity().registerReceiver(broadcastReceiverStatusUpdates, intentFilterStatusUpdates); - - Intent intent = new Intent(IodineVpnService.ACTION_CONTROL_UPDATE); - getActivity().sendBroadcast(intent); - - IntentFilter intentFilterLogMessages = new IntentFilter(); - intentFilterLogMessages.addAction(IodineClient.ACTION_LOG_MESSAGE); - getActivity().registerReceiver(broadcastReceiverLogMessages, intentFilterLogMessages); - } - - @Override - public void onDestroy() { - getActivity().unregisterReceiver(broadcastReceiverStatusUpdates); - getActivity().unregisterReceiver(broadcastReceiverLogMessages); - super.onDestroy(); - } - - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { - return inflater.inflate(R.layout.fragment_status, null); - } - - private void requestDisconnect() { - Intent intent = new Intent(IodineVpnService.ACTION_CONTROL_DISCONNECT); - getActivity().sendBroadcast(intent); - } -} diff --git a/src/org/xapek/andiodine/IodineClient.java b/src/org/xapek/andiodine/IodineClient.java deleted file mode 100644 index 37178b5..0000000 --- a/src/org/xapek/andiodine/IodineClient.java +++ /dev/null @@ -1,53 +0,0 @@ -package org.xapek.andiodine; - -import android.content.Intent; -import android.util.Log; - -public class IodineClient { - public static final String TAG = "NATIVE"; - - public static native int getDnsFd(); - - public static native int connect(String nameserv_addr, String topdomain, boolean raw_mode, boolean lazy_mode, - String password); - - public static native String getIp(); - - public static native String getRemoteIp(); - - public static native int getNetbits(); - - public static native int getMtu(); - - public static native int tunnel(int fd); - - public static native void tunnelInterrupt(); - - public static native String getPropertyNetDns1(); - - /** - * Intent to distribute logmessages from native code - * LOG_MESSAGE(EXTRA_MESSAGE) - */ - public static final String ACTION_LOG_MESSAGE = "org.xapek.andiodine.IodineClient.ACTION_LOG_MESSAGE"; - - public static final String EXTRA_MESSAGE = "message"; - - @SuppressWarnings("UnusedDeclaration") - public static void log_callback(String message) { - Intent intent = new Intent(ACTION_LOG_MESSAGE); - - intent.putExtra(EXTRA_MESSAGE, message); - if (IodineVpnService.instance != null) { - IodineVpnService.instance.sendBroadcast(intent); - } else { - Log.d(TAG, "No VPNService running, cannot broadcast native message"); - } - - } - - static { - System.loadLibrary("iodine-client"); - Log.d(TAG, "Native Library iodine-client loaded"); - } -}
\ No newline at end of file diff --git a/src/org/xapek/andiodine/IodineMain.java b/src/org/xapek/andiodine/IodineMain.java deleted file mode 100644 index f631c1d..0000000 --- a/src/org/xapek/andiodine/IodineMain.java +++ /dev/null @@ -1,112 +0,0 @@ -package org.xapek.andiodine; - -import android.app.Activity; -import android.app.AlertDialog; -import android.app.FragmentTransaction; -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; -import android.content.IntentFilter; -import android.os.Bundle; -import android.util.Log; -import android.view.Menu; -import android.view.MenuItem; - -import org.xapek.andiodine.config.ConfigDatabase; - -import java.util.Scanner; - -public class IodineMain extends Activity { - private static final String TAG = "MAIN"; - private ConfigDatabase mConfigDatabase; - - private final FragmentList fragmentList = new FragmentList(); - private final FragmentStatus fragmentStatus = new FragmentStatus(); - - private final BroadcastReceiver broadcastReceiverStatusUpdates = new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - Log.d(TAG, "Got intent: " + intent); - if (IodineVpnService.ACTION_STATUS_ERROR.equals(intent.getAction())) { - // Switch to List of Configurations Fragment - FragmentTransaction ft = getFragmentManager().beginTransaction(); - ft.replace(R.id.main_fragment_status, fragmentList); - ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE); - ft.commit(); - } else if (IodineVpnService.ACTION_STATUS_IDLE.equals(intent.getAction())) { - // Switch to List of Configurations Fragment - FragmentTransaction ft = getFragmentManager().beginTransaction(); - ft.replace(R.id.main_fragment_status, fragmentList); - ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE); - ft.commit(); - } else if (IodineVpnService.ACTION_STATUS_CONNECT.equals(intent.getAction()) - || IodineVpnService.ACTION_STATUS_CONNECTED.equals(intent.getAction())) { - // Switch to Status Fragment - FragmentTransaction ft = getFragmentManager().beginTransaction(); - ft.replace(R.id.main_fragment_status, fragmentStatus); - ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE); - ft.commit(); - } - } - }; - - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setContentView(R.layout.main); - - mConfigDatabase = new ConfigDatabase(this); - - startService(new Intent(this, IodineVpnService.class)); - } - - @Override - public boolean onCreateOptionsMenu(Menu menu) { - getMenuInflater().inflate(R.menu.main, menu); - return true; - } - - @Override - protected void onResume() { - super.onResume(); - IntentFilter intentFilterStatusUpdates = new IntentFilter(); - intentFilterStatusUpdates.addAction(IodineVpnService.ACTION_STATUS_CONNECT); - intentFilterStatusUpdates.addAction(IodineVpnService.ACTION_STATUS_CONNECTED); - intentFilterStatusUpdates.addAction(IodineVpnService.ACTION_STATUS_ERROR); - intentFilterStatusUpdates.addAction(IodineVpnService.ACTION_STATUS_IDLE); - registerReceiver(broadcastReceiverStatusUpdates, intentFilterStatusUpdates); - - Log.d(TAG, "Request CONTROL_UPDATE"); - sendBroadcast(new Intent(IodineVpnService.ACTION_CONTROL_UPDATE)); - } - - @Override - protected void onPause() { - unregisterReceiver(broadcastReceiverStatusUpdates); - super.onPause(); - } - - @Override - protected void onDestroy() { - mConfigDatabase.close(); - super.onDestroy(); - } - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - if (item.getItemId() == R.id.menu_main_about) { - Scanner scanner = new Scanner(getResources().openRawResource(R.raw.license)); - scanner.useDelimiter("\\A"); - new AlertDialog.Builder(IodineMain.this)// - .setMessage(scanner.next()) // - .setCancelable(true)// - .create() // - .show(); - scanner.close(); - } else if (item.getItemId() == R.id.menu_main_add) { - startActivity(new Intent(this, IodinePref.class)); - } - return super.onOptionsItemSelected(item); - } -} diff --git a/src/org/xapek/andiodine/IodinePref.java b/src/org/xapek/andiodine/IodinePref.java deleted file mode 100644 index cc21b59..0000000 --- a/src/org/xapek/andiodine/IodinePref.java +++ /dev/null @@ -1,112 +0,0 @@ -package org.xapek.andiodine; - -import android.content.Intent; -import android.os.Bundle; -import android.util.Log; -import android.view.Menu; -import android.view.MenuItem; - -import org.xapek.andiodine.config.ConfigDatabase; -import org.xapek.andiodine.config.IodineConfiguration; -import org.xapek.andiodine.config.IodineConfiguration.NameserverMode; -import org.xapek.andiodine.config.IodineConfiguration.RequestType; - -public class IodinePref extends org.xapek.andiodine.preferences.PreferenceActivity { - public static final String EXTRA_CONFIGURATION_ID = "uuid"; - public static final String ACTION_CONFIGURATION_CHANGED = "org.xapek.andiodine.preferences.PreferenceActivity.CONFIGURATION_CHANGED"; - - private static final String TAG = "PREF"; - - private ConfigDatabase mConfigDatabase; - - private IodineConfiguration mIodineConfiguration; - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - getActionBar().setDisplayHomeAsUpEnabled(true); - - mConfigDatabase = new ConfigDatabase(this); - Long configurationId = getIntent().getLongExtra(EXTRA_CONFIGURATION_ID, -1); - if (configurationId == null || configurationId == -1) { - // Configuration ID is empty; create new configuration - mIodineConfiguration = new IodineConfiguration(); - } else { - mIodineConfiguration = mConfigDatabase.selectById(configurationId); - if (mIodineConfiguration == null) { - Log.e(TAG, "No configuration with uuid: " + configurationId + " found"); - finish(); - } - } - setContentValues(mIodineConfiguration.getContentValues()); - - // Name - addPreference(ConfigDatabase.COLUMN_CONF_NAME, "Name", R.string.pref_help_name, "New Connection"); - // Topdomain - addPreference(ConfigDatabase.COLUMN_CONF_TOP_DOMAIN, "Tunnel Topdomain", R.string.pref_help_topdomain, - "tun.example.com"); - // Password - addPreference(ConfigDatabase.COLUMN_CONF_PASSWORD, "Password", R.string.pref_help_password, ""); - // Tunnel Nameserver - addPreference(ConfigDatabase.COLUMN_CONF_TUNNEL_NAMESERVER, "Tunnel Nameserver (or empty)", - R.string.pref_help_tunnel_nameserver, ""); - // Nameserver Mode - String[] nameserverModes = new String[NameserverMode.values().length]; - for (int i = 0; i < NameserverMode.values().length; i++) { - nameserverModes[i] = NameserverMode.values()[i].name(); - } - addPreference(ConfigDatabase.COLUMN_CONF_NAMESERVER_MODE, "Nameserver Mode", - R.string.pref_help_nameserver_mode, nameserverModes, NameserverMode.LEAVE_DEFAULT.name()); - // Nameserver - addPreference(ConfigDatabase.COLUMN_CONF_NAMESERVER, "Nameserver", R.string.pref_help_nameserver, ""); - // Request Type - String[] requestTypes = new String[RequestType.values().length]; - for (int i = 0; i < RequestType.values().length; i++) { - requestTypes[i] = RequestType.values()[i].name(); - } - addPreference(ConfigDatabase.COLUMN_CONF_REQUEST_TYPE, "Request Type", R.string.pref_help_request_type, - requestTypes, RequestType.AUTODETECT.name()); - // Lazy Mode - addPreference(ConfigDatabase.COLUMN_CONF_LAZY_MODE, "Lazy mode", R.string.pref_help_lazy, true); - // Raw Mode - addPreference(ConfigDatabase.COLUMN_CONF_RAW_MODE, "Raw Mode", R.string.pref_help_raw, false); - // Default Route - addPreference(ConfigDatabase.COLUMN_CONF_DEFAULT_ROUTE, "Default Route", R.string.pref_help_default_route, true); - } - - @Override - protected void onDestroy() { - mConfigDatabase.close(); - super.onDestroy(); - } - - @Override - public boolean onCreateOptionsMenu(Menu menu) { - getMenuInflater().inflate(R.menu.pref, menu); - return super.onCreateOptionsMenu(menu); - } - - @Override - protected void onStop() { - mConfigDatabase.insertOrUpdate(mIodineConfiguration.getContentValues()); - Intent intent = new Intent(ACTION_CONFIGURATION_CHANGED); - intent.putExtra(EXTRA_CONFIGURATION_ID, mIodineConfiguration.getId()); - sendBroadcast(intent); - super.onStop(); - } - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - if (item.getItemId() == R.id.menu_pref_delete) { - // Delete current connection - if (mIodineConfiguration.getId() != null) { - mConfigDatabase.delete(mIodineConfiguration.getContentValues()); - } - finish(); - } else if (item.getItemId() == android.R.id.home) { - finish(); - } - return super.onOptionsItemSelected(item); - } -} diff --git a/src/org/xapek/andiodine/IodineVpnService.java b/src/org/xapek/andiodine/IodineVpnService.java deleted file mode 100644 index 2adad1c..0000000 --- a/src/org/xapek/andiodine/IodineVpnService.java +++ /dev/null @@ -1,350 +0,0 @@ -package org.xapek.andiodine; - -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; -import android.content.IntentFilter; -import android.net.VpnService; -import android.os.ParcelFileDescriptor; -import android.util.Log; - -import org.xapek.andiodine.config.ConfigDatabase; -import org.xapek.andiodine.config.IodineConfiguration; - -import java.io.IOException; -import java.net.InetAddress; -import java.net.UnknownHostException; - -public class IodineVpnService extends VpnService implements Runnable { - private class IodineVpnException extends Exception { - private static final long serialVersionUID = 32487871521160156L; - - public IodineVpnException(String message, Throwable e) { - super(message, e); - } - - public IodineVpnException(String message) { - super(message); - } - } - - private static final String TAG = "VPN_SERVICE"; - - public static IodineVpnService instance = null; - - /** - * long - */ - public static final String EXTRA_CONFIGURATION_ID = "configuration_id"; - /** - * String - */ - public static final String EXTRA_ERROR_MESSAGE = "message"; - - /** - * Intent to connect to VPN Connection - * CONTROL_CONNECT(EXTRA_CONFIGURATION_ID) - */ - - public static final String ACTION_CONTROL_CONNECT = "org.xapek.andiodine.IodineVpnService.CONTROL_CONNECT"; - /** - * Intent to close the vpn connection - */ - public static final String ACTION_CONTROL_DISCONNECT = "org.xapek.andiodine.IodineVpnService.CONTROL_DISCONNECT"; - - /** - * Intent to request a new status update - */ - public static final String ACTION_CONTROL_UPDATE = "org.xapek.andiodine.IodineVpnService.CONTROL_UPDATE"; - - /** - * Broadcast Action: The tunnel service is idle. This Action contains no - * extras. - */ - public static final String ACTION_STATUS_IDLE = "org.xapek.andiodine.IodineVpnService.STATUS_IDLE"; - - /** - * Broadcast Action: The user sent CONTROL_CONNECT and the vpn service is - * trying to connect. - * - * @see #EXTRA_CONFIGURATION_ID - */ - public static final String ACTION_STATUS_CONNECT = "org.xapek.andiodine.IodineVpnService.STATUS_CONNECT"; - /** - * Broadcast Action: The tunnel is connected - * - * @see #EXTRA_CONFIGURATION_ID - */ - public static final String ACTION_STATUS_CONNECTED = "org.xapek.andiodine.IodineVpnService.STATUS_CONNECTED"; - /** - * Broadcast Action: The tunnel was disconnected - * - * @see #EXTRA_CONFIGURATION_ID - */ - public static final String ACTION_STATUS_DISCONNECT = "org.xapek.andiodine.IodineVpnService.STATUS_DISCONNECT"; - /** - * Broadcast Action: An error occured - * - * @see #EXTRA_CONFIGURATION_ID - * @see #EXTRA_ERROR_MESSAGE - */ - public static final String ACTION_STATUS_ERROR = "org.xapek.andiodine.IodineVpnService.STATUS_ERROR"; - - private Thread mThread; - private ConfigDatabase configDatabase; - private IodineConfiguration mConfiguration; - private final BroadcastReceiver broadcastReceiver = new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - if (ACTION_CONTROL_DISCONNECT.equals(intent.getAction())) { - shutdown(); - } else if (ACTION_CONTROL_UPDATE.equals(intent.getAction())) { - sendStatus(); - } else if (ACTION_CONTROL_CONNECT.equals(intent.getAction())) { - if (mThread != null) { - setStatus(ACTION_STATUS_ERROR, -1L, getString(R.string.vpnservice_error_already_running)); - return; - } - - long configurationId = intent.getLongExtra(EXTRA_CONFIGURATION_ID, -1); - if (configurationId == -1L) { - setStatus(ACTION_STATUS_ERROR, -1L, getString(R.string.vpnservice_error_configuration_incomplete)); - return; - } - - mConfiguration = configDatabase.selectById(configurationId); - if (mConfiguration == null) { - setStatus(ACTION_STATUS_ERROR, mConfiguration.getId(), - getString(R.string.vpnservice_error_configuration_incomplete)); - return; - } - - mThread = new Thread(IodineVpnService.this, IodineVpnService.class.getName()); - mThread.start(); - } - } - }; - - private String currentActionStatus = ACTION_STATUS_IDLE; - - private Long currentConfigurationId = null; - - private String currentMessage = null; - - @Override - public void onCreate() { - super.onCreate(); - instance = this; - - configDatabase = new ConfigDatabase(this); - - IntentFilter filterInterruptAction = new IntentFilter(); - filterInterruptAction.addAction(ACTION_CONTROL_CONNECT); - filterInterruptAction.addAction(ACTION_CONTROL_DISCONNECT); - filterInterruptAction.addAction(ACTION_CONTROL_UPDATE); - registerReceiver(broadcastReceiver, filterInterruptAction); - } - - @Override - public int onStartCommand(Intent intent, int flags, int startId) { - sendStatus(); - return START_STICKY; - } - - private void shutdown() { - if (mConfiguration != null) - setStatus(ACTION_STATUS_DISCONNECT, mConfiguration.getId(), null); - else - setStatus(ACTION_STATUS_IDLE, null, null); - - if (mThread != null) { - mThread.interrupt(); - IodineClient.tunnelInterrupt(); - } - } - - @Override - public void onRevoke() { - shutdown(); - } - - @Override - public void onDestroy() { - if (mThread != null) { - mThread.interrupt(); - IodineClient.tunnelInterrupt(); - mThread = null; - } - instance = null; - configDatabase.close(); - unregisterReceiver(broadcastReceiver); - } - - private void setStatus(String ACTION_STATUS, Long configurationId, String message) { - currentActionStatus = ACTION_STATUS; - currentConfigurationId = configurationId; - currentMessage = message; - sendStatus(); - } - - private void sendStatus() { - Log.d(TAG, "Send status: " + currentActionStatus); - if (currentActionStatus != null) { - Intent intent = new Intent(currentActionStatus); - - if (currentConfigurationId != null) { - intent.putExtra(EXTRA_CONFIGURATION_ID, currentConfigurationId); - } - if (currentMessage != null) { - intent.putExtra(EXTRA_ERROR_MESSAGE, currentMessage); - } - Log.d(TAG, "Send: " + intent); - sendBroadcast(intent); - } - } - - @Override - public void run() { - try { - Log.d(TAG, "VPN Thread enter"); - setStatus(ACTION_STATUS_CONNECT, mConfiguration.getId(), null); - - String tunnelNamesver = IodineClient.getPropertyNetDns1(); - if (!"".equals(mConfiguration.getTunnelNameserver())) { - tunnelNamesver = mConfiguration.getTunnelNameserver(); - } - String password = ""; - if (!"".equals(mConfiguration.getPassword())) { - password = mConfiguration.getPassword(); - } - - int ret = IodineClient.connect(tunnelNamesver, mConfiguration.getTopDomain(), mConfiguration.getRawMode(), - mConfiguration.getLazyMode(), password); - - String errorMessage = ""; - switch (ret) { - case 0: - Log.d(TAG, "Handshake successful"); - setStatus(ACTION_STATUS_CONNECTED, currentConfigurationId, null); - runTunnel(); // this blocks until connection is closed - setStatus(ACTION_STATUS_IDLE, null, null); - break; - case 1: - if (errorMessage.equals("")) - errorMessage = getString(R.string.vpnservice_error_cant_open_dnssocket); - // Fall through - case 2: - if (errorMessage.equals("")) - errorMessage = getString(R.string.vpnservice_error_handshake_failed); - // fall through - default: - if (errorMessage.equals("")) - errorMessage = String.format(getString(R.string.vpnservice_error_unknown_error_code), ret); - - setStatus(ACTION_STATUS_ERROR, mConfiguration.getId(), errorMessage); - break; - } - } catch (IllegalStateException e) { - String errorMessage = "IllegalStateException"; - if (e.getMessage().contains("Cannot create interface")) { - errorMessage = "Failed to create tunnel network device"; - } else { - e.printStackTrace(); - } - setStatus(ACTION_STATUS_ERROR, mConfiguration.getId(), errorMessage); - } catch (IodineVpnException e) { - e.printStackTrace(); - - setStatus(ACTION_STATUS_ERROR, mConfiguration.getId(), - String.format(getString(R.string.vpnservice_error_unknown_error_string), e.getMessage())); - } finally { - mThread = null; - mConfiguration = null; - Log.d(TAG, "VPN Thread exit"); - } - } - - private void runTunnel() throws IodineVpnException { - Builder b = new Builder(); - b.setSession("Iodine VPN Service"); - - String ip = IodineClient.getIp(); - int netbits = IodineClient.getNetbits(); - int mtu = IodineClient.getMtu(); - Log.d(TAG, "Build tunnel for configuration: ip=" + ip + " netbits=" + netbits + " mtu=" + mtu); - - String[] ipBytesString = ip.split("\\."); - if (ipBytesString.length != 4) { - throw new IodineVpnException("Server sent invalid IP"); - } - byte[] ipBytes = new byte[4]; - for (int i = 0; i < 4; i++) { - try { - int integer = Integer.parseInt(ipBytesString[i]); - ipBytes[i] = (byte) (integer); - } catch (NumberFormatException e) { - throw new IodineVpnException("Server sent invalid IP", e); - } - } - - InetAddress hostAddress; - try { - hostAddress = InetAddress.getByAddress(ipBytes); - } catch (UnknownHostException e) { - throw new IodineVpnException("Server sent invalid IP", e); - } - try { - switch (mConfiguration.getNameserverMode()) { - case LEAVE_DEFAULT: - // do nothing - break; - case SET_SERVER_TUNNEL_IP: - b.addDnsServer(IodineClient.getRemoteIp()); - break; - case SET_CUSTOM: - b.addDnsServer(InetAddress.getByName(mConfiguration.getNameserver())); - break; - default: - throw new IodineVpnException("Invalid Nameserver mode"); - } - } catch (UnknownHostException e) { - throw new IodineVpnException("Invalid Nameserver address", e); - } - - b.addAddress(hostAddress, netbits); - if (mConfiguration.getDefaultRoute()) { - Log.d(TAG, "Set default route"); - b.addRoute("0.0.0.0", 0); // Default Route - } - b.setMtu(mtu); - - Log.d(TAG, "Build tunnel interface"); - ParcelFileDescriptor parcelFD; - try { - parcelFD = b.establish(); - } catch (Exception e) { - if (e.getMessage().contains("fwmark") || e.getMessage().contains("iptables")) { - throw new IodineVpnException( - "Error while creating interface, please check issue #9 at https://github.com/yvesf/andiodine/issues/9"); - } else { - throw new IodineVpnException("Error while creating interface: " - + e.getMessage()); - } - } - - protect(IodineClient.getDnsFd()); - - int tun_fd = parcelFD.detachFd(); - - setStatus(ACTION_STATUS_CONNECTED, mConfiguration.getId(), null); - - Log.d(TAG, "Tunnel active"); - IodineClient.tunnel(tun_fd); - try { - ParcelFileDescriptor.adoptFd(tun_fd).close(); - } catch (IOException e) { - throw new IodineVpnException( - "Failed to close fd after tunnel exited"); - } - } -} diff --git a/src/org/xapek/andiodine/config/ConfigDatabase.java b/src/org/xapek/andiodine/config/ConfigDatabase.java deleted file mode 100644 index c4245ba..0000000 --- a/src/org/xapek/andiodine/config/ConfigDatabase.java +++ /dev/null @@ -1,124 +0,0 @@ -package org.xapek.andiodine.config; - -import android.content.ContentValues; -import android.content.Context; -import android.database.Cursor; -import android.database.DatabaseUtils; -import android.database.SQLException; -import android.database.sqlite.SQLiteDatabase; -import android.database.sqlite.SQLiteOpenHelper; -import android.util.Log; - -import java.util.ArrayList; -import java.util.List; - -public class ConfigDatabase extends SQLiteOpenHelper { - public static final String TAG = "ConfigDatabase"; - - private static final String DATABASE_NAME = "andiodine.db"; - private static final int DATABASE_VERSION = 1; - static public final String TABLE_NAME_CONF = "configuration"; - static public final String COLUMN_CONF_ID = "id"; - static public final String COLUMN_CONF_NAME = "name"; - static public final String COLUMN_CONF_LAST_USED = "last_used"; - static public final String COLUMN_CONF_TUNNEL_NAMESERVER = "tunnel_nameserver"; - static public final String COLUMN_CONF_TOP_DOMAIN = "top_domain"; - static public final String COLUMN_CONF_PASSWORD = "password"; - static public final String COLUMN_CONF_NAMESERVER_MODE = "nameserver_mode"; - static public final String COLUMN_CONF_NAMESERVER = "nameserver"; - static public final String COLUMN_CONF_RAW_MODE = "raw_mode"; - static public final String COLUMN_CONF_LAZY_MODE = "lazy_mode"; - static public final String COLUMN_CONF_DEFAULT_ROUTE = "default_route"; - static public final String COLUMN_CONF_REQUEST_TYPE = "request_type"; - - private static final String createStmt = "CREATE TABLE " + TABLE_NAME_CONF + " (" + // - COLUMN_CONF_ID + " INTEGER PRIMARY KEY," + // - COLUMN_CONF_NAME + " TEXT," + // - COLUMN_CONF_LAST_USED + " INTEGER," + // - COLUMN_CONF_TUNNEL_NAMESERVER + " TEXT," + // - COLUMN_CONF_TOP_DOMAIN + " TEXT," + // - COLUMN_CONF_PASSWORD + " TEXT," + // - COLUMN_CONF_NAMESERVER_MODE + " TEXT," + // - COLUMN_CONF_NAMESERVER + " TEXT," + // - COLUMN_CONF_RAW_MODE + " INTEGER," + // Boolean stored as 1=true / 0=false - COLUMN_CONF_LAZY_MODE + " INTEGER," + // - COLUMN_CONF_DEFAULT_ROUTE + " INTEGER," + // - COLUMN_CONF_REQUEST_TYPE + " TEXT" + // - ");"; - - public ConfigDatabase(Context context) { - super(context, DATABASE_NAME, null, DATABASE_VERSION); - } - - @Override - public void onCreate(SQLiteDatabase db) { - db.execSQL(createStmt); - } - - @Override - public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { - } - - public void insert(ContentValues config) throws SQLException { - if (config.getAsLong(COLUMN_CONF_ID) != null) - throw new SQLException("id must be null for update"); - SQLiteDatabase writableDatabase = getWritableDatabase(); - long id = writableDatabase.insertOrThrow(TABLE_NAME_CONF, null, config); - writableDatabase.close(); - config.put(COLUMN_CONF_ID, id); - Log.d(TAG, "Insert id=" + id); - } - - public int update(ContentValues config) throws SQLException { - if (config.getAsLong(COLUMN_CONF_ID) == null) - throw new SQLException("id must NOT be null for update"); - SQLiteDatabase writableDatabase = getWritableDatabase(); - int rows = writableDatabase.update(TABLE_NAME_CONF, config, COLUMN_CONF_ID + " = ?", - new String[]{config.getAsString(COLUMN_CONF_ID)}); - writableDatabase.close(); - Log.d(TAG, "Update rows=" + rows); - return rows; - } - - public void delete(ContentValues config) throws SQLException { - if (config.getAsLong(COLUMN_CONF_ID) == null) - throw new SQLException("id must NOT be null for delete"); - SQLiteDatabase writableDatabase = getWritableDatabase(); - writableDatabase.delete(TABLE_NAME_CONF, COLUMN_CONF_ID + " = ?", - new String[]{config.getAsString(COLUMN_CONF_ID)}); - writableDatabase.close(); - } - - public IodineConfiguration selectById(Long id) throws SQLException { - ContentValues v = new ContentValues(); - SQLiteDatabase readableDatabase = getReadableDatabase(); - Cursor query = readableDatabase.query(TABLE_NAME_CONF, null, COLUMN_CONF_ID + " = ?", - new String[]{id.toString()}, null, null, null); - query.moveToFirst(); - DatabaseUtils.cursorRowToContentValues(query, v); - IodineConfiguration iodineConfiguration = new IodineConfiguration(v); - Log.d(TAG, "Selected: " + iodineConfiguration); - return iodineConfiguration; - } - - public List<IodineConfiguration> selectAll() throws SQLException { - List<IodineConfiguration> configurations = new ArrayList<IodineConfiguration>(); - SQLiteDatabase readableDatabase = getReadableDatabase(); - Cursor query = readableDatabase.query(TABLE_NAME_CONF, null, null, null, null, null, null); - - while (query.moveToNext()) { - ContentValues v = new ContentValues(); - DatabaseUtils.cursorRowToContentValues(query, v); - configurations.add(new IodineConfiguration(v)); - } - return configurations; - } - - public void insertOrUpdate(ContentValues config) { - try { - update(config); - } catch (SQLException e) { - insert(config); - } - } -} diff --git a/src/org/xapek/andiodine/config/IodineConfiguration.java b/src/org/xapek/andiodine/config/IodineConfiguration.java deleted file mode 100644 index 21aac6c..0000000 --- a/src/org/xapek/andiodine/config/IodineConfiguration.java +++ /dev/null @@ -1,132 +0,0 @@ -package org.xapek.andiodine.config; - -import android.content.ContentValues; - -/** - * Wrapper around ContentValues in Database - */ -public class IodineConfiguration { - public static enum NameserverMode { - LEAVE_DEFAULT, SET_SERVER_TUNNEL_IP, SET_CUSTOM - } - - public static enum RequestType { - AUTODETECT, NULL, TXT, SRV, MX, CNAME, A - } - - private final ContentValues v; - - public IodineConfiguration() { - v = new ContentValues(); - } - - public IodineConfiguration(ContentValues v) { - this.v = v; - } - - @Override - public boolean equals(Object o) { - if (o instanceof IodineConfiguration) { - return getId() != null && getId().equals(((IodineConfiguration) o).getId()); - } else { - return super.equals(o); - } - } - - public Long getId() { - return v.getAsLong(ConfigDatabase.COLUMN_CONF_ID); - } - - public boolean getDefaultRoute() { - return v.getAsInteger(ConfigDatabase.COLUMN_CONF_DEFAULT_ROUTE) == 1; - } - - public void setDefaultRoute(boolean isDefaultRoute) { - v.put(ConfigDatabase.COLUMN_CONF_DEFAULT_ROUTE, isDefaultRoute ? 1 : 0); - } - - public boolean getLazyMode() { - return v.getAsInteger(ConfigDatabase.COLUMN_CONF_LAZY_MODE) == 1; - } - - public String getName() { - return v.getAsString(ConfigDatabase.COLUMN_CONF_NAME); - } - - public String getNameserver() { - return v.getAsString(ConfigDatabase.COLUMN_CONF_NAMESERVER); - } - - public NameserverMode getNameserverMode() { - return NameserverMode.valueOf(v.getAsString(ConfigDatabase.COLUMN_CONF_NAMESERVER_MODE)); - } - - public String getPassword() { - return v.getAsString(ConfigDatabase.COLUMN_CONF_PASSWORD); - } - - public boolean getRawMode() { - return v.getAsInteger(ConfigDatabase.COLUMN_CONF_RAW_MODE) == 1; - } - - public RequestType getRequestType() { - return RequestType.valueOf(v.getAsString(ConfigDatabase.COLUMN_CONF_REQUEST_TYPE)); - } - - public String getTopDomain() { - return v.getAsString(ConfigDatabase.COLUMN_CONF_TOP_DOMAIN); - } - - public String getTunnelNameserver() { - return v.getAsString(ConfigDatabase.COLUMN_CONF_TUNNEL_NAMESERVER); - } - - public void setLazyMode(boolean lazyMode) { - v.put(ConfigDatabase.COLUMN_CONF_LAZY_MODE, lazyMode ? 1 : 0); - } - - public void setName(String name) { - v.put(ConfigDatabase.COLUMN_CONF_NAME, name); - } - - public void setNameserver(String nameserver) { - v.put(ConfigDatabase.COLUMN_CONF_NAMESERVER, nameserver); - } - - public void setNameserverMode(NameserverMode nameserverMode) { - v.put(ConfigDatabase.COLUMN_CONF_NAMESERVER_MODE, nameserverMode.name()); - } - - public void setPassword(String password) { - v.put(ConfigDatabase.COLUMN_CONF_PASSWORD, password); - } - - public void setRawMode(boolean rawMode) { - v.put(ConfigDatabase.COLUMN_CONF_RAW_MODE, rawMode ? 1 : 0); - } - - public void setRequestType(RequestType requestType) { - v.put(ConfigDatabase.COLUMN_CONF_REQUEST_TYPE, requestType.name()); - } - - public void setTopDomain(String topDomain) { - v.put(ConfigDatabase.COLUMN_CONF_TOP_DOMAIN, topDomain); - } - - public void setTunnelNameserver(String tunnelNameserver) { - v.put(ConfigDatabase.COLUMN_CONF_TUNNEL_NAMESERVER, tunnelNameserver); - } - - public void setId(Long id) { - v.put(ConfigDatabase.COLUMN_CONF_ID, id); - } - - public ContentValues getContentValues() { - return v; - } - - @Override - public String toString() { - return "[IodineConfiguration name=" + getName() + "]"; - } -} diff --git a/src/org/xapek/andiodine/preferences/AbstractPreference.java b/src/org/xapek/andiodine/preferences/AbstractPreference.java deleted file mode 100644 index 278de63..0000000 --- a/src/org/xapek/andiodine/preferences/AbstractPreference.java +++ /dev/null @@ -1,49 +0,0 @@ -package org.xapek.andiodine.preferences; - -import android.content.Context; -import android.util.Log; -import android.view.View; - -abstract class AbstractPreference { - public static final String TAG = "Preference"; - private final String mKey; - private final PreferenceActivity mPreferenceActivity; - private final String mTitle; - private final int mHelpMsgId; - - public AbstractPreference(PreferenceActivity preferenceActivity, String title, int helpResId, String key) { - mPreferenceActivity = preferenceActivity; - mTitle = title; - mHelpMsgId = helpResId; - mKey = key; - } - - protected abstract View getListItemView(Context context); - - public void persist(final String value) { - Log.d(TAG, String.format("persist String %s -> %s", mKey, value)); - mPreferenceActivity.getContentValues().put(mKey, value); - } - - public void persist(final boolean value) { - Log.d(TAG, String.format("persist boolean %s -> %s", mKey, "" + value)); - mPreferenceActivity.getContentValues().put(mKey, value ? 1 : 0); - } - - public boolean getAsBoolean() { - return mPreferenceActivity.getContentValues().getAsInteger(mKey) != null - && mPreferenceActivity.getContentValues().getAsInteger(mKey) == 1; - } - - public String getAsString() { - return mPreferenceActivity.getContentValues().getAsString(mKey); - } - - public String getTitle() { - return mTitle; - } - - public String getMessage() { - return mPreferenceActivity.getResources().getString(mHelpMsgId); - } -} diff --git a/src/org/xapek/andiodine/preferences/BooleanPreference.java b/src/org/xapek/andiodine/preferences/BooleanPreference.java deleted file mode 100644 index 9e7917d..0000000 --- a/src/org/xapek/andiodine/preferences/BooleanPreference.java +++ /dev/null @@ -1,33 +0,0 @@ -package org.xapek.andiodine.preferences; - -import android.content.Context; -import android.util.Log; -import android.view.View; -import android.widget.CheckBox; -import android.widget.CompoundButton; -import android.widget.CompoundButton.OnCheckedChangeListener; - -import org.xapek.andiodine.R; - -public class BooleanPreference extends AbstractPreference { - - public BooleanPreference(PreferenceActivity preferenceActivity, String title, int helpMsgId, String key) { - super(preferenceActivity, title, helpMsgId, key); - } - - @Override - protected View getListItemView(Context context) { - CheckBox view = new CheckBox(context); - view.setText(context.getString(R.string.enable) + " " + getTitle()); - Log.d(TAG, "Status: " + getTitle() + " = " + getAsBoolean()); - view.setChecked(getAsBoolean()); - view.setOnCheckedChangeListener(new OnCheckedChangeListener() { - @Override - public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { - persist(isChecked); - } - }); - return view; - } - -} diff --git a/src/org/xapek/andiodine/preferences/PreferenceActivity.java b/src/org/xapek/andiodine/preferences/PreferenceActivity.java deleted file mode 100644 index dd0faa4..0000000 --- a/src/org/xapek/andiodine/preferences/PreferenceActivity.java +++ /dev/null @@ -1,104 +0,0 @@ -package org.xapek.andiodine.preferences; - -import android.app.AlertDialog; -import android.app.ListActivity; -import android.content.ContentValues; -import android.content.Context; -import android.os.Bundle; -import android.view.LayoutInflater; -import android.view.View; -import android.view.View.OnClickListener; -import android.view.ViewGroup; -import android.widget.ArrayAdapter; -import android.widget.ImageButton; -import android.widget.LinearLayout; -import android.widget.ListView; -import android.widget.TextView; - -import org.xapek.andiodine.R; - -import java.util.ArrayList; -import java.util.List; - -public abstract class PreferenceActivity extends ListActivity { - private ArrayList<AbstractPreference> mPreferences; - - private ContentValues mContentValues = new ContentValues(); - - private static class DialogPreferenceAdapter extends ArrayAdapter<AbstractPreference> { - - private final LayoutInflater mInflater; - - private static class HelpOnClickListener implements OnClickListener { - private final AbstractPreference p; - - public HelpOnClickListener(AbstractPreference p) { - this.p = p; - } - - @Override - public void onClick(View v) { - new AlertDialog.Builder(v.getContext())// - .setTitle(p.getTitle())// - .setMessage(p.getMessage())// - .create().show(); - } - } - - public DialogPreferenceAdapter(Context context, List<AbstractPreference> preferences) { - super(context, -1, preferences); - mInflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE); - - } - - @Override - public View getView(int position, View convertView, ViewGroup parent) { - AbstractPreference item = getItem(position); - View rowView = mInflater.inflate(R.layout.rowlayout, parent, false); - LinearLayout content = (LinearLayout) rowView.findViewById(R.id.rowlayout_content); - ImageButton helpButton = (ImageButton) rowView.findViewById(R.id.rowlayout_help); - TextView title = (TextView) rowView.findViewById(R.id.rowlayout_title); - - content.addView(item.getListItemView(getContext())); - helpButton.setOnClickListener(new HelpOnClickListener(item)); - title.setText(item.getTitle()); - - return rowView; - } - } - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - mPreferences = new ArrayList<AbstractPreference>(); - - setListAdapter(new DialogPreferenceAdapter(this, mPreferences)); - } - - public void setContentValues(final ContentValues contentValues) { - mContentValues = contentValues; - } - - public ContentValues getContentValues() { - return mContentValues; - } - - public void addPreference(String key, String title, int helpMsgId, String defaultValue) { - if (mContentValues.get(key) == null) - mContentValues.put(key, defaultValue); - mPreferences.add(new TextPreference(this, title, helpMsgId, key)); - } - - public void addPreference(String key, String title, int helpMsgId, boolean defaultValue) { - BooleanPreference preference = new BooleanPreference(this, title, helpMsgId, key); - if (mContentValues.get(key) == null) - preference.persist(defaultValue); - mPreferences.add(preference); - } - - public void addPreference(String key, String title, int helpMsgId, String[] values, String defaultValue) { - if (mContentValues.get(key) == null) - mContentValues.put(key, defaultValue); - mPreferences.add(new SpinnerPreference(this, key, title, helpMsgId, values)); - } -} diff --git a/src/org/xapek/andiodine/preferences/SpinnerPreference.java b/src/org/xapek/andiodine/preferences/SpinnerPreference.java deleted file mode 100644 index 3528f05..0000000 --- a/src/org/xapek/andiodine/preferences/SpinnerPreference.java +++ /dev/null @@ -1,47 +0,0 @@ -package org.xapek.andiodine.preferences; - -import android.content.Context; -import android.view.View; -import android.widget.AdapterView; -import android.widget.AdapterView.OnItemSelectedListener; -import android.widget.ArrayAdapter; -import android.widget.Spinner; - -public class SpinnerPreference extends AbstractPreference { - private final String[] mValues; - - public SpinnerPreference(PreferenceActivity preferenceActivity, String key, String title, int helpResId, - String[] values) { - super(preferenceActivity, title, helpResId, key); - mValues = values; - } - - @Override - protected View getListItemView(Context context) { - Spinner view = new Spinner(context); - view.setAdapter(new ArrayAdapter<String>(context, android.R.layout.simple_list_item_1, mValues)); - - int i = 0; - for (final String value : mValues) { - if (value != null && value.equals(getAsString())) { - view.setSelection(i); - break; - } - i++; - } - - view.setOnItemSelectedListener(new OnItemSelectedListener() { - @Override - public void onItemSelected(AdapterView<?> parent, View view, int position, long id) { - String item = mValues[position]; - persist(item); - } - - @Override - public void onNothingSelected(AdapterView<?> parent) { - } - }); - - return view; - } -} diff --git a/src/org/xapek/andiodine/preferences/TextPreference.java b/src/org/xapek/andiodine/preferences/TextPreference.java deleted file mode 100644 index ae28f1e..0000000 --- a/src/org/xapek/andiodine/preferences/TextPreference.java +++ /dev/null @@ -1,35 +0,0 @@ -package org.xapek.andiodine.preferences; - -import android.content.Context; -import android.text.Editable; -import android.text.TextWatcher; -import android.view.View; -import android.widget.EditText; - -public class TextPreference extends AbstractPreference { - public TextPreference(PreferenceActivity preferenceActivity, String title, int helpMsgId, String key) { - super(preferenceActivity, title, helpMsgId, key); - } - - @Override - protected View getListItemView(Context context) { - final EditText view = new EditText(context); - view.setSingleLine(); - view.setText(getAsString()); - view.addTextChangedListener(new TextWatcher() { - @Override - public void onTextChanged(CharSequence s, int start, int before, int count) { - } - - @Override - public void beforeTextChanged(CharSequence s, int start, int count, int after) { - } - - @Override - public void afterTextChanged(Editable s) { - persist(s.toString()); - } - }); - return view; - } -} |