refactoring into cleaner packages

This commit is contained in:
Nathan Freitas 2015-02-02 11:04:32 -05:00
parent ee1d54826b
commit 7c303f1589
18 changed files with 412 additions and 274 deletions

View File

@ -1,8 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.torproject.android"
android:versionName="15.1.0"
android:versionCode="1510"
android:versionName="15.0.0-alpha-1"
android:versionCode="15001"
android:installLocation="auto"
>
@ -29,7 +29,7 @@
android:largeHeap="false"
>
<activity android:name=".Orbot"
<activity android:name=".OrbotMainActivity"
android:configChanges="orientation|screenSize"
android:excludeFromRecents="true"
android:launchMode="singleTop"
@ -63,6 +63,12 @@
</activity>
<activity android:name=".ui.OrbotLogActivity"
android:configChanges="orientation|screenSize"
android:exported="false"
/>
<!--
This is for ensuring the background service still runs when/if the app is swiped away
-->
@ -77,14 +83,13 @@
android:stateNotNeeded="true"
android:clearTaskOnLaunch="true"
android:finishOnTaskLaunch="true"
/>
<activity android:name=".wizard.LotsaText" android:exported="false"/>
<activity android:name=".wizard.Permissions" android:exported="false"/>
<activity android:name=".wizard.TipsAndTricks" android:exported="false"/>
<activity android:name=".wizard.ConfigureTransProxy" android:exported="false"/>
<activity android:name=".wizard.ChooseLocaleWizardActivity" android:exported="false"/>
<activity android:name=".ui.LotsaText" android:exported="false"/>
<activity android:name=".ui.TipsAndTricks" android:exported="false"/>
<activity android:name=".ui.ChooseLocaleWizardActivitycaleWizardActivity" android:exported="false"/>
<activity android:name=".settings.SettingsPreferences" android:label="@string/app_name"/>
<activity android:name=".settings.AppManager" android:label="@string/app_name"/>
@ -143,7 +148,7 @@
</intent-filter>
</service>
<receiver android:name=".OnBootReceiver">
<receiver android:name="org.torproject.android.service.OnBootReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.intent.action.QUICKBOOT_POWERON" />

View File

@ -3,7 +3,6 @@
package org.torproject.android;
import static org.torproject.android.TorConstants.TAG;
import info.guardianproject.browser.Browser;
import java.net.URLDecoder;
@ -13,11 +12,13 @@ import org.torproject.android.service.TorService;
import org.torproject.android.service.TorServiceConstants;
import org.torproject.android.service.TorServiceUtils;
import org.torproject.android.settings.SettingsPreferences;
import org.torproject.android.wizard.ChooseLocaleWizardActivity;
import org.torproject.android.ui.ChooseLocaleWizardActivity;
import org.torproject.android.ui.ImageProgressView;
import org.torproject.android.ui.Rotate3dAnimation;
import android.annotation.TargetApi;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
@ -38,7 +39,9 @@ import android.os.Handler;
import android.os.Message;
import android.os.RemoteException;
import android.support.v4.content.LocalBroadcastManager;
import android.support.v7.app.ActionBarActivity;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBarDrawerToggle;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.GestureDetector;
import android.view.GestureDetector.SimpleOnGestureListener;
@ -48,6 +51,7 @@ import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnLongClickListener;
import android.view.View.OnTouchListener;
import android.view.animation.AccelerateInterpolator;
@ -56,16 +60,15 @@ import android.widget.TextView;
import android.widget.Toast;
public class Orbot extends ActionBarActivity implements TorConstants, OnLongClickListener, OnTouchListener, OnSharedPreferenceChangeListener
public class OrbotMainActivity extends Activity implements TorConstants, OnLongClickListener, OnTouchListener, OnSharedPreferenceChangeListener
{
/* Useful UI bits */
//private TextView lblStatus = null; //the main text display widget
private TextView lblStatus = null; //the main text display widget
private ImageProgressView imgStatus = null; //the main touchable image for activating Orbot
private MenuItem mItemOnOff = null;
private TextView downloadText = null;
private TextView uploadText = null;
private boolean mDrawerOpen = false;
private Button mBtnBrowser = null;
private Button mBtnVPN = null;
@ -152,8 +155,6 @@ public class Orbot extends ActionBarActivity implements TorConstants, OnLongClic
}
};
ProgressDialog mProgressDialog;
private void startService (String action)
{
@ -171,58 +172,47 @@ public class Orbot extends ActionBarActivity implements TorConstants, OnLongClic
}
private DrawerLayout mDrawer;
private ActionBarDrawerToggle mDrawerToggle;
private Toolbar mToolbar;
private void doLayout ()
{
setContentView(R.layout.layout_main);
// lblStatus = (TextView)findViewById(R.id.lblStatus);
// lblStatus.setOnLongClickListener(this);
mToolbar = (Toolbar) findViewById(R.id.toolbar);
mToolbar.inflateMenu(R.menu.orbot_main);
mToolbar.setTitle(R.string.app_name);
mDrawer = (DrawerLayout) findViewById(R.id.drawer_layout);
mDrawerToggle = new ActionBarDrawerToggle(
this, mDrawer, mToolbar,
android.R.string.ok, android.R.string.cancel
);
mDrawer.setDrawerListener(mDrawerToggle);
mDrawerToggle.setDrawerIndicatorEnabled(true);
mDrawerToggle.syncState();
mDrawerToggle.setToolbarNavigationClickListener(new OnClickListener ()
{
@Override
public void onClick(View v) {
}
});
lblStatus = (TextView)findViewById(R.id.lblStatus);
imgStatus = (ImageProgressView)findViewById(R.id.imgStatus);
imgStatus.setOnLongClickListener(this);
imgStatus.setOnTouchListener(this);
// lblStatus.setText("Initializing the application...");
downloadText = (TextView)findViewById(R.id.trafficDown);
uploadText = (TextView)findViewById(R.id.trafficUp);
// mTxtOrbotLog = (TextView)findViewById(R.id.orbotLog);
/*
mDrawer = ((SlidingDrawer)findViewById(R.id.SlidingDrawer));
Button slideButton = (Button)findViewById(R.id.slideButton);
if (slideButton != null)
{
slideButton.setOnTouchListener(new OnTouchListener (){
@Override
public boolean onTouch(View v, MotionEvent event) {
if (event.equals(MotionEvent.ACTION_DOWN))
{
mDrawerOpen = !mDrawerOpen;
mTxtOrbotLog.setEnabled(mDrawerOpen);
}
return false;
}
});
}*/
/*
ScrollingMovementMethod smm = new ScrollingMovementMethod();
mTxtOrbotLog.setMovementMethod(smm);
mTxtOrbotLog.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
ClipboardManager cm = (ClipboardManager)getSystemService(Context.CLIPBOARD_SERVICE);
cm.setText(mTxtOrbotLog.getText());
Toast.makeText(Orbot.this, "LOG COPIED TO CLIPBOARD", Toast.LENGTH_SHORT).show();
return true;
}
});*/
downloadText.setText(formatCount(0) + " / " + formatTotal(0));
uploadText.setText(formatCount(0) + " / " + formatTotal(0));
@ -269,26 +259,6 @@ public class Orbot extends ActionBarActivity implements TorConstants, OnLongClic
}
/*
private void appendLogTextAndScroll(String text)
{
if(mTxtOrbotLog != null && text != null && text.length() > 0){
if (mTxtOrbotLog.getText().length() > MAX_LOG_LENGTH)
mTxtOrbotLog.setText("");
mTxtOrbotLog.append(text + "\n");
final Layout layout = mTxtOrbotLog.getLayout();
if(layout != null){
int scrollDelta = layout.getLineBottom(mTxtOrbotLog.getLineCount() - 1)
- mTxtOrbotLog.getScrollY() - mTxtOrbotLog.getHeight();
if(scrollDelta > 0)
mTxtOrbotLog.scrollBy(0, scrollDelta);
}
}
}*/
/*
* Create the UI Options Menu (non-Javadoc)
* @see android.app.Activity#onCreateOptionsMenu(android.view.Menu)
@ -872,7 +842,7 @@ public class Orbot extends ActionBarActivity implements TorConstants, OnLongClic
if (button)
{
aDialog = new AlertDialog.Builder(Orbot.this)
aDialog = new AlertDialog.Builder(OrbotMainActivity.this)
.setIcon(R.drawable.onion32)
.setTitle(title)
.setMessage(msg)
@ -881,7 +851,7 @@ public class Orbot extends ActionBarActivity implements TorConstants, OnLongClic
}
else
{
aDialog = new AlertDialog.Builder(Orbot.this)
aDialog = new AlertDialog.Builder(OrbotMainActivity.this)
.setIcon(R.drawable.onion32)
.setTitle(title)
.setMessage(msg)
@ -906,8 +876,7 @@ public class Orbot extends ActionBarActivity implements TorConstants, OnLongClic
mBtnBrowser.setEnabled(true);
mBtnVPN.setEnabled(true);
String lblMsg = getString(R.string.status_activated);
//lblStatus.setText(lblMsg);
lblStatus.setText("");
if (mItemOnOff != null)
mItemOnOff.setTitle(R.string.menu_stop);
@ -949,11 +918,10 @@ public class Orbot extends ActionBarActivity implements TorConstants, OnLongClic
if (mItemOnOff != null)
mItemOnOff.setTitle(R.string.menu_stop);
/**
if (lblStatus != null && torServiceMsg != null)
if (torServiceMsg.indexOf('%')!=-1)
lblStatus.setText(torServiceMsg);
**/
//appendLogTextAndScroll(torServiceMsg);
@ -962,6 +930,7 @@ public class Orbot extends ActionBarActivity implements TorConstants, OnLongClic
else if (torStatus == TorServiceConstants.STATUS_OFF)
{
imgStatus.setImageResource(R.drawable.toroff);
lblStatus.setText("");
//lblStatus.setText(getString(R.string.status_disabled) + "\n" + getString(R.string.press_to_start));
if (mItemOnOff != null)
@ -1009,12 +978,9 @@ public class Orbot extends ActionBarActivity implements TorConstants, OnLongClic
startService (TorServiceConstants.CMD_STOP);
torStatus = TorServiceConstants.STATUS_OFF;
Message msg = mHandler.obtainMessage(TorServiceConstants.DISABLE_TOR_MSG);
mHandler.sendMessage(msg);
Message msg = mHandler.obtainMessage(TorServiceConstants.DISABLE_TOR_MSG);
mHandler.sendMessage(msg);
}
/*
@ -1022,35 +988,31 @@ public class Orbot extends ActionBarActivity implements TorConstants, OnLongClic
* @see android.view.View.OnClickListener#onClick(android.view.View)
*/
public boolean onLongClick(View view) {
if (!mDrawerOpen)
{
try
{
if (torStatus == TorServiceConstants.STATUS_OFF)
{
startTor();
}
else
{
stopTor();
stopService ();
}
return true;
}
catch (Exception e)
{
Log.d(TAG,"error onclick",e);
}
try
{
if (torStatus == TorServiceConstants.STATUS_OFF)
{
startTor();
}
else
{
stopTor();
stopService ();
}
return true;
}
catch (Exception e)
{
Log.d(TAG,"error onclick",e);
}
}
return false;
}

View File

@ -1,134 +0,0 @@
package org.torproject.android;
import java.util.Random;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
public class RandomColorCircleView extends View
{
private Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
private float initX, initY, radius;
private boolean drawing = false;
Random rand = new Random();
public RandomColorCircleView(Context context) {
super(context);
// TODO Auto-generated constructor stub
init();
}
public RandomColorCircleView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public RandomColorCircleView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}
private void init(){
paint.setStyle(Paint.Style.STROKE);
paint.setColor(Color.WHITE);
paint.setAntiAlias(false);
paint.setStrokeWidth(6);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
setMeasuredDimension(MeasureSpec.getSize(widthMeasureSpec),
MeasureSpec.getSize(heightMeasureSpec));
}
int a1 = 30;
int a2 = 255;
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
for (int i = 0; i < 20; i++)
{
float r = rand.nextFloat()*255f;
float g = rand.nextFloat()*255f;
float b = rand.nextFloat()*255f;
paint.setARGB(a1,(int)r,(int)g,(int)b);
float x = rand.nextFloat() * getWidth();
float y = rand.nextFloat() * getHeight();
float w = rand.nextFloat() * getWidth();
float h = rand.nextFloat() * getHeight();
canvas.drawCircle(x, y, w/2, paint);
}
}
int a1mod = 1;
public void updateAlpha ()
{
a1 += a1mod;
if (a1 > 255 || a1 < 0)
a1mod *= -1;
}
/*
@Override
public boolean onTouchEvent(MotionEvent event) {
int action = event.getAction();
if (action==MotionEvent.ACTION_MOVE){
float x = event.getX();
float y = event.getY();
// radius = (float) Math.sqrt(Math.pow(x-initX, 2) + Math.pow(y-initY, 2));
//updateAlpha();
a1 = (int)(255*(y/((float)getHeight())));
}
else if (action==MotionEvent.ACTION_DOWN){
initX = event.getX();
initY = event.getY();
radius = 1;
drawing = true;
}
else if (action==MotionEvent.ACTION_UP){
drawing = false;
}
return true;
}*/
}

View File

@ -0,0 +1,14 @@
package org.torproject.android.pluto;
public class PlutoFactory {
//load pluto.properties from res/raw/pluto.properties
//ensure the PT binaries are installed and exe
//expose the installed PT's via a simple factory instance interface .getPlutoInstance("obfs3")
//return instance with interface for getting exe path, directly starting/stopping, monitoring status, etc
}

View File

@ -0,0 +1,194 @@
/* Copyright (c) 2009, Nathan Freitas, Orbot / The Guardian Project - http://openideals.com/guardian */
/* See LICENSE for licensing information */
package org.torproject.android.pluto;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.StringBufferInputStream;
import java.util.ArrayList;
import java.util.concurrent.TimeoutException;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import org.sufficientlysecure.rootcommands.Shell;
import org.sufficientlysecure.rootcommands.command.SimpleCommand;
import org.torproject.android.R;
import org.torproject.android.TorConstants;
import android.content.Context;
import android.os.Build;
import android.util.Log;
public class PlutoInstaller {
private File installFolder;
private Context context;
private final static int FILE_WRITE_BUFFER_SIZE = 1024;
private final static String CHMOD_EXE_VALUE = "770";
private final static String COMMAND_RM_FORCE = "rm -f ";
public PlutoInstaller (Context context, File installFolder)
{
this.installFolder = installFolder;
this.context = context;
}
public boolean installBinaries () throws Exception
{
InputStream is;
File outFile;
installFolder.mkdirs();
Shell shell = Shell.startShell(new ArrayList<String>(),installFolder.getAbsolutePath());
String ptAsset = null;
is = context.getResources().openRawResource(R.raw.obfsclient);
outFile = new File(installFolder, ptAsset);
shell.add(new SimpleCommand(COMMAND_RM_FORCE + outFile.getAbsolutePath())).waitForFinish();
streamToFile(is,outFile, false, true);
enableBinExec (outFile);
return true;
}
private boolean enableBinExec (File fileBin) throws Exception
{
if (!fileBin.canExecute())
{
Shell shell = Shell.startShell();
shell.add(new SimpleCommand("chmod " + CHMOD_EXE_VALUE + ' ' + fileBin.getCanonicalPath())).waitForFinish();
File fileTest = new File(fileBin.getCanonicalPath());
shell.close();
}
return fileBin.canExecute();
}
/*
* Write the inputstream contents to the file
*/
public static boolean streamToFile(InputStream stm, File outFile, boolean append, boolean zip) throws IOException
{
byte[] buffer = new byte[FILE_WRITE_BUFFER_SIZE];
int bytecount;
OutputStream stmOut = new FileOutputStream(outFile.getAbsolutePath(), append);
ZipInputStream zis = null;
if (zip)
{
zis = new ZipInputStream(stm);
ZipEntry ze = zis.getNextEntry();
stm = zis;
}
while ((bytecount = stm.read(buffer)) > 0)
{
stmOut.write(buffer, 0, bytecount);
}
stmOut.close();
stm.close();
if (zis != null)
zis.close();
return true;
}
//copy the file from inputstream to File output - alternative impl
public static void copyFile (InputStream is, File outputFile)
{
try {
outputFile.createNewFile();
DataOutputStream out = new DataOutputStream(new FileOutputStream(outputFile));
DataInputStream in = new DataInputStream(is);
int b = -1;
byte[] data = new byte[1024];
while ((b = in.read(data)) != -1) {
out.write(data);
}
if (b == -1); //rejoice
//
out.flush();
out.close();
in.close();
// chmod?
} catch (IOException ex) {
Log.e(TorConstants.TAG, "error copying binary", ex);
}
}
/**
* Copies a raw resource file, given its ID to the given location
* @param ctx context
* @param resid resource id
* @param file destination file
* @param mode file permissions (E.g.: "755")
* @throws IOException on error
* @throws InterruptedException when interrupted
*/
public static void copyRawFile(Context ctx, int resid, File file, String mode, boolean isZipd) throws IOException, InterruptedException
{
final String abspath = file.getAbsolutePath();
// Write the iptables binary
final FileOutputStream out = new FileOutputStream(file);
InputStream is = ctx.getResources().openRawResource(resid);
if (isZipd)
{
ZipInputStream zis = new ZipInputStream(is);
ZipEntry ze = zis.getNextEntry();
is = zis;
}
byte buf[] = new byte[1024];
int len;
while ((len = is.read(buf)) > 0) {
out.write(buf, 0, len);
}
out.close();
is.close();
// Change the permissions
Runtime.getRuntime().exec("chmod "+mode+" "+abspath).waitFor();
}
}

View File

@ -0,0 +1,9 @@
package org.torproject.android.pluto;
import java.io.File;
public class PlutoInstance {
public String name;
public File fileBinary;
}

View File

@ -1,4 +1,4 @@
package org.torproject.android;
package org.torproject.android.service;
//list view with add/remove hidden services - user is prompted for port

View File

@ -1,7 +1,5 @@
package org.torproject.android;
package org.torproject.android.service;
import org.torproject.android.service.TorService;
import org.torproject.android.service.TorServiceUtils;
import android.content.BroadcastReceiver;
import android.content.Context;

View File

@ -47,10 +47,9 @@ import org.json.JSONArray;
import org.json.JSONObject;
import org.sufficientlysecure.rootcommands.Shell;
import org.sufficientlysecure.rootcommands.command.SimpleCommand;
import org.torproject.android.Orbot;
import org.torproject.android.OrbotMainActivity;
import org.torproject.android.R;
import org.torproject.android.TorConstants;
import org.torproject.android.Utils;
import org.torproject.android.settings.AppManager;
import org.torproject.android.settings.TorifiedApp;
import org.torproject.android.vpn.OrbotVpnService;
@ -241,7 +240,7 @@ public class TorService extends Service implements TorServiceConstants, TorConst
{
//Reusable code.
Intent intent = new Intent(TorService.this, Orbot.class);
Intent intent = new Intent(TorService.this, OrbotMainActivity.class);
PendingIntent pendIntent = PendingIntent.getActivity(TorService.this, 0, intent, 0);
if (mNotifyBuilder == null)

View File

@ -2,7 +2,7 @@
/* See LICENSE for licensing information */
package org.torproject.android;
package org.torproject.android.service;
import java.io.BufferedReader;
import java.io.File;

View File

@ -1,4 +1,4 @@
package org.torproject.android.wizard;
package org.torproject.android.ui;
import java.util.Locale;

View File

@ -1,4 +1,4 @@
package org.torproject.android;
package org.torproject.android.ui;
import java.util.Random;

View File

@ -1,4 +1,4 @@
package org.torproject.android.wizard;
package org.torproject.android.ui;
import org.torproject.android.R;
import org.torproject.android.TorConstants;

View File

@ -1,4 +1,4 @@
package org.torproject.android;
package org.torproject.android.ui;
import java.io.BufferedReader;
import java.io.File;
@ -9,6 +9,11 @@ import java.util.ArrayList;
import org.sufficientlysecure.rootcommands.Shell;
import org.sufficientlysecure.rootcommands.command.SimpleCommand;
import org.torproject.android.R;
import org.torproject.android.R.id;
import org.torproject.android.R.layout;
import org.torproject.android.R.menu;
import org.torproject.android.R.raw;
import org.torproject.android.service.TorResourceInstaller;
import org.torproject.android.service.TorServiceConstants;

View File

@ -0,0 +1,75 @@
/* Copyright (c) 2009, Nathan Freitas, Orbot / The Guardian Project - https://guardianproject.info */
/* See LICENSE for licensing information */
package org.torproject.android.ui;
import org.torproject.android.TorConstants;
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.support.v4.content.LocalBroadcastManager;
public class OrbotLogActivity extends Activity implements TorConstants
{
/** Called when the activity is first created. */
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
doLayout();
LocalBroadcastManager.getInstance(this).registerReceiver(mMessageReceiver,
new IntentFilter("log"));
}
// Our handler for received Intents. This will be called whenever an Intent
// with an action named "custom-event-name" is broadcasted.
private BroadcastReceiver mMessageReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
// Get extra data included in the Intent
if (intent.hasExtra("log"))
{
String log = intent.getStringExtra("log");
updateStatus(log);
}
}
};
private void doLayout ()
{
}
private void updateStatus(String log)
{
}
@Override
protected void onDestroy() {
super.onDestroy();
LocalBroadcastManager.getInstance(this).unregisterReceiver(mMessageReceiver);
}
}

View File

@ -1,4 +1,4 @@
package org.torproject.android;
package org.torproject.android.ui;
import android.graphics.Camera;
import android.graphics.Matrix;

View File

@ -1,6 +1,6 @@
package org.torproject.android.wizard;
package org.torproject.android.ui;
import org.torproject.android.Orbot;
import org.torproject.android.OrbotMainActivity;
import org.torproject.android.R;
import org.torproject.android.TorConstants;

View File

@ -41,13 +41,13 @@ public class OrbotVpnService extends VpnService implements Handler.Callback {
private PendingIntent mConfigureIntent;
private Handler mHandler;
private Thread mThreadProxy;
private Thread mThreadVPN;
private String mSessionName = "OrbotVPN";
private ParcelFileDescriptor mInterface;
private int mSocksProxyPort = 9999;
//private Thread mThreadProxy;
//private int mSocksProxyPort = 9999;
// private ProxyServer mProxyServer;
private final static int VPN_MTU = 1500;
@ -63,7 +63,7 @@ public class OrbotVpnService extends VpnService implements Handler.Callback {
// Stop the previous session by interrupting the thread.
if (mThreadVPN == null || (!mThreadVPN.isAlive()))
{
startSocksBypass ();
enableAppRouting ();
setupTun2Socks();
}
@ -71,8 +71,19 @@ public class OrbotVpnService extends VpnService implements Handler.Callback {
return START_STICKY;
}
private void startSocksBypass ()
private void enableAppRouting ()
{
boolean isLollipop = false;
if (isLollipop)
{
//allow for specific apps to be sent through VPN based on list selection
}
else
{
//do socks bypass trick
}
}
@Override