diff --git a/app/build.gradle b/app/build.gradle
index c5b8ded9..7629b10f 100755
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -101,7 +101,7 @@ dependencies {
implementation "org.mozilla.components:browser-engine-gecko:73.0.8"
implementation "org.mozilla.components:browser-icons:73.0.9"
- implementation "org.mozilla.geckoview:geckoview:80.0.20200903001900"
+ implementation "org.mozilla.geckoview:geckoview:89.0.20210524222230"
implementation "org.mozilla.components:concept-fetch:73.0.9"
implementation "org.mozilla.components:concept-base:73.0.9"
implementation "org.mozilla.components:support-utils:73.0.9"
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 48ad5e19..e498b729 100755
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -233,10 +233,6 @@
android:resource="@xml/provider_paths" />
-
-->
@@ -250,11 +246,27 @@
android:resource="@xml/provider_paths" />
+
+
+
+
+
+
+
diff --git a/app/src/main/java/com/darkweb/genesissearchengine/appManager/activityContextManager.java b/app/src/main/java/com/darkweb/genesissearchengine/appManager/activityContextManager.java
index 3c01b1a3..2dae71b6 100755
--- a/app/src/main/java/com/darkweb/genesissearchengine/appManager/activityContextManager.java
+++ b/app/src/main/java/com/darkweb/genesissearchengine/appManager/activityContextManager.java
@@ -179,6 +179,16 @@ public class activityContextManager
}
}
+ public void onResetLanguage(){
+ for(int mCounter=0;mCounter
- {
- mSession.stop();
- mSession.loadUri(mSession.getCurrentURL());
- }, 500);
+ mSession.stop();
+ loadURL(mSession.getCurrentURL(), mNestedGeckoView, pcontext);
}else {
String mURL = mSession.getCurrentURL();
if(mURL.equals("https://genesishiddentechnologies.com") || mURL.startsWith(CONST_GENESIS_URL_CACHED) || mURL.startsWith(CONST_GENESIS_URL_CACHED_DARK)){
@@ -140,7 +141,6 @@ public class geckoClients
if(mRuntime==null){
mRuntime = GeckoRuntime.getDefault(context.getApplicationContext());
mRuntime.getSettings().setAboutConfigEnabled(true);
- mRuntime.getSettings().setAboutConfigEnabled(true);
mRuntime.getSettings().setAutomaticFontSizeAdjustment(false);
mRuntime.getSettings().setWebFontsEnabled(status.sShowWebFonts);
mRuntime.getSettings().setForceUserScalableEnabled(status.sSettingEnableZoom);
@@ -202,8 +202,10 @@ public class geckoClients
public String getTheme(){
if(mSessionID.equals(strings.GENERIC_EMPTY_STR)){
return null;
- }else {
+ }else if(mSession!=null && mSession.getTheme()!=null){
return mSession.getTheme();
+ }else {
+ return null;
}
}
@@ -242,6 +244,8 @@ public class geckoClients
String mURL = constants.CONST_GENESIS_URL_CACHED + "?pData="+ dataController.getInstance().invokeReferenceWebsite(dataEnums.eReferenceWebsiteCommands.M_FETCH,null);
mSession.getSettings().setAllowJavascript(true);
mSession.initURL(mURL);
+
+ mSession.stop();
mSession.loadUri(mURL);
}else {
String mURL = constants.CONST_GENESIS_URL_CACHED_DARK + "?pData="+ dataController.getInstance().invokeReferenceWebsite(dataEnums.eReferenceWebsiteCommands.M_FETCH,null);
diff --git a/app/src/main/java/com/darkweb/genesissearchengine/appManager/homeManager/geckoManager/geckoSession.java b/app/src/main/java/com/darkweb/genesissearchengine/appManager/homeManager/geckoManager/geckoSession.java
index 44583635..76e7e717 100644
--- a/app/src/main/java/com/darkweb/genesissearchengine/appManager/homeManager/geckoManager/geckoSession.java
+++ b/app/src/main/java/com/darkweb/genesissearchengine/appManager/homeManager/geckoManager/geckoSession.java
@@ -50,7 +50,7 @@ import org.mozilla.geckoview.GeckoView;
import org.mozilla.geckoview.SlowScriptResponse;
import org.mozilla.geckoview.WebRequestError;
import org.mozilla.geckoview.WebResponse;
-import org.torproject.android.proxy.wrapper.orbotLocalConstants;
+import org.torproject.android.service.wrapper.orbotLocalConstants;
import java.io.File;
import java.io.FileOutputStream;
@@ -72,6 +72,7 @@ import static com.darkweb.genesissearchengine.constants.constants.CONST_GENESIS_
import static com.darkweb.genesissearchengine.constants.constants.CONST_GENESIS_HELP_URL_CACHE_DARK;
import static com.darkweb.genesissearchengine.constants.constants.CONST_GENESIS_URL_CACHED;
import static com.darkweb.genesissearchengine.constants.constants.CONST_GENESIS_URL_CACHED_DARK;
+import static com.darkweb.genesissearchengine.constants.enums.etype.M_DEFAULT_BROWSER;
import static com.darkweb.genesissearchengine.constants.enums.etype.M_RATE_COUNT;
import static com.darkweb.genesissearchengine.pluginManager.pluginEnums.eMessageManager.M_LONG_PRESS_URL;
import static com.darkweb.genesissearchengine.pluginManager.pluginEnums.eMessageManager.M_LONG_PRESS_WITH_LINK;
@@ -102,6 +103,7 @@ geckoSession extends GeckoSession implements GeckoSession.MediaDelegate,GeckoSes
private boolean mRemovableFromBackPressed = false;
private boolean mThemeChanged = false;
private int mScollOffset = 0;
+ private selectionActionDelegate mSelectionActionDelegate;
/*Temp Variables*/
private GeckoSession.HistoryDelegate.HistoryList mHistoryList = null;
@@ -131,8 +133,9 @@ geckoSession extends GeckoSession implements GeckoSession.MediaDelegate,GeckoSes
setPermissionDelegate(this);
setScrollDelegate(this);
mDownloadManager = new geckoDownloadManager();
+ mSelectionActionDelegate = new selectionActionDelegate(mContext, true);
setPromptDelegate(new geckoPromptView(mContext));
- setSelectionActionDelegate(new selectionActionDelegate(mContext, true));
+ setSelectionActionDelegate(mSelectionActionDelegate);
}
public void onDestroy(){
@@ -358,6 +361,9 @@ geckoSession extends GeckoSession implements GeckoSession.MediaDelegate,GeckoSes
mContext.get().runOnUiThread(() -> event.invokeObserver(Arrays.asList(5,mSessionID), enums.etype.progress_update));
}else {
if(progress==100){
+ if(!mCurrentURL.contains("genesis")){
+ checkApplicationRate();
+ }
if(!mIsProgressBarChanging){
mIsProgressBarChanging = true;
mContext.get().runOnUiThread(() -> event.invokeObserver(Arrays.asList(mProgress,mSessionID), enums.etype.progress_update));
@@ -529,7 +535,6 @@ geckoSession extends GeckoSession implements GeckoSession.MediaDelegate,GeckoSes
event.invokeObserver(Arrays.asList(var1.uri,mSessionID), enums.etype.start_proxy);
event.invokeObserver(Arrays.asList(mCurrentURL,mSessionID), enums.etype.search_update);
- checkApplicationRate();
/* Its Absence causes delay on first launch*/
@@ -732,6 +737,7 @@ geckoSession extends GeckoSession implements GeckoSession.MediaDelegate,GeckoSes
@Override
public void onFullScreen(@NonNull GeckoSession var1, boolean var2) {
mFullScreen = var2;
+ mSelectionActionDelegate.setFullScreen(mFullScreen);
event.invokeObserver(Arrays.asList(var2,mSessionID), enums.etype.on_full_screen);
}
@@ -1105,10 +1111,15 @@ geckoSession extends GeckoSession implements GeckoSession.MediaDelegate,GeckoSes
private void checkApplicationRate(){
if(status.sSettingIsAppStarted){
- if(status.sRateCount==10){
+ if(status.sGlobalURLCount == 10){
event.invokeObserver(Arrays.asList(mCurrentURL,mSessionID,mCurrentTitle, mTheme), M_RATE_APPLICATION);
}
- status.sRateCount+=1;
+
+ else if(status.sGlobalURLCount == 20 || status.sGlobalURLCount == 80){
+ event.invokeObserver(Arrays.asList(mCurrentURL,mSessionID,mCurrentTitle, mTheme), M_DEFAULT_BROWSER);
+ }
+
+ status.sGlobalURLCount +=1;
event.invokeObserver(Arrays.asList(mCurrentURL,mSessionID,mCurrentTitle, mTheme), M_RATE_COUNT);
}
}
diff --git a/app/src/main/java/com/darkweb/genesissearchengine/appManager/homeManager/geckoManager/selectionActionDelegate.java b/app/src/main/java/com/darkweb/genesissearchengine/appManager/homeManager/geckoManager/selectionActionDelegate.java
index e62f0034..2d3752d3 100644
--- a/app/src/main/java/com/darkweb/genesissearchengine/appManager/homeManager/geckoManager/selectionActionDelegate.java
+++ b/app/src/main/java/com/darkweb/genesissearchengine/appManager/homeManager/geckoManager/selectionActionDelegate.java
@@ -3,6 +3,9 @@ package com.darkweb.genesissearchengine.appManager.homeManager.geckoManager;
import android.annotation.TargetApi;
import android.app.Activity;
import android.content.ActivityNotFoundException;
+import android.content.ClipData;
+import android.content.ClipboardManager;
+import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Matrix;
@@ -56,6 +59,7 @@ public class selectionActionDelegate implements ActionMode.Callback,
protected final boolean mUseFloatingToolbar;
protected final @NonNull Matrix mTempMatrix = new Matrix();
protected final @NonNull RectF mTempRect = new RectF();
+ private boolean mFullScreen = false;
private boolean mExternalActionsEnabled;
@@ -64,6 +68,10 @@ public class selectionActionDelegate implements ActionMode.Callback,
protected @Nullable Selection mSelection;
protected boolean mRepopulatedMenu;
+ public void setFullScreen(boolean pFullScreen){
+ mFullScreen = pFullScreen;
+ }
+
@TargetApi(Build.VERSION_CODES.M)
private class Callback2Wrapper extends ActionMode.Callback2 {
@Override
@@ -148,7 +156,7 @@ public class selectionActionDelegate implements ActionMode.Callback,
* @return True if the action is presently available.
*/
protected boolean isActionAvailable(final @NonNull String id) {
- if (mSelection == null) {
+ if (mSelection == null || mSelection.text.toString().length()<1) {
return false;
}
@@ -189,6 +197,9 @@ public class selectionActionDelegate implements ActionMode.Callback,
*/
protected void prepareAction(final @NonNull String id, final @NonNull MenuItem item) {
+ if(mFullScreen){
+ return;
+ }
switch (id) {
case ACTION_CUT:
item.setTitle(android.R.string.cut);
diff --git a/app/src/main/java/com/darkweb/genesissearchengine/appManager/homeManager/hintManager/hintAdapter.java b/app/src/main/java/com/darkweb/genesissearchengine/appManager/homeManager/hintManager/hintAdapter.java
index 7b3851cf..ef4856db 100644
--- a/app/src/main/java/com/darkweb/genesissearchengine/appManager/homeManager/hintManager/hintAdapter.java
+++ b/app/src/main/java/com/darkweb/genesissearchengine/appManager/homeManager/hintManager/hintAdapter.java
@@ -28,6 +28,7 @@ import com.example.myapplication.R;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -227,11 +228,14 @@ public class hintAdapter extends RecyclerView.Adapter= Build.VERSION_CODES.M) {
+ id = android.R.id.pasteAsPlainText;
+ } else {
+ onInterceptClipDataToPlainText();
+ }
+ }
+ return super.onTextContextMenuItem(id);
+ }
+
+ private void onInterceptClipDataToPlainText() {
+ ClipboardManager clipboard = (ClipboardManager) getContext().getSystemService(Context.CLIPBOARD_SERVICE);
+ ClipData clip = clipboard.getPrimaryClip();
+ if (clip != null) {
+ for (int i = 0; i < clip.getItemCount(); i++) {
+ final CharSequence paste;
+ // Get an item as text and remove all spans by toString().
+ final CharSequence text = clip.getItemAt(i).coerceToText(getContext());
+ paste = (text instanceof Spanned) ? text.toString() : text;
+ if (paste != null) {
+ copyToClipBoard(getContext(), paste);
+ }
+ }
+ }
+ }
+
+ public void copyToClipBoard(@NonNull Context context, @NonNull CharSequence text) {
+ ClipData clipData = ClipData.newPlainText("rebase_copy", text);
+ ClipboardManager manager = (ClipboardManager) context
+ .getSystemService(Context.CLIPBOARD_SERVICE);
+ manager.setPrimaryClip(clipData);
+ }
+
public editTextManager(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
mContext = context;
diff --git a/app/src/main/java/com/darkweb/genesissearchengine/appManager/homeManager/homeController/homeController.java b/app/src/main/java/com/darkweb/genesissearchengine/appManager/homeManager/homeController/homeController.java
index 250b01d4..ebcf2570 100644
--- a/app/src/main/java/com/darkweb/genesissearchengine/appManager/homeManager/homeController/homeController.java
+++ b/app/src/main/java/com/darkweb/genesissearchengine/appManager/homeManager/homeController/homeController.java
@@ -2,7 +2,6 @@ package com.darkweb.genesissearchengine.appManager.homeManager.homeController;
import android.annotation.SuppressLint;
import android.app.DownloadManager;
-import android.app.Notification;
import android.content.ActivityNotFoundException;
import android.content.BroadcastReceiver;
import android.content.ComponentCallbacks2;
@@ -11,6 +10,7 @@ import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.content.res.Configuration;
+import android.content.res.Resources;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.Color;
@@ -78,10 +78,10 @@ import com.google.android.gms.ads.AdView;
import org.mozilla.geckoview.ContentBlocking;
import org.mozilla.geckoview.GeckoResult;
import org.mozilla.geckoview.GeckoSession;
-import org.torproject.android.proxy.OrbotService;
-import org.torproject.android.proxy.util.Prefs;
-import org.torproject.android.proxy.wrapper.LocaleHelper;
-import org.torproject.android.proxy.wrapper.orbotLocalConstants;
+import org.torproject.android.service.OrbotService;
+import org.torproject.android.service.util.Prefs;
+import org.torproject.android.service.wrapper.LocaleHelper;
+import org.torproject.android.service.wrapper.orbotLocalConstants;
import java.lang.ref.WeakReference;
import java.lang.reflect.Field;
@@ -197,6 +197,9 @@ public class homeController extends AppCompatActivity implements ComponentCallba
dataController.getInstance().invokeSQLCipher(dataEnums.eSqlCipherCommands.M_INIT, Collections.singletonList(this));
trueTime.getInstance().initTime();
+ helperMethod.updateResources(this, status.mSystemLocale.getLanguage());
+ pluginController.getInstance().onLanguageInvoke(Collections.singletonList(this), pluginEnums.eLangManager.M_ACTIVITY_CREATED);
+
super.onCreate(savedInstanceState);
setContentView(R.layout.home_view);
@@ -734,8 +737,6 @@ public class homeController extends AppCompatActivity implements ComponentCallba
super.onDestroy();
return;
}
- mBackSplash.setImageDrawable(null);
- mBackSplash.setBackground(null);
if(!status.mThemeApplying){
if(!status.sSettingIsAppStarted){
@@ -746,32 +747,8 @@ public class homeController extends AppCompatActivity implements ComponentCallba
}
}
- KeyboardUtils.removeAllKeyboardToggleListeners();
- mGatewaySplash.setOnTouchListener(null);
-
- ((ConstraintLayout)mGatewaySplash.getParent()).removeView(mGatewaySplash);
- ((ConstraintLayout)mGeckoView.getParent()).removeView(mGeckoView);
- ((ConstraintLayout)mTabFragment.getParent()).removeView(mTabFragment);
- ((LinearLayout)mSearchbar.getParent()).removeView(mSearchbar);
-
- mTabFragment = null;
- mNestedScroll = null;
- mGeckoView.setOnFocusChangeListener(null);
- mGeckoView.setOnTouchListener(null);
- mGeckoView.destroyDrawingCache();
- mGeckoView.releaseSession();
- mGeckoClient.onDestroy();
-
- mGeckoView.onDestroy();
- mGeckoClient=null;
- mHomeViewController = null;
- activityContextManager.getInstance().setHomeController(null);
- mGeckoView.releaseSession();
- mGeckoView = null;
-
- activityContextManager.getInstance().setHomeController(null);
- activityContextManager.getInstance().setCurrentActivity(null);
- pluginController.getInstance().onRemoveInstances();
+ // mGeckoClient.onDestroy();
+ // mGeckoView.onDestroy();
unregisterReceiver(downloadStatus);
@@ -807,8 +784,8 @@ public class homeController extends AppCompatActivity implements ComponentCallba
@Override
public void onTextChanged(CharSequence s, int start,int before, int count) {
- if(!mSearchbar.isFocused()){
- if(mFindText.getText().length()==0 && mGeckoClient!=null){
+ if(!mSearchbar.isFocused() && !status.mThemeApplying && mGeckoClient.getSession()!=null){
+ if(mFindText.getText().length()==0 && mGeckoClient!=null && mGeckoClient.getSession()!=null){
mGeckoClient.getSession().getFinder().clear();
mHomeViewController.onUpdateFindBarCount(0,0);
}else if(mGeckoClient!=null){
@@ -1394,6 +1371,9 @@ public class homeController extends AppCompatActivity implements ComponentCallba
mHomeViewController.onUpdateFindBar(false);
mHomeViewController.onClearSelections(isKeyboardOpened);
mTopBarContainer.getLayoutTransition().setDuration(0);
+
+ mSearchbar.clearFocus();
+ mHomeViewController.onUpdateSearchBar(mGeckoClient.getSession().getCurrentURL(),false,false, true);
}
@Override
@@ -1583,9 +1563,12 @@ public class homeController extends AppCompatActivity implements ComponentCallba
}
public void onStartApplication(View view){
- pluginController.getInstance().onOrbotInvoke(Arrays.asList(status.sBridgeCustomBridge, status.sBridgeGatewayManual, status.sBridgeCustomType, status.sBridgeStatus, status.sShowImages, status.sClearOnExit, (String)dataController.getInstance().invokeBridges(dataEnums.eBridgeWebsiteCommands.M_FETCH, null)), pluginEnums.eOrbotManager.M_START_ORBOT);
- onInvokeProxyLoading();
mHomeViewController.initHomePage();
+ new Handler().postDelayed(() ->
+ {
+ pluginController.getInstance().onOrbotInvoke(Arrays.asList(status.sBridgeCustomBridge, status.sBridgeGatewayManual, status.sBridgeCustomType, status.sBridgeStatus, status.sShowImages, status.sClearOnExit, (String)dataController.getInstance().invokeBridges(dataEnums.eBridgeWebsiteCommands.M_FETCH, null)), pluginEnums.eOrbotManager.M_START_ORBOT);
+ onInvokeProxyLoading();
+ }, 1000);
}
public void onDownloadFile(){
@@ -1895,7 +1878,7 @@ public class homeController extends AppCompatActivity implements ComponentCallba
dataController.getInstance().invokePrefs(dataEnums.ePreferencesCommands.M_SET_INT, Arrays.asList(keys.SETTING_SHOW_IMAGES,0));
dataController.getInstance().invokePrefs(dataEnums.ePreferencesCommands.M_SET_BOOL, Arrays.asList(keys.SETTING_SHOW_FONTS,true));
dataController.getInstance().invokePrefs(dataEnums.ePreferencesCommands.M_SET_BOOL, Arrays.asList(keys.SETTING_TOOLBAR_THEME,true));
- dataController.getInstance().invokePrefs(dataEnums.ePreferencesCommands.M_SET_BOOL, Arrays.asList(keys.SETTING_FULL_SCREEN_BROWSIING,true));
+ dataController.getInstance().invokePrefs(dataEnums.ePreferencesCommands.M_SET_BOOL, Arrays.asList(keys.SETTING_FULL_SCREEN_BROWSIING,false));
dataController.getInstance().invokePrefs(dataEnums.ePreferencesCommands.M_SET_INT, Arrays.asList(keys.SETTING_THEME, enums.Theme.THEME_DEFAULT));
dataController.getInstance().invokePrefs(dataEnums.ePreferencesCommands.M_SET_BOOL, Arrays.asList(keys.SETTING_LIST_VIEW,true));
dataController.getInstance().invokePrefs(dataEnums.ePreferencesCommands.M_SET_BOOL, Arrays.asList(keys.SETTING_SHOW_TAB_GRID,true));
@@ -1946,9 +1929,6 @@ public class homeController extends AppCompatActivity implements ComponentCallba
mHomeViewController.onClearSelections(isKeyboardOpened);
mSearchbar.clearFocus();
}
- else if(e_type.equals(GECKO_SCROLL_DOWN_MOVE)){
- mAppBar.setExpanded(true,false);
- }
else if(e_type.equals(GECKO_SCROLL_UP_MOVE)){
mAppBar.setExpanded(false,false);
}
@@ -1960,12 +1940,12 @@ public class homeController extends AppCompatActivity implements ComponentCallba
mAppBar.getLocalVisibleRect(rectf);
int height = mAppBar.getHeight();
- Log.i("asddasas","asdasd : " + rectf.top + " : " + height);
- if(rectf.top!=0 && rectf.top + height!=0)
- if(rectf.top<=height/2){
- mHomeViewController.expandTopBar(true, mGeckoView.getMaxY());
- }else {
- mHomeViewController.shrinkTopBar(true, mGeckoView.getMaxY());
+ if(rectf.top>0 && rectf.top + height!=0){
+ if(rectf.top<=height/2){
+ mHomeViewController.expandTopBar(true, mGeckoView.getMaxY());
+ }else {
+ mHomeViewController.shrinkTopBar(true, mGeckoView.getMaxY());
+ }
}
}
}
@@ -2160,10 +2140,27 @@ public class homeController extends AppCompatActivity implements ComponentCallba
if(e_type.equals(enums.etype.fetch_favicon)){
mGeckoClient.onGetFavIcon((ImageView) data.get(0), (String) data.get(1), homeController.this);
}
+ else if(e_type.equals(enums.etype.M_COPY_URL)){
+ mHomeViewController.onUpdateSearchBar((String) data.get(0), true, true, false);
+ }
return null;
}
}
+ public boolean updateResources(Context context, String language) {
+ Locale locale = new Locale(language);
+ Locale.setDefault(locale);
+
+ Resources resources = context.getResources();
+
+ Configuration configuration = resources.getConfiguration();
+ configuration.locale = locale;
+
+ resources.updateConfiguration(configuration, resources.getDisplayMetrics());
+
+ return true;
+ }
+
public void onDisableAdvert(){
mHomeViewController.updateBannerAdvertStatus(false, true);
}
@@ -2198,7 +2195,7 @@ public class homeController extends AppCompatActivity implements ComponentCallba
}catch (Exception ignored){}
new Handler().postDelayed(() ->
{
- if(mTabFragment!=null){
+ if(mTabFragment!=null && mGeckoClient.getSession()!=null){
if(mTabFragment.getVisibility()!=View.VISIBLE){
dataController.getInstance().invokeTab(dataEnums.eTabCommands.M_UPDATE_PIXEL, Arrays.asList(mGeckoClient.getSession().getSessionID(), mRenderedBitmap, null, mGeckoView, true));
}else {
@@ -2367,11 +2364,16 @@ public class homeController extends AppCompatActivity implements ComponentCallba
mHomeViewController.initTopBarPadding();
}
else if(e_type.equals(enums.etype.M_RATE_COUNT)){
- dataController.getInstance().invokePrefs(dataEnums.ePreferencesCommands.M_SET_INT, Arrays.asList(keys.SETTING_RATE_COUNT, status.sRateCount));
+ dataController.getInstance().invokePrefs(dataEnums.ePreferencesCommands.M_SET_INT, Arrays.asList(keys.SETTING_RATE_COUNT, status.sGlobalURLCount));
}
else if(e_type.equals(enums.etype.M_ORBOT_LOADING)){
pluginController.getInstance().onMessageManagerInvoke(Collections.singletonList(homeController.this), M_ORBOT_LOADING);
}
+ else if(e_type.equals(enums.etype.M_DEFAULT_BROWSER)){
+ if(helperMethod.isDefaultBrowserSet(homeController.this)){
+ helperMethod.openDefaultBrowser(homeController.this);
+ }
+ }
else if(e_type.equals(enums.etype.M_NEW_IDENTITY)){
pluginController.getInstance().onOrbotInvoke(null, pluginEnums.eOrbotManager.M_NEW_CIRCUIT);
}
diff --git a/app/src/main/java/com/darkweb/genesissearchengine/appManager/homeManager/homeController/homeViewController.java b/app/src/main/java/com/darkweb/genesissearchengine/appManager/homeManager/homeController/homeViewController.java
index e444155d..6458fbc9 100644
--- a/app/src/main/java/com/darkweb/genesissearchengine/appManager/homeManager/homeController/homeViewController.java
+++ b/app/src/main/java/com/darkweb/genesissearchengine/appManager/homeManager/homeController/homeViewController.java
@@ -47,8 +47,11 @@ import com.darkweb.genesissearchengine.helperManager.helperMethod;
import com.example.myapplication.R;
import com.google.android.gms.ads.AdView;
import com.google.android.material.appbar.AppBarLayout;
+import com.google.android.material.appbar.CollapsingToolbarLayout;
+
import org.mozilla.geckoview.GeckoView;
-import org.torproject.android.proxy.wrapper.orbotLocalConstants;
+import org.torproject.android.service.wrapper.orbotLocalConstants;
+
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
@@ -164,6 +167,8 @@ class homeViewController
recreateStatusBar();
initTopBarPadding();
initializeViews();
+ stopScroll();
+ onFullScreen();
}
@SuppressLint("WrongConstant")
@@ -227,6 +232,7 @@ class homeViewController
View child = mAppBar.getChildAt(0);
AppBarLayout.LayoutParams params = (AppBarLayout.LayoutParams) child.getLayoutParams();
params.setScrollFlags(0);
+ onFullScreen();
return;
}
}
@@ -237,7 +243,7 @@ class homeViewController
View child = mAppBar.getChildAt(0);
AppBarLayout.LayoutParams params = (AppBarLayout.LayoutParams) child.getLayoutParams();
params.setScrollFlags(0);
-
+ onFullScreen();
}else {
int paddingDp = 0;
if(isFullScreen){
@@ -250,6 +256,7 @@ class homeViewController
View child = mAppBar.getChildAt(0);
AppBarLayout.LayoutParams params = (AppBarLayout.LayoutParams) child.getLayoutParams();
params.setScrollFlags(1);
+ onFullScreen();
}
}
@@ -496,11 +503,13 @@ class homeViewController
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
ColorAnimator oneToTwo = new ColorAnimator(ContextCompat.getColor(mContext, R.color.landing_ease_blue), ContextCompat.getColor(mContext, R.color.green_dark_v2));
- int mDelay = 500;
+ int mDelay = 1250;
if(status.mThemeApplying || mInstant){
mDelay = 0;
}
+ Log.i("asdadsshadkkasjd","asdasdasd");
+
ValueAnimator animator = ObjectAnimator.ofFloat(0f, 1f);
animator.setDuration(250).setStartDelay(mDelay);
animator.addUpdateListener(animation ->
@@ -531,16 +540,17 @@ class homeViewController
});
animator.start();
}else {
- mContext.getWindow().setStatusBarColor(ContextCompat.getColor(mContext, R.color.c_background));
+ mSplashScreen.animate().alpha(0).setDuration(250).setStartDelay(0);
}
}
public void initSplashLoading(){
- mLoadingText.setAlpha(0);
- mLoadingText.setVisibility(View.VISIBLE);
- mLoadingText.animate().setStartDelay(0).alpha(1);
+ if(mLoadingText.getAlpha()==0){
+ Log.i("sadads111","asdasdasd");
+ mLoadingText.animate().setStartDelay(0).setDuration(250).alpha(1);
+ }
mProgressBarIndeterminate.setVisibility(View.VISIBLE);
mProgressBarIndeterminate.animate().alpha(1);
@@ -615,7 +625,7 @@ class homeViewController
}
}
- sleep(1500);
+ sleep(500);
if(mFastConnect){
continue;
}
@@ -632,13 +642,13 @@ class homeViewController
}
}
if(!status.sSettingIsAppStarted){
- startPostTask(messages.MESSAGE_ON_URL_LOAD);
mContext.runOnUiThread(() -> {
splashScreenDisable();
});
+ startPostTask(messages.MESSAGE_ON_URL_LOAD);
}else {
mContext.runOnUiThread(() -> {
- mEvent.invokeObserver(null, enums.etype.ON_LOAD_TAB_ON_RESUME);
+ mEvent.invokeObserver(null, enums.etype.ON_LOAD_TAB_ON_RESUME);
});
}
}
@@ -655,6 +665,9 @@ class homeViewController
splashScreenDisable();
}
+ public void stopScroll() {
+ }
+
public void splashScreenDisableInstant() {
mSplashScreen.setAlpha(0f);
mSplashScreen.setVisibility(View.GONE);
@@ -669,18 +682,11 @@ class homeViewController
if(mSplashScreen.getAlpha()==1){
if(!mIsAnimating){
mIsAnimating = true;
- triggerPostUI(2000);
- mProgressBar.setVisibility(View.GONE);
- mSplashScreen.animate().cancel();
- onClearSelections(false);
- mGeckoView.requestFocus();
- mProgressBarIndeterminate.animate().cancel();
+ initStatusBarColor(false);
mProgressBarIndeterminate.animate().setStartDelay(350).setDuration(250).alpha(0).withEndAction(() -> {
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
- initStatusBarColor(false);
- }
- mSplashScreen.animate().setDuration(0).setStartDelay(1000).alpha(0).withEndAction(() -> {
+ new Handler().postDelayed(() ->
+ {
mProgressBarIndeterminate.setVisibility(View.GONE);
mSplashScreen.setClickable(false);
mSplashScreen.setFocusable(false);
@@ -695,7 +701,8 @@ class homeViewController
mEvent.invokeObserver(null, enums.etype.M_CACHE_UPDATE_TAB);
mEvent.invokeObserver(null, enums.etype.M_SPLASH_DISABLE);
- });
+ }, 2000);
+
});
mEvent.invokeObserver(null, enums.etype.M_WELCOME_MESSAGE);
mOrbotLogManager.setClickable(false);
@@ -1446,7 +1453,7 @@ class homeViewController
params.setMargins(0, 0, 0,0);
mNestedScroll.setLayoutParams(params);
- com.darkweb.genesissearchengine.constants.status.sFullScreenBrowsing = (boolean) dataController.getInstance().invokePrefs(dataEnums.ePreferencesCommands.M_GET_BOOL, Arrays.asList(keys.SETTING_FULL_SCREEN_BROWSIING,true));
+ com.darkweb.genesissearchengine.constants.status.sFullScreenBrowsing = (boolean) dataController.getInstance().invokePrefs(dataEnums.ePreferencesCommands.M_GET_BOOL, Arrays.asList(keys.SETTING_FULL_SCREEN_BROWSIING,false));
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if(status.sTheme == enums.Theme.THEME_DARK || status.sDefaultNightMode){
@@ -1470,6 +1477,15 @@ class homeViewController
}
+ public void onFullScreen(){
+ if(status.sFullScreenBrowsing || isFullScreen){
+ mWebviewContainer.setPadding(0,0,0,0);
+ }
+ else {
+ mWebviewContainer.setPadding(0,0,0,helperMethod.pxFromDp(60));
+ }
+ }
+
void onReDraw(){
if(mWebviewContainer.getPaddingBottom()==0){
mWebviewContainer.setPadding(0,0,0,1);
diff --git a/app/src/main/java/com/darkweb/genesissearchengine/appManager/kotlinHelperLibraries/defaultBrowser.kt b/app/src/main/java/com/darkweb/genesissearchengine/appManager/kotlinHelperLibraries/defaultBrowser.kt
new file mode 100644
index 00000000..dff3f491
--- /dev/null
+++ b/app/src/main/java/com/darkweb/genesissearchengine/appManager/kotlinHelperLibraries/defaultBrowser.kt
@@ -0,0 +1,105 @@
+package com.darkweb.genesissearchengine.appManager.kotlinHelperLibraries
+
+import android.app.Activity
+import android.view.View
+import android.view.WindowManager
+import android.app.role.RoleManager
+import android.content.Intent
+import android.os.Build
+import android.provider.Settings
+import androidx.annotation.DrawableRes
+import androidx.appcompat.app.AppCompatActivity
+import androidx.core.os.bundleOf
+
+class defaultBrowser {
+ fun Activity.enterToImmersiveMode() {
+ window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
+ @Suppress("DEPRECATION")
+ window.decorView.systemUiVisibility = (View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
+ or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
+ or View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
+ or View.SYSTEM_UI_FLAG_FULLSCREEN
+ or View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY)
+ }
+
+ fun Activity.getabcEnabledValue(): Boolean {
+ when {
+ Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q -> {
+ getSystemService(RoleManager::class.java).also {
+ if (it.isRoleAvailable(RoleManager.ROLE_BROWSER) && !it.isRoleHeld(
+ RoleManager.ROLE_BROWSER
+ )
+ ) {
+ return true;
+ }
+ }
+ }
+ Build.VERSION.SDK_INT >= Build.VERSION_CODES.N -> {
+ navigateToDefaultBrowserAppsSettings()
+ }
+ else -> {
+ }
+ }
+ return false;
+ }
+
+ fun Activity.openSetDefaultBrowserOption() {
+ when {
+ Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q -> {
+ getSystemService(RoleManager::class.java).also {
+ if (it.isRoleAvailable(RoleManager.ROLE_BROWSER) && !it.isRoleHeld(
+ RoleManager.ROLE_BROWSER
+ )
+ ) {
+ startActivityForResult(
+ it.createRequestRoleIntent(RoleManager.ROLE_BROWSER),
+ REQUEST_CODE_BROWSER_ROLE
+ )
+ } else {
+ navigateToDefaultBrowserAppsSettings()
+ }
+ }
+ }
+ Build.VERSION.SDK_INT >= Build.VERSION_CODES.N -> {
+ navigateToDefaultBrowserAppsSettings()
+ }
+ else -> {
+ }
+ }
+ }
+
+ private fun Activity.navigateToDefaultBrowserAppsSettings() {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
+ val intent = Intent(Settings.ACTION_MANAGE_DEFAULT_APPS_SETTINGS)
+ intent.putExtra(
+ SETTINGS_SELECT_OPTION_KEY,
+ DEFAULT_BROWSER_APP_OPTION
+ )
+ intent.putExtra(
+ SETTINGS_SHOW_FRAGMENT_ARGS,
+ bundleOf(SETTINGS_SELECT_OPTION_KEY to DEFAULT_BROWSER_APP_OPTION)
+ )
+ startActivity(intent)
+ }
+ }
+
+ /**
+ * Sets the icon for the back (up) navigation button.
+ * @param icon The resource id of the icon.
+ */
+ fun Activity.setNavigationIcon(
+ @DrawableRes icon: Int
+ ) {
+ (this as? AppCompatActivity)?.supportActionBar?.let {
+ it.setDisplayHomeAsUpEnabled(true)
+ it.setHomeAsUpIndicator(icon)
+ it.setHomeActionContentDescription("Set Default Browser")
+ }
+ }
+
+
+}
+const val REQUEST_CODE_BROWSER_ROLE = 1
+const val SETTINGS_SELECT_OPTION_KEY = ":settings:fragment_args_key"
+const val SETTINGS_SHOW_FRAGMENT_ARGS = ":settings:show_fragment_args"
+const val DEFAULT_BROWSER_APP_OPTION = "default_browser"
diff --git a/app/src/main/java/com/darkweb/genesissearchengine/appManager/languageManager/languageController.java b/app/src/main/java/com/darkweb/genesissearchengine/appManager/languageManager/languageController.java
index 8f5b16bc..14b82ad5 100644
--- a/app/src/main/java/com/darkweb/genesissearchengine/appManager/languageManager/languageController.java
+++ b/app/src/main/java/com/darkweb/genesissearchengine/appManager/languageManager/languageController.java
@@ -1,5 +1,6 @@
package com.darkweb.genesissearchengine.appManager.languageManager;
+import android.content.Intent;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.os.Bundle;
@@ -44,6 +45,8 @@ public class languageController extends AppCompatActivity {
private languageViewController mLanguageViewController;
private languageModel mLanguageModel;
private ImageView mBlocker;
+ private boolean mThemeApplied = false;
+ private Locale mLanguagePrevious = status.mSystemLocale;
private RecyclerView mRecycleView;
private languageAdapter mLanguageAdapter;
@@ -113,6 +116,7 @@ public class languageController extends AppCompatActivity {
mRecycleView.scrollToPosition(mPosition);
}else {
int mPositionOffset = getIntent().getExtras().getInt("activity_restarted");
+ mThemeApplied = true;
Objects.requireNonNull(mRecycleView.getLayoutManager()).scrollToPosition(mPositionOffset);
}
}
@@ -149,12 +153,6 @@ public class languageController extends AppCompatActivity {
}
dataController.getInstance().invokePrefs(dataEnums.ePreferencesCommands.M_SET_STRING, Arrays.asList(keys.SETTING_LANGUAGE,status.sSettingLanguage));
dataController.getInstance().invokePrefs(dataEnums.ePreferencesCommands.M_SET_STRING, Arrays.asList(keys.SETTING_LANGUAGE_REGION,status.sSettingLanguageRegion));
- finish();
-
- getIntent().putExtra("activity_restarted",((LinearLayoutManager) Objects.requireNonNull(mRecycleView.getLayoutManager())).findFirstCompletelyVisibleItemPosition());
- helperMethod.restartActivity(getIntent(), this);
- overridePendingTransition(R.anim.fade_in_lang, R.anim.fade_out_lang);
- pluginController.getInstance().onLanguageInvoke(Arrays.asList(this, status.sSettingLanguage, status.sSettingLanguageRegion, status.mThemeApplying), pluginEnums.eLangManager.M_SET_LANGUAGE);
if(activityContextManager.getInstance().getSettingController()!=null && !activityContextManager.getInstance().getSettingController().isDestroyed()){
activityContextManager.getInstance().getSettingController().onRedrawXML();
@@ -168,10 +166,14 @@ public class languageController extends AppCompatActivity {
}
status.mThemeApplying = true;
- activityContextManager.getInstance().getHomeController().recreate();
- if(activityContextManager.getInstance().getSettingGeneralController()!=null){
- activityContextManager.getInstance().getSettingGeneralController().recreate();
- }
+ mThemeApplied = true;
+
+ Intent intent = new Intent(this, languageController.class);
+ intent.putExtra("activity_restarted",((LinearLayoutManager) Objects.requireNonNull(mRecycleView.getLayoutManager())).findFirstCompletelyVisibleItemPosition());
+ this.startActivity(intent);
+
+ overridePendingTransition(R.anim.fade_in_lang, R.anim.fade_out_lang);
+ this.finish();
return true;
}
@@ -226,6 +228,22 @@ public class languageController extends AppCompatActivity {
super.onResume();
}
+ @Override
+ protected void onPause() {
+ if(mThemeApplied && !status.mThemeApplying){
+ helperMethod.updateResources(activityContextManager.getInstance().getHomeController(), status.mSystemLocale.getLanguage());
+ activityContextManager.getInstance().onResetTheme();
+
+ String mSystemLangugage = status.mSystemLocale.toString();
+ if(mSystemLangugage.equals("ur_PK") || mSystemLangugage.equals("ur_UR") || mLanguagePrevious.toString().equals("ur_PK") || mLanguagePrevious.toString().equals("ur_UR")){
+ activityContextManager.getInstance().getHomeController().recreate();
+ }
+ mLanguagePrevious = status.mSystemLocale;
+ }
+ status.mThemeApplying = false;
+ super.onPause();
+ }
+
@Override
public void onBackPressed() {
onClose(null);
diff --git a/app/src/main/java/com/darkweb/genesissearchengine/appManager/orbotLogManager/orbotLogAdapter.java b/app/src/main/java/com/darkweb/genesissearchengine/appManager/orbotLogManager/orbotLogAdapter.java
index 818b31aa..ef376154 100644
--- a/app/src/main/java/com/darkweb/genesissearchengine/appManager/orbotLogManager/orbotLogAdapter.java
+++ b/app/src/main/java/com/darkweb/genesissearchengine/appManager/orbotLogManager/orbotLogAdapter.java
@@ -15,7 +15,9 @@ import com.darkweb.genesissearchengine.appManager.tabManager.tabEnums;
import com.darkweb.genesissearchengine.constants.constants;
import com.darkweb.genesissearchengine.eventObserver;
import com.example.myapplication.R;
-import org.torproject.android.proxy.wrapper.logRowModel;
+
+import org.torproject.android.service.wrapper.logRowModel;
+
import java.util.ArrayList;
import java.util.List;
diff --git a/app/src/main/java/com/darkweb/genesissearchengine/appManager/orbotLogManager/orbotLogController.java b/app/src/main/java/com/darkweb/genesissearchengine/appManager/orbotLogManager/orbotLogController.java
index 8344aa80..7f6676ca 100644
--- a/app/src/main/java/com/darkweb/genesissearchengine/appManager/orbotLogManager/orbotLogController.java
+++ b/app/src/main/java/com/darkweb/genesissearchengine/appManager/orbotLogManager/orbotLogController.java
@@ -28,8 +28,9 @@ import com.darkweb.genesissearchengine.pluginManager.pluginEnums;
import com.example.myapplication.R;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
-import org.torproject.android.proxy.wrapper.logRowModel;
-import org.torproject.android.proxy.wrapper.orbotLocalConstants;
+
+import org.torproject.android.service.wrapper.logRowModel;
+import org.torproject.android.service.wrapper.orbotLocalConstants;
import java.util.ArrayList;
import java.util.Collections;
diff --git a/app/src/main/java/com/darkweb/genesissearchengine/appManager/orbotLogManager/orbotLogModel.java b/app/src/main/java/com/darkweb/genesissearchengine/appManager/orbotLogManager/orbotLogModel.java
index 277795c6..1be3fa6d 100644
--- a/app/src/main/java/com/darkweb/genesissearchengine/appManager/orbotLogManager/orbotLogModel.java
+++ b/app/src/main/java/com/darkweb/genesissearchengine/appManager/orbotLogManager/orbotLogModel.java
@@ -2,7 +2,8 @@ package com.darkweb.genesissearchengine.appManager.orbotLogManager;
import com.darkweb.genesissearchengine.constants.constants;
import com.darkweb.genesissearchengine.helperManager.helperMethod;
-import org.torproject.android.proxy.wrapper.logRowModel;
+import org.torproject.android.service.wrapper.logRowModel;
+
import java.util.ArrayList;
import java.util.List;
diff --git a/app/src/main/java/com/darkweb/genesissearchengine/appManager/settingManager/clearManager/settingClearController.java b/app/src/main/java/com/darkweb/genesissearchengine/appManager/settingManager/clearManager/settingClearController.java
index ed2627e6..a346e8b0 100644
--- a/app/src/main/java/com/darkweb/genesissearchengine/appManager/settingManager/clearManager/settingClearController.java
+++ b/app/src/main/java/com/darkweb/genesissearchengine/appManager/settingManager/clearManager/settingClearController.java
@@ -209,7 +209,7 @@ public class settingClearController extends AppCompatActivity {
dataController.getInstance().invokePrefs(dataEnums.ePreferencesCommands.M_SET_INT, Arrays.asList(keys.SETTING_SHOW_IMAGES,0));
dataController.getInstance().invokePrefs(dataEnums.ePreferencesCommands.M_SET_BOOL, Arrays.asList(keys.SETTING_SHOW_FONTS,true));
dataController.getInstance().invokePrefs(dataEnums.ePreferencesCommands.M_SET_BOOL, Arrays.asList(keys.SETTING_TOOLBAR_THEME,true));
- dataController.getInstance().invokePrefs(dataEnums.ePreferencesCommands.M_SET_BOOL, Arrays.asList(keys.SETTING_FULL_SCREEN_BROWSIING,true));
+ dataController.getInstance().invokePrefs(dataEnums.ePreferencesCommands.M_SET_BOOL, Arrays.asList(keys.SETTING_FULL_SCREEN_BROWSIING,false));
dataController.getInstance().invokePrefs(dataEnums.ePreferencesCommands.M_SET_INT, Arrays.asList(keys.SETTING_THEME, enums.Theme.THEME_DEFAULT));
dataController.getInstance().invokePrefs(dataEnums.ePreferencesCommands.M_SET_BOOL, Arrays.asList(keys.SETTING_LIST_VIEW,true));
dataController.getInstance().invokePrefs(dataEnums.ePreferencesCommands.M_SET_BOOL, Arrays.asList(keys.SETTING_SHOW_TAB_GRID,true));
diff --git a/app/src/main/java/com/darkweb/genesissearchengine/appManager/settingManager/generalManager/settingGeneralController.java b/app/src/main/java/com/darkweb/genesissearchengine/appManager/settingManager/generalManager/settingGeneralController.java
index efb5a7ae..71242d32 100644
--- a/app/src/main/java/com/darkweb/genesissearchengine/appManager/settingManager/generalManager/settingGeneralController.java
+++ b/app/src/main/java/com/darkweb/genesissearchengine/appManager/settingManager/generalManager/settingGeneralController.java
@@ -1,6 +1,8 @@
package com.darkweb.genesissearchengine.appManager.settingManager.generalManager;
+import android.content.Context;
import android.content.res.Configuration;
+import android.content.res.Resources;
import android.os.Bundle;
import android.view.View;
import android.widget.RadioButton;
@@ -27,6 +29,7 @@ import com.google.android.material.switchmaterial.SwitchMaterial;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
+import java.util.Locale;
public class settingGeneralController extends AppCompatActivity {
@@ -70,6 +73,7 @@ public class settingGeneralController extends AppCompatActivity {
}
}
+ helperMethod.updateResources(this, status.mSystemLocale.getDisplayName());
}
private void viewsInitializations() {
diff --git a/app/src/main/java/com/darkweb/genesissearchengine/appManager/settingManager/settingHomeManager/settingHomeController.java b/app/src/main/java/com/darkweb/genesissearchengine/appManager/settingManager/settingHomeManager/settingHomeController.java
index 2600661f..2233ff19 100644
--- a/app/src/main/java/com/darkweb/genesissearchengine/appManager/settingManager/settingHomeManager/settingHomeController.java
+++ b/app/src/main/java/com/darkweb/genesissearchengine/appManager/settingManager/settingHomeManager/settingHomeController.java
@@ -1,7 +1,12 @@
package com.darkweb.genesissearchengine.appManager.settingManager.settingHomeManager;
+import android.content.Context;
import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
import android.content.res.Configuration;
+import android.content.res.Resources;
+import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.view.View;
@@ -11,6 +16,8 @@ import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import com.darkweb.genesissearchengine.appManager.activityContextManager;
import com.darkweb.genesissearchengine.appManager.helpManager.helpController;
+import com.darkweb.genesissearchengine.appManager.kotlinHelperLibraries.BrowserIconManager;
+import com.darkweb.genesissearchengine.appManager.kotlinHelperLibraries.defaultBrowser;
import com.darkweb.genesissearchengine.appManager.proxyStatusManager.proxyStatusController;
import com.darkweb.genesissearchengine.appManager.settingManager.accessibilityManager.settingAccessibilityController;
import com.darkweb.genesissearchengine.appManager.settingManager.advanceManager.settingAdvanceController;
@@ -37,6 +44,8 @@ import java.net.URLEncoder;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
+import java.util.Locale;
+
import static com.darkweb.genesissearchengine.pluginManager.pluginEnums.eMessageManager.*;
public class settingHomeController extends AppCompatActivity
@@ -73,6 +82,8 @@ public class settingHomeController extends AppCompatActivity
activityContextManager.getInstance().onResetTheme();
}
+ helperMethod.updateResources(this, status.mSystemLocale.getDisplayName());
+ activityContextManager.getInstance().getHomeController().updateResources(this, status.mSystemLocale.getDisplayName());
super.onConfigurationChanged(newConfig);
}
@@ -176,9 +187,9 @@ public class settingHomeController extends AppCompatActivity
public void onDefaultBrowser(View view){
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
- startActivity(new Intent(android.provider.Settings.ACTION_MANAGE_DEFAULT_APPS_SETTINGS));
+ helperMethod.openDefaultBrowser(this);
}else{
- //pluginController.getInstance().onMessageManagerInvoke(Collections.singletonList(this), M_NOT_SUPPORTED);
+ pluginController.getInstance().onMessageManagerInvoke(Collections.singletonList(this), M_NOT_SUPPORTED);
}
}
diff --git a/app/src/main/java/com/darkweb/genesissearchengine/constants/enums.java b/app/src/main/java/com/darkweb/genesissearchengine/constants/enums.java
index 88a5e6f9..40dbea9d 100755
--- a/app/src/main/java/com/darkweb/genesissearchengine/constants/enums.java
+++ b/app/src/main/java/com/darkweb/genesissearchengine/constants/enums.java
@@ -4,10 +4,10 @@ public class enums
{
/*Settings Manager*/
public enum etype{
- M_CHANGE_HOME_THEME, on_update_favicon,M_RELOAD,ON_UPDATE_TAB_TITLE, ON_OPEN_TAB_VIEW,ON_NEW_TAB_ANIMATION, M_UPDATE_SESSION_STATE,ON_LOAD_REQUEST, GECKO_SCROLL_UP, GECKO_SCROLL_UP_ALWAYS, GECKO_SCROLL_DOWN, WAS_SCROLL_CHANGED, GECKO_SCROLL_DOWN_MOVE, GECKO_SCROLL_UP_MOVE, GECKO_SCROLL_DOWN_CALLER,ON_UPDATE_SEARCH_BAR,M_ON_MAIL,SESSION_ID,M_UPDATE_PIXEL_BACKGROUND, M_ON_SCROLL_BOUNDARIES, M_ON_SCROLL_TOP_BOUNDARIES, M_ON_SCROLL_NO_BOUNDARIES, M_INIT_PADDING, M_RATE_COUNT,M_CACHE_UPDATE_TAB,
+ M_CHANGE_HOME_THEME, on_update_favicon,M_RELOAD,ON_UPDATE_TAB_TITLE, ON_OPEN_TAB_VIEW,ON_NEW_TAB_ANIMATION, M_UPDATE_SESSION_STATE,ON_LOAD_REQUEST, GECKO_SCROLL_UP, GECKO_SCROLL_UP_ALWAYS, GECKO_SCROLL_DOWN, WAS_SCROLL_CHANGED, GECKO_SCROLL_DOWN_MOVE, GECKO_SCROLL_UP_MOVE, GECKO_SCROLL_DOWN_CALLER,ON_UPDATE_SEARCH_BAR,M_ON_MAIL,SESSION_ID,M_UPDATE_PIXEL_BACKGROUND, M_ON_SCROLL_BOUNDARIES, M_ON_SCROLL_TOP_BOUNDARIES, M_ON_SCROLL_NO_BOUNDARIES, M_INIT_PADDING, M_RATE_COUNT,M_CACHE_UPDATE_TAB,M_DEFAULT_BROWSER,
on_verify_selected_url_menu,FINDER_RESULT_CALLBACK,M_ADMOB_BANNER_RECHECK,M_OPEN_SESSION,M_DOWNLOAD_FAILURE,
welcome, reload,download_folder, M_UPDATE_THEME,M_ON_BANNER_UPDATE, M_LOAD_HOMEPAGE_GENESIS,M_INIT_TAB_COUNT_FORCED,M_SPLASH_DISABLE,M_NEW_LINK_IN_NEW_TAB,M_RESET_SUGGESTION,
- url_triggered, url_triggered_new_tab,url_clear,fetch_favicon,url_clear_at,remove_from_database,is_empty,M_HOME_PAGE,M_PRELOAD_URL,ON_KEYBOARD_CLOSE,M_CLOSE_TAB,
+ url_triggered, url_triggered_new_tab,url_clear,fetch_favicon, M_COPY_URL,url_clear_at,remove_from_database,is_empty,M_HOME_PAGE,M_PRELOAD_URL,ON_KEYBOARD_CLOSE,M_CLOSE_TAB,
on_close_sesson,on_long_press, on_full_screen,on_handle_external_intent,on_update_suggestion_url,progress_update,progress_update_forced, ON_EXPAND_TOP_BAR,recheck_orbot,on_url_load,on_playstore_load,back_list_empty,start_proxy, ON_UPDATE_THEME, M_NEW_IDENTITY, M_NEW_IDENTITY_MESSAGED, M_INITIALIZE_TAB_SINGLE, M_INITIALIZE_TAB_LINK,on_request_completed, on_update_history,on_update_suggestion,M_WELCOME_MESSAGE,ON_FIRST_PAINT, ON_LOAD_TAB_ON_RESUME, ON_SESSION_REINIT,on_page_loaded,on_load_error, M_ORBOT_LOADING,download_file_popup,on_init_ads, M_GET_CURRENT_URL,search_update, open_new_tab,open_new_tab_instant
}
diff --git a/app/src/main/java/com/darkweb/genesissearchengine/constants/status.java b/app/src/main/java/com/darkweb/genesissearchengine/constants/status.java
index 101f8598..7eb15b78 100755
--- a/app/src/main/java/com/darkweb/genesissearchengine/constants/status.java
+++ b/app/src/main/java/com/darkweb/genesissearchengine/constants/status.java
@@ -74,7 +74,7 @@ public class status
public static int sWidgetResponse = enums.WidgetResponse.NONE;
public static int sBridgeNotificationManual = 0;
public static int sSettingTrackingProtection = 0;
- public static int sRateCount = 0;
+ public static int sGlobalURLCount = 0;
public static float sSettingFontSize = 1;
@@ -126,13 +126,13 @@ public class status
status.sCharacterEncoding = (boolean)dataController.getInstance().invokePrefs(dataEnums.ePreferencesCommands.M_GET_BOOL, Arrays.asList(keys.SETTING_CHARACTER_ENCODING,false));
status.sShowImages = (int)dataController.getInstance().invokePrefs(dataEnums.ePreferencesCommands.M_GET_INT, Arrays.asList(keys.SETTING_SHOW_IMAGES,0));
status.sShowWebFonts = (boolean)dataController.getInstance().invokePrefs(dataEnums.ePreferencesCommands.M_GET_BOOL, Arrays.asList(keys.SETTING_SHOW_FONTS,true));
- status.sFullScreenBrowsing = (boolean)dataController.getInstance().invokePrefs(dataEnums.ePreferencesCommands.M_GET_BOOL, Arrays.asList(keys.SETTING_FULL_SCREEN_BROWSIING,true));
+ status.sFullScreenBrowsing = (boolean)dataController.getInstance().invokePrefs(dataEnums.ePreferencesCommands.M_GET_BOOL, Arrays.asList(keys.SETTING_FULL_SCREEN_BROWSIING,false));
status.sToolbarTheme = (boolean)dataController.getInstance().invokePrefs(dataEnums.ePreferencesCommands.M_GET_BOOL, Arrays.asList(keys.SETTING_TOOLBAR_THEME,true));
status.sTheme = (int)dataController.getInstance().invokePrefs(dataEnums.ePreferencesCommands.M_GET_INT, Arrays.asList(keys.SETTING_THEME,enums.Theme.THEME_DEFAULT));
status.sOpenURLInNewTab = (boolean)dataController.getInstance().invokePrefs(dataEnums.ePreferencesCommands.M_GET_BOOL, Arrays.asList(keys.SETTING_OPEN_URL_IN_NEW_TAB,true));
status.sLogThemeStyleAdvanced = (boolean)dataController.getInstance().invokePrefs(dataEnums.ePreferencesCommands.M_GET_BOOL, Arrays.asList(keys.SETTING_LIST_VIEW,true));
status.sTabGridLayoutEnabled = (boolean)dataController.getInstance().invokePrefs(dataEnums.ePreferencesCommands.M_GET_BOOL, Arrays.asList(keys.SETTING_SHOW_TAB_GRID,true));
- status.sRateCount = (int)dataController.getInstance().invokePrefs(dataEnums.ePreferencesCommands.M_GET_INT, Arrays.asList(keys.SETTING_RATE_COUNT, 0));
+ status.sGlobalURLCount = (int)dataController.getInstance().invokePrefs(dataEnums.ePreferencesCommands.M_GET_INT, Arrays.asList(keys.SETTING_RATE_COUNT, 0));
status.sAppInstalled = (boolean)dataController.getInstance().invokePrefs(dataEnums.ePreferencesCommands.M_GET_BOOL, Arrays.asList(keys.SETTING_INSTALLED,false));
}
diff --git a/app/src/main/java/com/darkweb/genesissearchengine/dataManager/dataController.java b/app/src/main/java/com/darkweb/genesissearchengine/dataManager/dataController.java
index 7822b822..e09d20fd 100755
--- a/app/src/main/java/com/darkweb/genesissearchengine/dataManager/dataController.java
+++ b/app/src/main/java/com/darkweb/genesissearchengine/dataManager/dataController.java
@@ -229,7 +229,7 @@ public class dataController
dataController.getInstance().invokePrefs(dataEnums.ePreferencesCommands.M_SET_INT, Arrays.asList(keys.SETTING_SHOW_IMAGES,0));
dataController.getInstance().invokePrefs(dataEnums.ePreferencesCommands.M_SET_BOOL, Arrays.asList(keys.SETTING_SHOW_FONTS,true));
dataController.getInstance().invokePrefs(dataEnums.ePreferencesCommands.M_SET_BOOL, Arrays.asList(keys.SETTING_TOOLBAR_THEME,true));
- dataController.getInstance().invokePrefs(dataEnums.ePreferencesCommands.M_SET_BOOL, Arrays.asList(keys.SETTING_FULL_SCREEN_BROWSIING,true));
+ dataController.getInstance().invokePrefs(dataEnums.ePreferencesCommands.M_SET_BOOL, Arrays.asList(keys.SETTING_FULL_SCREEN_BROWSIING,false));
dataController.getInstance().invokePrefs(dataEnums.ePreferencesCommands.M_SET_INT, Arrays.asList(keys.SETTING_THEME, enums.Theme.THEME_DEFAULT));
dataController.getInstance().invokePrefs(dataEnums.ePreferencesCommands.M_SET_BOOL, Arrays.asList(keys.SETTING_LIST_VIEW,true));
dataController.getInstance().invokePrefs(dataEnums.ePreferencesCommands.M_SET_BOOL, Arrays.asList(keys.SETTING_SHOW_TAB_GRID,true));
diff --git a/app/src/main/java/com/darkweb/genesissearchengine/dataManager/tabDataModel.java b/app/src/main/java/com/darkweb/genesissearchengine/dataManager/tabDataModel.java
index 78f50018..83eb06ae 100644
--- a/app/src/main/java/com/darkweb/genesissearchengine/dataManager/tabDataModel.java
+++ b/app/src/main/java/com/darkweb/genesissearchengine/dataManager/tabDataModel.java
@@ -158,8 +158,10 @@ class tabDataModel
try{
if(mTabs.get(counter).getSession().getSessionID().equals(mSessionID))
{
+ String[] params = new String[1];
+ params[0] = mSessionState;
- mExternalEvents.invokeObserver(Arrays.asList("UPDATE tab SET session = '" + mSessionState + "' WHERE mid='"+mTabs.get(counter).getmId() + "'",null), dataEnums.eTabCallbackCommands.M_EXEC_SQL);
+ mExternalEvents.invokeObserver(Arrays.asList("UPDATE tab SET session = ? WHERE mid='"+mTabs.get(counter).getmId() + "'",params), dataEnums.eTabCallbackCommands.M_EXEC_SQL);
mTabs.add(0,mTabs.remove(counter));
break;
}
diff --git a/app/src/main/java/com/darkweb/genesissearchengine/helperManager/helperMethod.java b/app/src/main/java/com/darkweb/genesissearchengine/helperManager/helperMethod.java
index a971c952..59517294 100755
--- a/app/src/main/java/com/darkweb/genesissearchengine/helperManager/helperMethod.java
+++ b/app/src/main/java/com/darkweb/genesissearchengine/helperManager/helperMethod.java
@@ -13,6 +13,7 @@ import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
+import android.content.res.Configuration;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.Canvas;
@@ -50,6 +51,8 @@ import androidx.core.app.ShareCompat;
import androidx.core.content.ContextCompat;
import androidx.core.content.FileProvider;
import androidx.core.graphics.ColorUtils;
+
+import com.darkweb.genesissearchengine.appManager.kotlinHelperLibraries.defaultBrowser;
import com.darkweb.genesissearchengine.constants.enums;
import com.darkweb.genesissearchengine.constants.keys;
import com.example.myapplication.R;
@@ -589,6 +592,25 @@ public class helperMethod
return size;
}
+ public static void openDefaultBrowser(AppCompatActivity mContext){
+ defaultBrowser mIconManager = new defaultBrowser();
+ mIconManager.openSetDefaultBrowserOption(mContext);
+ }
+
+ public static boolean isDefaultBrowserSet(AppCompatActivity mContext){
+ defaultBrowser mIconManager = new defaultBrowser();
+ return mIconManager.getabcEnabledValue(mContext);
+ }
+
+ public static void updateResources(Context context, String language) {
+ Locale locale = new Locale(language);
+ Locale.setDefault(locale);
+ Resources resources = context.getResources();
+ Configuration configuration = resources.getConfiguration();
+ configuration.locale = locale;
+ resources.updateConfiguration(configuration, resources.getDisplayMetrics());
+ }
+
public static void openActivity( Class> cls,int type,AppCompatActivity context,boolean animation){
Intent myIntent = new Intent(context, cls);
myIntent.putExtra(keys.PROXY_LIST_TYPE, type);
diff --git a/app/src/main/java/com/darkweb/genesissearchengine/libs/clientauth/ClientAuthContentProvider.java b/app/src/main/java/com/darkweb/genesissearchengine/libs/providers/ClientAuthContentProviderGenesis.java
similarity index 93%
rename from app/src/main/java/com/darkweb/genesissearchengine/libs/clientauth/ClientAuthContentProvider.java
rename to app/src/main/java/com/darkweb/genesissearchengine/libs/providers/ClientAuthContentProviderGenesis.java
index a5b8fb76..4612a226 100644
--- a/app/src/main/java/com/darkweb/genesissearchengine/libs/clientauth/ClientAuthContentProvider.java
+++ b/app/src/main/java/com/darkweb/genesissearchengine/libs/providers/ClientAuthContentProviderGenesis.java
@@ -1,4 +1,4 @@
-package com.darkweb.genesissearchengine.libs.clientauth;
+package com.darkweb.genesissearchengine.libs.providers;
import android.content.ContentProvider;
import android.content.ContentUris;
@@ -12,14 +12,14 @@ import android.provider.BaseColumns;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
-public class ClientAuthContentProvider extends ContentProvider {
+public class ClientAuthContentProviderGenesis extends ContentProvider {
public static final String[] PROJECTION = {
V3ClientAuth._ID,
V3ClientAuth.DOMAIN,
V3ClientAuth.HASH,
V3ClientAuth.ENABLED,
};
- private static final String AUTH = "com.darkweb.genesissearchengine.libs.clientauth.ClientAuthContentProvider";
+ private static final String AUTH = "org.torproject.android.ui.v3onionservice.clientauth";
public static final Uri CONTENT_URI = Uri.parse("content://" + AUTH + "/v3auth");
private static final int V3AUTHS = 1, V3AUTH_ID = 2;
@@ -101,4 +101,4 @@ public class ClientAuthContentProvider extends ContentProvider {
ENABLED = "enabled";
}
-}
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/darkweb/genesissearchengine/libs/clientauth/ClientAuthDatabase.java b/app/src/main/java/com/darkweb/genesissearchengine/libs/providers/ClientAuthDatabase.java
similarity index 94%
rename from app/src/main/java/com/darkweb/genesissearchengine/libs/clientauth/ClientAuthDatabase.java
rename to app/src/main/java/com/darkweb/genesissearchengine/libs/providers/ClientAuthDatabase.java
index 305f926d..eea4273b 100644
--- a/app/src/main/java/com/darkweb/genesissearchengine/libs/clientauth/ClientAuthDatabase.java
+++ b/app/src/main/java/com/darkweb/genesissearchengine/libs/providers/ClientAuthDatabase.java
@@ -1,4 +1,4 @@
-package com.darkweb.genesissearchengine.libs.clientauth;
+package com.darkweb.genesissearchengine.libs.providers;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
diff --git a/app/src/main/java/com/darkweb/genesissearchengine/libs/providers/CookieContentProvider.java b/app/src/main/java/com/darkweb/genesissearchengine/libs/providers/CookieContentProvider.java
new file mode 100644
index 00000000..8029fc33
--- /dev/null
+++ b/app/src/main/java/com/darkweb/genesissearchengine/libs/providers/CookieContentProvider.java
@@ -0,0 +1,133 @@
+package com.darkweb.genesissearchengine.libs.providers;
+
+import android.content.ContentProvider;
+import android.content.ContentUris;
+import android.content.ContentValues;
+import android.content.Context;
+import android.content.UriMatcher;
+import android.database.Cursor;
+import android.database.sqlite.SQLiteDatabase;
+import android.net.Uri;
+import android.provider.BaseColumns;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import com.darkweb.genesissearchengine.libs.providers.HSDatabase;
+
+
+public class CookieContentProvider extends ContentProvider {
+ public static final String[] PROJECTION = new String[]{
+ ClientCookie._ID,
+ ClientCookie.DOMAIN,
+ ClientCookie.AUTH_COOKIE_VALUE,
+ ClientCookie.ENABLED
+ };
+ private static final String AUTH = "org.torproject.android.ui.hiddenservices.providers.cookie";
+ public static final Uri CONTENT_URI =
+ Uri.parse("content://" + AUTH + "/cookie");
+ //UriMatcher
+ private static final int COOKIES = 1;
+ private static final int COOKIE_ID = 2;
+
+ private static final UriMatcher uriMatcher;
+
+ static {
+ uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
+ uriMatcher.addURI(AUTH, "hs", COOKIES);
+ uriMatcher.addURI(AUTH, "hs/#", COOKIE_ID);
+ }
+
+ private HSDatabase mServervices;
+ private Context mContext;
+
+ @Override
+ public boolean onCreate() {
+ mContext = getContext();
+ mServervices = new HSDatabase(mContext);
+ return true;
+ }
+
+ @Nullable
+ @Override
+ public Cursor query(@NonNull Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
+ String where = selection;
+ if (uriMatcher.match(uri) == COOKIE_ID) {
+ where = "_id=" + uri.getLastPathSegment();
+ }
+
+ SQLiteDatabase db = mServervices.getReadableDatabase();
+
+ return db.query(HSDatabase.HS_CLIENT_COOKIE_TABLE_NAME, projection, where,
+ selectionArgs, null, null, sortOrder);
+ }
+
+ @Nullable
+ @Override
+ public String getType(@NonNull Uri uri) {
+ int match = uriMatcher.match(uri);
+
+ switch (match) {
+ case COOKIES:
+ return "vnd.android.cursor.dir/vnd.torproject.cookies";
+ case COOKIE_ID:
+ return "vnd.android.cursor.item/vnd.torproject.cookie";
+ default:
+ return null;
+ }
+ }
+
+ @Nullable
+ @Override
+ public Uri insert(@NonNull Uri uri, ContentValues values) {
+ long regId;
+
+ SQLiteDatabase db = mServervices.getWritableDatabase();
+
+ regId = db.insert(HSDatabase.HS_CLIENT_COOKIE_TABLE_NAME, null, values);
+
+ mContext.getContentResolver().notifyChange(CONTENT_URI, null);
+
+ return ContentUris.withAppendedId(CONTENT_URI, regId);
+ }
+
+ @Override
+ public int delete(@NonNull Uri uri, String selection, String[] selectionArgs) {
+
+ String where = selection;
+ if (uriMatcher.match(uri) == COOKIE_ID) {
+ where = "_id=" + uri.getLastPathSegment();
+ }
+
+ SQLiteDatabase db = mServervices.getWritableDatabase();
+
+ int rows = db.delete(HSDatabase.HS_CLIENT_COOKIE_TABLE_NAME, where, selectionArgs);
+
+ mContext.getContentResolver().notifyChange(CONTENT_URI, null);
+
+ return rows;
+
+ }
+
+ @Override
+ public int update(@NonNull Uri uri, ContentValues values, String selection, String[] selectionArgs) {
+ SQLiteDatabase db = mServervices.getWritableDatabase();
+
+ String where = selection;
+ if (uriMatcher.match(uri) == COOKIE_ID) {
+ where = "_id=" + uri.getLastPathSegment();
+ }
+
+ int rows = db.update(HSDatabase.HS_CLIENT_COOKIE_TABLE_NAME, values, where, null);
+ mContext.getContentResolver().notifyChange(CONTENT_URI, null);
+
+ return rows;
+ }
+
+ public static final class ClientCookie implements BaseColumns {
+ public static final String DOMAIN = "domain";
+ public static final String AUTH_COOKIE_VALUE = "auth_cookie_value";
+ public static final String ENABLED = "enabled";
+
+ private ClientCookie() {
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/darkweb/genesissearchengine/libs/providers/HSContentProvider.java b/app/src/main/java/com/darkweb/genesissearchengine/libs/providers/HSContentProvider.java
new file mode 100644
index 00000000..37ec23ac
--- /dev/null
+++ b/app/src/main/java/com/darkweb/genesissearchengine/libs/providers/HSContentProvider.java
@@ -0,0 +1,141 @@
+package com.darkweb.genesissearchengine.libs.providers;
+
+import android.content.ContentProvider;
+import android.content.ContentUris;
+import android.content.ContentValues;
+import android.content.Context;
+import android.content.UriMatcher;
+import android.database.Cursor;
+import android.database.sqlite.SQLiteDatabase;
+import android.net.Uri;
+import android.provider.BaseColumns;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import com.darkweb.genesissearchengine.libs.providers.HSDatabase;
+
+
+public class HSContentProvider extends ContentProvider {
+ public static final String[] PROJECTION = new String[]{
+ HiddenService._ID,
+ HiddenService.NAME,
+ HiddenService.PORT,
+ HiddenService.DOMAIN,
+ HiddenService.ONION_PORT,
+ HiddenService.AUTH_COOKIE,
+ HiddenService.AUTH_COOKIE_VALUE,
+ HiddenService.CREATED_BY_USER,
+ HiddenService.ENABLED
+ };
+ private static final String AUTH = "org.torproject.android.ui.hiddenservices.providers";
+ public static final Uri CONTENT_URI = Uri.parse("content://" + AUTH + "/hs");
+ //UriMatcher
+ private static final int ONIONS = 1;
+ private static final int ONION_ID = 2;
+
+ private static final UriMatcher uriMatcher;
+
+ static {
+ uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
+ uriMatcher.addURI(AUTH, "hs", ONIONS);
+ uriMatcher.addURI(AUTH, "hs/#", ONION_ID);
+ }
+
+ private HSDatabase mServervices;
+ private Context mContext;
+
+ @Override
+ public boolean onCreate() {
+ mContext = getContext();
+ mServervices = new HSDatabase(mContext);
+ return true;
+ }
+
+ @Nullable
+ @Override
+ public Cursor query(@NonNull Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
+ String where = selection;
+ if (uriMatcher.match(uri) == ONION_ID) {
+ where = "_id=" + uri.getLastPathSegment();
+ }
+
+ SQLiteDatabase db = mServervices.getReadableDatabase();
+
+ return db.query(HSDatabase.HS_DATA_TABLE_NAME, projection, where, selectionArgs, null, null, sortOrder);
+ }
+
+ @Nullable
+ @Override
+ public String getType(@NonNull Uri uri) {
+ int match = uriMatcher.match(uri);
+
+ switch (match) {
+ case ONIONS:
+ return "vnd.android.cursor.dir/vnd.torproject.onions";
+ case ONION_ID:
+ return "vnd.android.cursor.item/vnd.torproject.onion";
+ default:
+ return null;
+ }
+ }
+
+ @Nullable
+ @Override
+ public Uri insert(@NonNull Uri uri, ContentValues values) {
+ long regId;
+
+ SQLiteDatabase db = mServervices.getWritableDatabase();
+
+ regId = db.insert(HSDatabase.HS_DATA_TABLE_NAME, null, values);
+
+ mContext.getContentResolver().notifyChange(CONTENT_URI, null);
+
+ return ContentUris.withAppendedId(CONTENT_URI, regId);
+ }
+
+ @Override
+ public int delete(@NonNull Uri uri, String selection, String[] selectionArgs) {
+
+ String where = selection;
+ if (uriMatcher.match(uri) == ONION_ID) {
+ where = "_id=" + uri.getLastPathSegment();
+ }
+
+ SQLiteDatabase db = mServervices.getWritableDatabase();
+
+ int rows = db.delete(HSDatabase.HS_DATA_TABLE_NAME, where, selectionArgs);
+
+ mContext.getContentResolver().notifyChange(CONTENT_URI, null);
+
+ return rows;
+
+ }
+
+ @Override
+ public int update(@NonNull Uri uri, ContentValues values, String selection, String[] selectionArgs) {
+ SQLiteDatabase db = mServervices.getWritableDatabase();
+
+ String where = selection;
+ if (uriMatcher.match(uri) == ONION_ID) {
+ where = "_id=" + uri.getLastPathSegment();
+ }
+
+ int rows = db.update(HSDatabase.HS_DATA_TABLE_NAME, values, where, null);
+ mContext.getContentResolver().notifyChange(CONTENT_URI, null);
+
+ return rows;
+ }
+
+ public static final class HiddenService implements BaseColumns {
+ public static final String NAME = "name";
+ public static final String PORT = "port";
+ public static final String ONION_PORT = "onion_port";
+ public static final String DOMAIN = "domain";
+ public static final String AUTH_COOKIE = "auth_cookie";
+ public static final String AUTH_COOKIE_VALUE = "auth_cookie_value";
+ public static final String CREATED_BY_USER = "created_by_user";
+ public static final String ENABLED = "enabled";
+
+ private HiddenService() {
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/darkweb/genesissearchengine/libs/providers/HSDatabase.java b/app/src/main/java/com/darkweb/genesissearchengine/libs/providers/HSDatabase.java
new file mode 100644
index 00000000..c08171bf
--- /dev/null
+++ b/app/src/main/java/com/darkweb/genesissearchengine/libs/providers/HSDatabase.java
@@ -0,0 +1,49 @@
+package com.darkweb.genesissearchengine.libs.providers;
+
+import android.content.Context;
+import android.database.sqlite.SQLiteDatabase;
+import android.database.sqlite.SQLiteOpenHelper;
+
+public class HSDatabase extends SQLiteOpenHelper {
+
+ public static final String HS_DATA_TABLE_NAME = "hs_data";
+ public static final String HS_CLIENT_COOKIE_TABLE_NAME = "hs_client_cookie";
+ private static final int DATABASE_VERSION = 4;
+ private static final String DATABASE_NAME = "hidden_services";
+ private static final String HS_DATA_TABLE_CREATE =
+ "CREATE TABLE " + HS_DATA_TABLE_NAME + " (" +
+ "_id INTEGER PRIMARY KEY AUTOINCREMENT, " +
+ "name TEXT, " +
+ "domain TEXT, " +
+ "onion_port INTEGER, " +
+ "auth_cookie INTEGER DEFAULT 0, " +
+ "auth_cookie_value TEXT, " +
+ "created_by_user INTEGER DEFAULT 0, " +
+ "enabled INTEGER DEFAULT 1, " +
+ "port INTEGER, " +
+ "filepath TEXT);";
+
+ private static final String HS_CLIENT_COOKIE_TABLE_CREATE =
+ "CREATE TABLE " + HS_CLIENT_COOKIE_TABLE_NAME + " (" +
+ "_id INTEGER PRIMARY KEY AUTOINCREMENT, " +
+ "domain TEXT, " +
+ "auth_cookie_value TEXT, " +
+ "enabled INTEGER DEFAULT 1);";
+
+ public HSDatabase(Context context) {
+ super(context, DATABASE_NAME, null, DATABASE_VERSION);
+ }
+
+ @Override
+ public void onCreate(SQLiteDatabase db) {
+ db.execSQL(HS_DATA_TABLE_CREATE);
+ db.execSQL(HS_CLIENT_COOKIE_TABLE_CREATE);
+ }
+
+ @Override
+ public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
+ if (newVersion > oldVersion) {
+ db.execSQL("ALTER TABLE " + HS_DATA_TABLE_NAME + " ADD COLUMN filepath TEXT");
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/darkweb/genesissearchengine/libs/providers/OnionServiceContentProvider.java b/app/src/main/java/com/darkweb/genesissearchengine/libs/providers/OnionServiceContentProvider.java
new file mode 100644
index 00000000..12e537a5
--- /dev/null
+++ b/app/src/main/java/com/darkweb/genesissearchengine/libs/providers/OnionServiceContentProvider.java
@@ -0,0 +1,110 @@
+package com.darkweb.genesissearchengine.libs.providers;
+
+import android.content.ContentProvider;
+import android.content.ContentUris;
+import android.content.ContentValues;
+import android.content.UriMatcher;
+import android.database.Cursor;
+import android.database.sqlite.SQLiteDatabase;
+import android.net.Uri;
+import android.provider.BaseColumns;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
+public class OnionServiceContentProvider extends ContentProvider {
+
+ public static final String[] PROJECTION = {
+ OnionService._ID,
+ OnionService.NAME,
+ OnionService.PORT,
+ OnionService.DOMAIN,
+ OnionService.ONION_PORT,
+ OnionService.CREATED_BY_USER,
+ OnionService.ENABLED
+ };
+
+ private static final int ONIONS = 1, ONION_ID = 2;
+ private static final String AUTH = "org.torproject.android.ui.v3onionservice";
+ public static final Uri CONTENT_URI = Uri.parse("content://" + AUTH + "/v3");
+ private static final UriMatcher uriMatcher;
+
+ static {
+ uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
+ uriMatcher.addURI(AUTH, "v3", ONIONS);
+ uriMatcher.addURI(AUTH, "v3/#", ONION_ID);
+ }
+
+ private OnionServiceDatabase mDatabase;
+
+ @Override
+ public boolean onCreate() {
+ mDatabase = new OnionServiceDatabase(getContext());
+ return true;
+ }
+
+ @Nullable
+ @Override
+ public Cursor query(@NonNull Uri uri, @Nullable String[] projection, @Nullable String selection, @Nullable String[] selectionArgs, @Nullable String sortOrder) {
+ if (uriMatcher.match(uri) == ONION_ID)
+ selection = "_id=" + uri.getLastPathSegment();
+ SQLiteDatabase db = mDatabase.getReadableDatabase();
+ return db.query(OnionServiceDatabase.ONION_SERVICE_TABLE_NAME, projection, selection, selectionArgs, null, null, sortOrder);
+ }
+
+ @Nullable
+ @Override
+ public String getType(@NonNull Uri uri) {
+ int match = uriMatcher.match(uri);
+ switch (match) {
+ case ONIONS:
+ return "vnd.android.cursor.dir/vnd.torproject.onions";
+ case ONION_ID:
+ return "vnd.android.cursor.item/vnd.torproject.onion";
+ default:
+ return null;
+ }
+ }
+
+ @Nullable
+ @Override
+ public Uri insert(@NonNull Uri uri, @Nullable ContentValues values) {
+ SQLiteDatabase db = mDatabase.getWritableDatabase();
+ long regId = db.insert(OnionServiceDatabase.ONION_SERVICE_TABLE_NAME, null, values);
+ getContext().getContentResolver().notifyChange(CONTENT_URI, null);
+ return ContentUris.withAppendedId(CONTENT_URI, regId);
+ }
+
+ @Override
+ public int delete(@NonNull Uri uri, @Nullable String selection, @Nullable String[] selectionArgs) {
+ if (uriMatcher.match(uri) == ONION_ID)
+ selection = "_id=" + uri.getLastPathSegment();
+ SQLiteDatabase db = mDatabase.getWritableDatabase();
+ int rows = db.delete(OnionServiceDatabase.ONION_SERVICE_TABLE_NAME, selection, selectionArgs);
+ getContext().getContentResolver().notifyChange(CONTENT_URI, null);
+ return rows;
+ }
+
+ @Override
+ public int update(@NonNull Uri uri, @Nullable ContentValues values, @Nullable String selection, @Nullable String[] selectionArgs) {
+ SQLiteDatabase db = mDatabase.getWritableDatabase();
+ if (uriMatcher.match(uri) == ONION_ID)
+ selection = "_id=" + uri.getLastPathSegment();
+ int rows = db.update(OnionServiceDatabase.ONION_SERVICE_TABLE_NAME, values, selection, null);
+ getContext().getContentResolver().notifyChange(CONTENT_URI, null);
+ return rows;
+ }
+
+ public static final class OnionService implements BaseColumns {
+ public static final String NAME = "name";
+ public static final String PORT = "port";
+ public static final String ONION_PORT = "onion_port";
+ public static final String DOMAIN = "domain";
+ public static final String CREATED_BY_USER = "created_by_user";
+ public static final String ENABLED = "enabled";
+
+ private OnionService() { // no-op
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/darkweb/genesissearchengine/libs/providers/OnionServiceDatabase.java b/app/src/main/java/com/darkweb/genesissearchengine/libs/providers/OnionServiceDatabase.java
new file mode 100644
index 00000000..3a037b6d
--- /dev/null
+++ b/app/src/main/java/com/darkweb/genesissearchengine/libs/providers/OnionServiceDatabase.java
@@ -0,0 +1,41 @@
+package com.darkweb.genesissearchengine.libs.providers;
+
+import android.content.Context;
+import android.database.sqlite.SQLiteDatabase;
+import android.database.sqlite.SQLiteOpenHelper;
+
+public class OnionServiceDatabase extends SQLiteOpenHelper {
+
+ static final String DATABASE_NAME = "onion_service",
+ ONION_SERVICE_TABLE_NAME = "onion_services";
+ private static final int DATABASE_VERSION = 2;
+
+ private static final String ONION_SERVICES_CREATE_SQL =
+ "CREATE TABLE " + ONION_SERVICE_TABLE_NAME + " (" +
+ "_id INTEGER PRIMARY KEY AUTOINCREMENT, " +
+ "name TEXT, " +
+ "domain TEXT, " +
+ "onion_port INTEGER, " +
+ "created_by_user INTEGER DEFAULT 0, " +
+ "enabled INTEGER DEFAULT 1, " +
+ "port INTEGER, " +
+ "filepath TEXT);";
+
+ OnionServiceDatabase(Context context) {
+ super(context, DATABASE_NAME, null, DATABASE_VERSION);
+ }
+
+ @Override
+ public void onCreate(SQLiteDatabase db) {
+ db.execSQL(ONION_SERVICES_CREATE_SQL);
+ }
+
+ @Override
+ public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
+ if (newVersion > oldVersion) {
+ db.execSQL("ALTER TABLE " + ONION_SERVICE_TABLE_NAME + " ADD COLUMN filepath text");
+ }
+ }
+
+
+}
diff --git a/app/src/main/java/com/darkweb/genesissearchengine/pluginManager/adPluginManager/adManager.java b/app/src/main/java/com/darkweb/genesissearchengine/pluginManager/adPluginManager/adManager.java
index e9e62817..fd53651c 100644
--- a/app/src/main/java/com/darkweb/genesissearchengine/pluginManager/adPluginManager/adManager.java
+++ b/app/src/main/java/com/darkweb/genesissearchengine/pluginManager/adPluginManager/adManager.java
@@ -1,9 +1,14 @@
package com.darkweb.genesissearchengine.pluginManager.adPluginManager;
+import android.os.Handler;
import android.util.Log;
+import android.view.View;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
+
+import com.darkweb.genesissearchengine.dataManager.dataController;
+import com.darkweb.genesissearchengine.dataManager.dataEnums;
import com.darkweb.genesissearchengine.eventObserver;
import com.darkweb.genesissearchengine.pluginManager.pluginEnums;
import com.google.android.gms.ads.*;
@@ -83,8 +88,10 @@ public class adManager
@Override
public void onAdFailedToLoad(@NonNull LoadAdError var1) {
- Log.i("dsa","asd");
- bannerAdsLoading = false;
+ new Handler().postDelayed(() ->
+ {
+ initializeBannerAds();
+ }, 10000);
}
});
}
diff --git a/app/src/main/java/com/darkweb/genesissearchengine/pluginManager/downloadPluginManager/downloadReciever.java b/app/src/main/java/com/darkweb/genesissearchengine/pluginManager/downloadPluginManager/downloadReciever.java
index 8e53452b..354a356e 100644
--- a/app/src/main/java/com/darkweb/genesissearchengine/pluginManager/downloadPluginManager/downloadReciever.java
+++ b/app/src/main/java/com/darkweb/genesissearchengine/pluginManager/downloadPluginManager/downloadReciever.java
@@ -32,7 +32,6 @@ import com.darkweb.genesissearchengine.pluginManager.pluginEnums;
import com.darkweb.genesissearchengine.pluginManager.pluginReciever.downloadNotificationReciever;
import com.example.myapplication.R;
import org.mozilla.thirdparty.com.google.android.exoplayer2.util.Log;
-import org.torproject.android.proxy.util.Prefs;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
diff --git a/app/src/main/java/com/darkweb/genesissearchengine/pluginManager/langPluginManager/langManager.java b/app/src/main/java/com/darkweb/genesissearchengine/pluginManager/langPluginManager/langManager.java
index 71707201..107b8852 100644
--- a/app/src/main/java/com/darkweb/genesissearchengine/pluginManager/langPluginManager/langManager.java
+++ b/app/src/main/java/com/darkweb/genesissearchengine/pluginManager/langPluginManager/langManager.java
@@ -4,7 +4,11 @@ import android.content.res.Configuration;
import android.content.res.Resources;
import android.os.Build;
import androidx.appcompat.app.AppCompatActivity;
+
+import com.darkweb.genesissearchengine.appManager.activityContextManager;
+import com.darkweb.genesissearchengine.constants.status;
import com.darkweb.genesissearchengine.eventObserver;
+import com.darkweb.genesissearchengine.helperManager.helperMethod;
import com.darkweb.genesissearchengine.pluginManager.pluginEnums;
import java.util.Collections;
@@ -29,35 +33,39 @@ public class langManager {
onInitLanguage(pAppContext, pSettingLanguage, pSettingRegionLanguage, pThemeApplying);
}
- private boolean initLocale(Boolean pThemeApplying){
- if(!pThemeApplying){
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
- Locale mSystemLocale = Resources.getSystem().getConfiguration().getLocales().get(0);
- if(mSystemLocale!=mSystemLocale || !mSystemLocale.getLanguage().equals(mLanguage.getLanguage()) ){
- mEvent.invokeObserver(Collections.singletonList(mSystemLocale), pluginEnums.eLangManager.M_UPDATE_LOCAL);
- }
- } else {
- Locale mSystemLocale = Resources.getSystem().getConfiguration().locale;
- if(mSystemLocale!=mSystemLocale || !mSystemLocale.getLanguage().equals(mLanguage.getLanguage())){
- mEvent.invokeObserver(Collections.singletonList(mSystemLocale), pluginEnums.eLangManager.M_UPDATE_LOCAL);
- }
- }
- }
+ private boolean initLocale(){
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
+ Locale mSystemLocaleTemp = Resources.getSystem().getConfiguration().getLocales().get(0);
+ mEvent.invokeObserver(Collections.singletonList(mSystemLocaleTemp), pluginEnums.eLangManager.M_UPDATE_LOCAL);
+ mSystemLocale = mSystemLocaleTemp;
+ } else {
+ Locale mSystemLocaleTemp = Resources.getSystem().getConfiguration().locale;
+ mEvent.invokeObserver(Collections.singletonList(mSystemLocaleTemp), pluginEnums.eLangManager.M_UPDATE_LOCAL);
+ mSystemLocale = mSystemLocaleTemp;
+ }
return false;
}
private void onInitLanguage(AppCompatActivity pAppContext, String pSettingLanguage, String pSettingRegionLanguage, Boolean pThemeApplying) {
if(pSettingLanguage.equals("default")){
- if(!mLanguage.getLanguage().equals(Resources.getSystem().getConfiguration().locale.getLanguage()) || !mLanguage.getCountry().equals(Resources.getSystem().getConfiguration().locale.getCountry()))
+ Locale mSystemLocaleTemp = null;
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
+ mSystemLocaleTemp = Resources.getSystem().getConfiguration().getLocales().get(0);
+ } else {
+ mSystemLocaleTemp = Resources.getSystem().getConfiguration().locale;
+ }
+
+ if(!mLanguage.toString().equals(mSystemLocaleTemp.toString()))
{
if(mSystemLocale==null){
- initLocale(pThemeApplying);
+ initLocale();
}
+ mSystemLocale = mSystemLocaleTemp;
String mSystemLangugage = mSystemLocale.toString();
- if(mSystemLangugage.equals("en_US") || mSystemLangugage.equals("de_DE") || mSystemLangugage.equals("ur_UR") || mSystemLangugage.equals("ur_PK") || mSystemLangugage.equals("ca_ES") || mSystemLangugage.equals("zh_CN") || mSystemLangugage.equals("ch_CZ") || mSystemLangugage.equals("nl_NL") || mSystemLangugage.equals("fr_FR") || mSystemLangugage.equals("el_GR") || mSystemLangugage.equals("hu_HU") || mSystemLangugage.equals("in_ID") || mSystemLangugage.equals("it_IT") || mSystemLangugage.equals("ja_JP") || mSystemLangugage.equals("ko_KR") || mSystemLangugage.equals("pt_PT") || mSystemLangugage.equals("ro_RO") || mSystemLangugage.equals("ru_RU") || mSystemLangugage.equals("th_TH") || mSystemLangugage.equals("tr_TR") || mSystemLangugage.equals("uk_UA") || mSystemLangugage.equals("vi_VN")){
+ if(mSystemLangugage.equals("cs_CZ") || mSystemLangugage.equals("en_US") || mSystemLangugage.equals("de_DE") || mSystemLangugage.equals("ur_UR") || mSystemLangugage.equals("ur_PK") || mSystemLangugage.equals("ca_ES") || mSystemLangugage.equals("zh_CN") || mSystemLangugage.equals("ch_CZ") || mSystemLangugage.equals("nl_NL") || mSystemLangugage.equals("fr_FR") || mSystemLangugage.equals("el_GR") || mSystemLangugage.equals("hu_HU") || mSystemLangugage.equals("in_ID") || mSystemLangugage.equals("it_IT") || mSystemLangugage.equals("ja_JP") || mSystemLangugage.equals("ko_KR") || mSystemLangugage.equals("pt_PT") || mSystemLangugage.equals("ro_RO") || mSystemLangugage.equals("ru_RU") || mSystemLangugage.equals("th_TH") || mSystemLangugage.equals("tr_TR") || mSystemLangugage.equals("uk_UA") || mSystemLangugage.equals("vi_VN")){
if(mSystemLangugage.equals("ur_PK")){
mLanguage = new Locale("ur", "Ur");
- } else if(mSystemLangugage.equals("vi_VN")){
+ } else if(mSystemLangugage.equals("vi_VN") || mSystemLangugage.equals("cs_CZ")){
mLanguage = new Locale("ch", "Cz");
} else {
mLanguage = new Locale(mSystemLocale.getLanguage(), mSystemLocale.getCountry());
@@ -65,15 +73,18 @@ public class langManager {
}else {
mLanguage = new Locale("en", "Us");
}
+ helperMethod.updateResources(pAppContext, status.mSystemLocale.getLanguage());
}else {
- Locale mSystemLocale = Resources.getSystem().getConfiguration().locale;
- mEvent.invokeObserver(Collections.singletonList(mSystemLocale), pluginEnums.eLangManager.M_UPDATE_LOCAL);
+ helperMethod.updateResources(pAppContext, status.mSystemLocale.getLanguage());
return;
}
+
}else {
mLanguage = new Locale(pSettingLanguage, pSettingRegionLanguage);
}
+
+ status.mSystemLocale = mLanguage;
Locale.setDefault(mLanguage);
Resources resources = pAppContext.getResources();
Configuration config = resources.getConfiguration();
@@ -115,7 +126,7 @@ public class langManager {
}
else if(pEventType.equals(pluginEnums.eLangManager.M_RESUME))
{
- initLocale((boolean)pData.get(3));
+ initLocale();
onResume((AppCompatActivity) pData.get(0), (String)pData.get(1), (String)pData.get(2), (boolean)pData.get(3));
}
else if(pEventType.equals(pluginEnums.eLangManager.M_SET_LANGUAGE))
diff --git a/app/src/main/java/com/darkweb/genesissearchengine/pluginManager/orbotPluginManager/orbotManager.java b/app/src/main/java/com/darkweb/genesissearchengine/pluginManager/orbotPluginManager/orbotManager.java
index 0a65aa38..32e8b726 100644
--- a/app/src/main/java/com/darkweb/genesissearchengine/pluginManager/orbotPluginManager/orbotManager.java
+++ b/app/src/main/java/com/darkweb/genesissearchengine/pluginManager/orbotPluginManager/orbotManager.java
@@ -4,9 +4,9 @@ import android.content.Intent;
import android.os.Build;
import androidx.appcompat.app.AppCompatActivity;
import org.mozilla.gecko.PrefsHelper;
-import org.torproject.android.proxy.OrbotService;
-import org.torproject.android.proxy.util.Prefs;
-import org.torproject.android.proxy.wrapper.orbotLocalConstants;
+import org.torproject.android.service.OrbotService;
+import org.torproject.android.service.util.Prefs;
+import org.torproject.android.service.wrapper.orbotLocalConstants;
import java.lang.ref.WeakReference;
import java.util.List;
@@ -17,7 +17,8 @@ import com.darkweb.genesissearchengine.constants.strings;
import com.darkweb.genesissearchengine.eventObserver;
import com.darkweb.genesissearchengine.pluginManager.pluginEnums;
-import static org.torproject.android.proxy.TorServiceConstants.ACTION_START;
+import static org.torproject.android.service.TorServiceConstants.ACTION_START;
+
// https://github.com/guardianproject/orbot/blob/8fca5f8ecddb4da9565ac3fd8936e4f28acdd352/BUILD.md
public class orbotManager
@@ -60,6 +61,7 @@ public class orbotManager
}
else
{
+ mAppContext.get().stopService(mServiceIntent);
mAppContext.get().startService(mServiceIntent);
}
@@ -219,7 +221,9 @@ public class orbotManager
}
private void newCircuit(){
- OrbotService.getServiceObject().newIdentity();
+ if(OrbotService.getServiceObject()!=null){
+ OrbotService.getServiceObject().newIdentity();
+ }
}
private String getOrbotStatus(){
diff --git a/app/src/main/res/anim/fade_in_lang.xml b/app/src/main/res/anim/fade_in_lang.xml
index 0a08b417..97f216cc 100644
--- a/app/src/main/res/anim/fade_in_lang.xml
+++ b/app/src/main/res/anim/fade_in_lang.xml
@@ -1,7 +1,7 @@
diff --git a/app/src/main/res/anim/fade_out_lang.xml b/app/src/main/res/anim/fade_out_lang.xml
index 60fe9202..f4421c36 100644
--- a/app/src/main/res/anim/fade_out_lang.xml
+++ b/app/src/main/res/anim/fade_out_lang.xml
@@ -1,6 +1,6 @@
diff --git a/app/src/main/res/custom-xml/home/xml/hox_splash_gradient_back.xml b/app/src/main/res/custom-xml/home/xml/hox_splash_gradient_back.xml
new file mode 100644
index 00000000..48af58ff
--- /dev/null
+++ b/app/src/main/res/custom-xml/home/xml/hox_splash_gradient_back.xml
@@ -0,0 +1,7 @@
+
+
+
+
+ -
+
+
\ No newline at end of file
diff --git a/app/src/main/res/custom-xml/home/xml/splash_back.xml b/app/src/main/res/custom-xml/home/xml/splash_back.xml
new file mode 100644
index 00000000..624ed13a
--- /dev/null
+++ b/app/src/main/res/custom-xml/home/xml/splash_back.xml
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable-hdpi/ic_refresh_white_24dp.png b/app/src/main/res/drawable-hdpi/ic_refresh_white_24dp.png
old mode 100755
new mode 100644
diff --git a/app/src/main/res/drawable-hdpi/icon_ban.webp b/app/src/main/res/drawable-hdpi/icon_ban.webp
old mode 100755
new mode 100644
diff --git a/app/src/main/res/drawable-hdpi/icon_loading.webp b/app/src/main/res/drawable-hdpi/icon_loading.webp
old mode 100755
new mode 100644
diff --git a/app/src/main/res/drawable-hdpi/menu_item.webp b/app/src/main/res/drawable-hdpi/menu_item.webp
old mode 100755
new mode 100644
diff --git a/app/src/main/res/layouts/home/layout/home_view.xml b/app/src/main/res/layouts/home/layout/home_view.xml
index 2e4b4b12..46267256 100644
--- a/app/src/main/res/layouts/home/layout/home_view.xml
+++ b/app/src/main/res/layouts/home/layout/home_view.xml
@@ -25,7 +25,7 @@
android:background="@color/c_background"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
android:fitsSystemWindows="true"
- app:layout_scrollFlags="scroll|exitUntilCollapsed|snap"
+ app:layout_scrollFlags="enterAlwaysCollapsed"
android:translationZ="3dp">
-
diff --git a/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
old mode 100755
new mode 100644
diff --git a/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
old mode 100755
new mode 100644
diff --git a/orbotmanager.tar.gz b/orbotmanager.tar.gz
new file mode 100644
index 00000000..215d83bb
Binary files /dev/null and b/orbotmanager.tar.gz differ
diff --git a/orbotmanager/build.gradle b/orbotmanager/build.gradle
index edf0e14c..378653ed 100644
--- a/orbotmanager/build.gradle
+++ b/orbotmanager/build.gradle
@@ -3,11 +3,7 @@ apply plugin: 'com.android.library'
android {
compileSdkVersion 30
buildToolsVersion '30.0.3'
- ndkVersion '21.4.7075529'
- defaultConfig {
- minSdkVersion 21
- targetSdkVersion 30
- }
+ ndkVersion '21.3.6528147'
sourceSets {
main {
@@ -15,14 +11,18 @@ android {
}
}
+ defaultConfig {
+ minSdkVersion 16
+ targetSdkVersion 30
+ }
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
buildTypes {
release {
- minifyEnabled true
- proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
+ minifyEnabled false
+ proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
@@ -31,31 +31,38 @@ android {
}
lintOptions {
- abortOnError false
+ checkReleaseBuilds false
+ abortOnError true
+
+ htmlReport true
+ xmlReport false
+ textReport false
+
+ lintConfig file("../lint.xml")
}
packagingOptions {
- exclude 'assets/arm/obfs4proxy' //this is redundant
+ exclude 'META-INF/androidx.localbroadcastmanager_localbroadcastmanager.version'
}
-
}
dependencies {
-
- implementation 'org.torproject:tor-android-binary:0.4.4.6'
-
- implementation 'info.pluggabletransports.aptds:apt-dispatch-library:1.0.9'
- implementation 'info.pluggabletransports.aptds:apt-meek-obfs4-legacy:1.0.9'
- implementation 'info.pluggabletransports.aptds:jsocksAndroid:1.0.4'
+ implementation 'androidx.localbroadcastmanager:localbroadcastmanager:1.0.0'
+ implementation 'com.gitlab.guardianproject:jsocksandroid:1.0.4'
implementation 'com.jaredrummler:android-shell:1.0.0'
- implementation fileTree(dir: 'libs', include: ['.so'])
+ //implementation fileTree(dir: 'libs', include: ['.so','.aar'])
+
implementation 'androidx.core:core:1.5.0'
implementation 'androidx.localbroadcastmanager:localbroadcastmanager:1.0.0'
testImplementation 'junit:junit:4.13.2'
implementation 'com.offbynull.portmapper:portmapper:2.0.5'
- implementation 'info.guardianproject:jtorctl:0.4'
+ implementation 'info.guardianproject:geoip:20191217'
+ api 'info.guardianproject:jtorctl:0.4.5.7'
+ implementation 'info.guardianproject:tor-android:0.4.5.7'
+
+ implementation 'com.github.tladesignz:IPtProxy:1.0.0'
}
diff --git a/orbotmanager/proguard-rules.pro b/orbotmanager/proguard-rules.pro
index 97110cde..e69de29b 100644
--- a/orbotmanager/proguard-rules.pro
+++ b/orbotmanager/proguard-rules.pro
@@ -1,22 +0,0 @@
--keep,includedescriptorclasses class net.sqlcipher.** { *; }
--keep,includedescriptorclasses interface net.sqlcipher.** { *; }
-
--dontwarn javax.annotation.**
--dontwarn org.codehaus.mojo.animal_sniffer.*
--dontwarn okhttp3.internal.platform.ConscryptPlatform
--dontwarn org.conscrypt.ConscryptHostnameVerifier
--dontwarn okhttp3.*
--dontwarn org.chromium.net.*
-
--keep class com.flurry.** { *; }
--dontwarn com.flurry.**
--keepattributes *Annotation*,EnclosingMethod,Signature
--keepclasseswithmembers class * {
- public (android.content.Context, android.util.AttributeSet, int);
- }
- -keepnames class * implements android.os.Parcelable {
- public static final ** CREATOR;
- }
-
- -dontobfuscate
- -optimizations !code/simplification/arithmetic,!field/*,!class/merging/*,!code/allocation/variable
diff --git a/orbotmanager/src/main/AndroidManifest.xml b/orbotmanager/src/main/AndroidManifest.xml
index 801a9c18..589ee334 100644
--- a/orbotmanager/src/main/AndroidManifest.xml
+++ b/orbotmanager/src/main/AndroidManifest.xml
@@ -1,4 +1,6 @@
+
+
diff --git a/orbotmanager/src/main/ic_launcher-playstore.png b/orbotmanager/src/main/ic_launcher-playstore.png
deleted file mode 100644
index 24889790..00000000
Binary files a/orbotmanager/src/main/ic_launcher-playstore.png and /dev/null differ
diff --git a/orbotmanager/src/main/java/org/torproject/android/proxy/OrbotConstants.java b/orbotmanager/src/main/java/org/torproject/android/proxy/OrbotConstants.java
deleted file mode 100644
index 9dd461d2..00000000
--- a/orbotmanager/src/main/java/org/torproject/android/proxy/OrbotConstants.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/* Copyright (c) 2009, Nathan Freitas, Orbot/The Guardian Project - http://openideals.com/guardian */
-/* See LICENSE for licensing information */
-
-package org.torproject.android.proxy;
-
-public interface OrbotConstants {
-
- String TAG = "Orbot";
-
- String PREF_OR = "pref_or";
- String PREF_OR_PORT = "pref_or_port";
- String PREF_OR_NICKNAME = "pref_or_nickname";
- String PREF_REACHABLE_ADDRESSES = "pref_reachable_addresses";
- String PREF_REACHABLE_ADDRESSES_PORTS = "pref_reachable_addresses_ports";
-
- String PREF_DISABLE_NETWORK = "pref_disable_network";
-
- String PREF_TOR_SHARED_PREFS = "org.torproject.android_preferences";
-
- String PREF_SOCKS = "pref_socks";
-
- String PREF_HTTP = "pref_http";
-
- String PREF_ISOLATE_DEST = "pref_isolate_dest";
-
- String PREF_CONNECTION_PADDING = "pref_connection_padding";
- String PREF_REDUCED_CONNECTION_PADDING = "pref_reduced_connection_padding";
- String PREF_CIRCUIT_PADDING = "pref_circuit_padding";
- String PREF_REDUCED_CIRCUIT_PADDING = "pref_reduced_circuit_padding";
-
- String PREF_PREFER_IPV6 = "pref_prefer_ipv6";
- String PREF_DISABLE_IPV4 = "pref_disable_ipv4";
-
-
- String APP_TOR_KEY = "_app_tor";
- String APP_DATA_KEY = "_app_data";
- String APP_WIFI_KEY = "_app_wifi";
-}
diff --git a/orbotmanager/src/main/java/org/torproject/android/proxy/StartTorReceiver.java b/orbotmanager/src/main/java/org/torproject/android/proxy/StartTorReceiver.java
deleted file mode 100644
index 8e50e3b9..00000000
--- a/orbotmanager/src/main/java/org/torproject/android/proxy/StartTorReceiver.java
+++ /dev/null
@@ -1,42 +0,0 @@
-package org.torproject.android.proxy;
-
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.os.Build;
-import android.text.TextUtils;
-
-import org.torproject.android.proxy.util.Prefs;
-
-
-public class StartTorReceiver extends BroadcastReceiver implements TorServiceConstants {
-
- @Override
- public void onReceive(Context context, Intent intent) {
- /* sanitize the Intent before forwarding it to OrbotService */
- Prefs.setContext(context);
- String action = intent.getAction();
- if (TextUtils.equals(action, ACTION_START)) {
- String packageName = intent.getStringExtra(EXTRA_PACKAGE_NAME);
- if (Prefs.allowBackgroundStarts()) {
- Intent startTorIntent = new Intent(context, OrbotService.class);
- startTorIntent.setAction(action);
- if (packageName != null) {
- startTorIntent.putExtra(OrbotService.EXTRA_PACKAGE_NAME, packageName);
- }
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
- context.startForegroundService(startTorIntent);
- } else {
- context.startService(startTorIntent);
- }
- } else if (!TextUtils.isEmpty(packageName)) {
- // let the requesting app know that the user has disabled
- // starting via Intent
- Intent startsDisabledIntent = new Intent(ACTION_STATUS);
- startsDisabledIntent.putExtra(EXTRA_STATUS, STATUS_STARTS_DISABLED);
- startsDisabledIntent.setPackage(packageName);
- context.sendBroadcast(startsDisabledIntent);
- }
- }
- }
-}
diff --git a/orbotmanager/src/main/java/org/torproject/android/proxy/TorServiceConstants.java b/orbotmanager/src/main/java/org/torproject/android/proxy/TorServiceConstants.java
deleted file mode 100644
index 0d54bdf9..00000000
--- a/orbotmanager/src/main/java/org/torproject/android/proxy/TorServiceConstants.java
+++ /dev/null
@@ -1,119 +0,0 @@
-/* Copyright (c) 2009, Nathan Freitas, Orbot / The Guardian Project - http://openideals.com/guardian */
-/* See LICENSE for licensing information */
-
-package org.torproject.android.proxy;
-
-import android.content.Intent;
-
-public interface TorServiceConstants {
-
- String DIRECTORY_TOR_DATA = "tordata";
-
- String TOR_CONTROL_PORT_FILE = "control.txt";
- String TOR_PID_FILE = "torpid";
-
- //torrc (tor config file)
- String TORRC_ASSET_KEY = "torrc";
-
- String TOR_CONTROL_COOKIE = "control_auth_cookie";
-
- //geoip data file asset key
- String GEOIP_ASSET_KEY = "geoip";
- String GEOIP6_ASSET_KEY = "geoip6";
-
- String IP_LOCALHOST = "127.0.0.1";
- int TOR_TRANSPROXY_PORT_DEFAULT = 9040;
-
- int TOR_DNS_PORT_DEFAULT = 5400;
-
- String HTTP_PROXY_PORT_DEFAULT = "8125"; // like Privoxy!
- String SOCKS_PROXY_PORT_DEFAULT = "9055";
-
- //control port
- String LOG_NOTICE_HEADER = "NOTICE";
- String LOG_NOTICE_BOOTSTRAPPED = "Bootstrapped";
-
- /**
- * A request to Orbot to transparently start Tor services
- */
- String ACTION_START = "org.torproject.android.intent.action.START";
- String ACTION_STOP = "org.torproject.android.intent.action.STOP";
-
- String ACTION_START_VPN = "org.torproject.android.intent.action.START_VPN";
- String ACTION_STOP_VPN = "org.torproject.android.intent.action.STOP_VPN";
-
- String ACTION_START_ON_BOOT = "org.torproject.android.intent.action.START_BOOT";
-
- int REQUEST_VPN = 7777;
-
- /**
- * {@link Intent} send by Orbot with {@code ON/OFF/STARTING/STOPPING} status
- */
- String ACTION_STATUS = "org.torproject.android.intent.action.STATUS";
- /**
- * {@code String} that contains a status constant: {@link #STATUS_ON},
- * {@link #STATUS_OFF}, {@link #STATUS_STARTING}, or
- * {@link #STATUS_STOPPING}
- */
- String EXTRA_STATUS = "org.torproject.android.intent.extra.STATUS";
- /**
- * A {@link String} {@code packageName} for Orbot to direct its status reply
- * to, used in {@link #ACTION_START} {@link Intent}s sent to Orbot
- */
- String EXTRA_PACKAGE_NAME = "org.torproject.android.intent.extra.PACKAGE_NAME";
- /**
- * The SOCKS proxy settings in URL form.
- */
- String EXTRA_SOCKS_PROXY = "org.torproject.android.intent.extra.SOCKS_PROXY";
- String EXTRA_SOCKS_PROXY_HOST = "org.torproject.android.intent.extra.SOCKS_PROXY_HOST";
- String EXTRA_SOCKS_PROXY_PORT = "org.torproject.android.intent.extra.SOCKS_PROXY_PORT";
- /**
- * The HTTP proxy settings in URL form.
- */
- String EXTRA_HTTP_PROXY = "org.torproject.android.intent.extra.HTTP_PROXY";
- String EXTRA_HTTP_PROXY_HOST = "org.torproject.android.intent.extra.HTTP_PROXY_HOST";
- String EXTRA_HTTP_PROXY_PORT = "org.torproject.android.intent.extra.HTTP_PROXY_PORT";
-
- String EXTRA_DNS_PORT = "org.torproject.android.intent.extra.DNS_PORT";
- String EXTRA_TRANS_PORT = "org.torproject.android.intent.extra.TRANS_PORT";
-
- String LOCAL_ACTION_LOG = "log";
- String LOCAL_ACTION_BANDWIDTH = "bandwidth";
- String LOCAL_EXTRA_LOG = "log";
- String LOCAL_ACTION_PORTS = "ports";
-
- /**
- * All tor-related services and daemons are stopped
- */
- String STATUS_OFF = "OFF";
- /**
- * All tor-related services and daemons have completed starting
- */
- String STATUS_ON = "ON";
- String STATUS_STARTING = "STARTING";
- String STATUS_STOPPING = "STOPPING";
-
- /**
- * The user has disabled the ability for background starts triggered by
- * apps. Fallback to the old {@link Intent} action that brings up Orbot:
- * {@link org.torproject.android.OrbotMainActivity#INTENT_ACTION_REQUEST_START_TOR}
- */
- String STATUS_STARTS_DISABLED = "STARTS_DISABLED";
-
- // actions for internal command Intents
- String CMD_SIGNAL_HUP = "signal_hup";
- String CMD_NEWNYM = "newnym";
- String CMD_SETTING = "setting";
- String CMD_SET_EXIT = "setexit";
- String CMD_ACTIVE = "ACTIVE";
-
- String PREF_BINARY_TOR_VERSION_INSTALLED = "BINARY_TOR_VERSION_INSTALLED";
-
- //obfsproxy
- String OBFSCLIENT_ASSET_KEY = "obfs4proxy";
-
- String HIDDEN_SERVICES_DIR = "hidden_services";
- String ONION_SERVICES_DIR = "v3_onion_services";
- String V3_CLIENT_AUTH_DIR = "v3_client_auth";
-
-}
diff --git a/orbotmanager/src/main/java/org/torproject/android/proxy/util/CustomNativeLoader.java b/orbotmanager/src/main/java/org/torproject/android/proxy/util/CustomNativeLoader.java
deleted file mode 100644
index 9b22adfe..00000000
--- a/orbotmanager/src/main/java/org/torproject/android/proxy/util/CustomNativeLoader.java
+++ /dev/null
@@ -1,128 +0,0 @@
-package org.torproject.android.proxy.util;
-
-import android.annotation.SuppressLint;
-import android.content.Context;
-import android.content.pm.ApplicationInfo;
-import android.os.Build;
-import android.util.Log;
-
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.util.zip.ZipEntry;
-import java.util.zip.ZipFile;
-
-public class CustomNativeLoader {
-
- private final static String TAG = "CNL";
-
- @SuppressLint("SetWorldReadable")
- private static boolean loadFromZip(Context context, String libname, File destLocalFile, String arch) {
-
-
- ZipFile zipFile = null;
- InputStream stream = null;
-
- try {
- zipFile = new ZipFile(context.getApplicationInfo().sourceDir);
- ZipEntry entry = zipFile.getEntry("lib/" + arch + "/" + libname + ".so");
- if (entry == null) {
- entry = zipFile.getEntry("jni/" + arch + "/" + libname + ".so");
- if (entry == null)
- throw new Exception("Unable to find file in apk:" + "lib/" + arch + "/" + libname);
- }
-
- //how we wrap this in another stream because the native .so is zipped itself
- stream = zipFile.getInputStream(entry);
-
- OutputStream out = new FileOutputStream(destLocalFile);
- byte[] buf = new byte[4096];
- int len;
- while ((len = stream.read(buf)) > 0) {
- Thread.yield();
- out.write(buf, 0, len);
- }
- out.close();
-
- destLocalFile.setReadable(true, false);
- destLocalFile.setExecutable(true, false);
- destLocalFile.setWritable(true);
-
- return true;
- } catch (Exception e) {
- Log.e(TAG, e.getMessage());
- } finally {
- if (stream != null) {
- try {
- stream.close();
- } catch (Exception e) {
- Log.e(TAG, e.getMessage());
- }
- }
- if (zipFile != null) {
- try {
- zipFile.close();
- } catch (Exception e) {
- Log.e(TAG, e.getMessage());
- }
- }
- }
- return false;
- }
-
- public static File loadNativeBinary(Context context, String libname, File destLocalFile) {
-
- try {
-
-
- File fileNativeBin = new File(getNativeLibraryDir(context), libname + ".so");
- if (!fileNativeBin.exists())
- fileNativeBin = new File(getNativeLibraryDir(context), "lib" + libname + ".so");
-
- if (fileNativeBin.exists()) {
- if (fileNativeBin.canExecute())
- return fileNativeBin;
- else {
- setExecutable(fileNativeBin);
-
- if (fileNativeBin.canExecute())
- return fileNativeBin;
- }
- }
-
- String folder = Build.CPU_ABI;
-
-
- String javaArch = System.getProperty("os.arch");
- if (javaArch != null && javaArch.contains("686")) {
- folder = "x86";
- }
-
- if (loadFromZip(context, libname, destLocalFile, folder)) {
- return destLocalFile;
- }
-
- } catch (Throwable e) {
- Log.e(TAG, e.getMessage(), e);
- }
-
-
- return null;
- }
-
- private static void setExecutable(File fileBin) {
- fileBin.setReadable(true);
- fileBin.setExecutable(true);
- fileBin.setWritable(false);
- fileBin.setWritable(true, true);
- }
-
- // Return Full path to the directory where native JNI libraries are stored.
- private static String getNativeLibraryDir(Context context) {
- ApplicationInfo appInfo = context.getApplicationInfo();
- return appInfo.nativeLibraryDir;
- }
-
-}
-
diff --git a/orbotmanager/src/main/java/org/torproject/android/proxy/util/CustomShell.java b/orbotmanager/src/main/java/org/torproject/android/proxy/util/CustomShell.java
deleted file mode 100644
index 299a6218..00000000
--- a/orbotmanager/src/main/java/org/torproject/android/proxy/util/CustomShell.java
+++ /dev/null
@@ -1,80 +0,0 @@
-package org.torproject.android.proxy.util;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.annotation.WorkerThread;
-
-import com.jaredrummler.android.shell.CommandResult;
-import com.jaredrummler.android.shell.Shell;
-import com.jaredrummler.android.shell.ShellExitCode;
-import com.jaredrummler.android.shell.StreamGobbler;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-
-public class CustomShell extends Shell {
-
-
- @WorkerThread
- public static CommandResult run(@NonNull String shell, boolean waitFor, @Nullable Map env, @NonNull String command) {
- List stdout = Collections.synchronizedList(new ArrayList<>());
- List stderr = Collections.synchronizedList(new ArrayList<>());
- int exitCode = -1;
-
- try {
-
- // setup our process, retrieve stdin stream, and stdout/stderr gobblers
- //Process process = runWithEnv(command, env);
- ProcessBuilder builder = new ProcessBuilder();
-
- if (env != null && (!env.isEmpty()))
- builder.environment().putAll(env);
-
- builder.command("/system/bin/" + shell, "-c", command);
- Process process = builder.start();
-
- StreamGobbler stdoutGobbler = null;
- StreamGobbler stderrGobbler = null;
-
- if (waitFor) {
- stdoutGobbler = new StreamGobbler(process.getInputStream(), stdout);
- stderrGobbler = new StreamGobbler(process.getErrorStream(), stderr);
-
- // start gobbling and write our commands to the shell
- stdoutGobbler.start();
- stderrGobbler.start();
- }
-
- // wait for our process to finish, while we gobble away in the background
- if (waitFor)
- exitCode = process.waitFor();
- else
- exitCode = 0;
-
- // make sure our threads are done gobbling, our streams are closed, and the process is destroyed - while the
- // latter two shouldn't be needed in theory, and may even produce warnings, in "normal" Java they are required
- // for guaranteed cleanup of resources, so lets be safe and do this on Android as well
- /**
- try {
- stdin.close();
- } catch (IOException e) {
- // might be closed already
- }**/
-
- if (waitFor) {
- stdoutGobbler.join();
- stderrGobbler.join();
- }
-
- } catch (InterruptedException e) {
- exitCode = ShellExitCode.WATCHDOG_EXIT;
- } catch (IOException e) {
- exitCode = ShellExitCode.SHELL_WRONG_UID;
- }
-
- return new CommandResult(stdout, stderr, exitCode);
- }
-}
diff --git a/orbotmanager/src/main/java/org/torproject/android/proxy/util/CustomTorResourceInstaller.java b/orbotmanager/src/main/java/org/torproject/android/proxy/util/CustomTorResourceInstaller.java
deleted file mode 100644
index c2b8ac7f..00000000
--- a/orbotmanager/src/main/java/org/torproject/android/proxy/util/CustomTorResourceInstaller.java
+++ /dev/null
@@ -1,184 +0,0 @@
-package org.torproject.android.proxy.util;
-
-import android.content.Context;
-import android.content.pm.ApplicationInfo;
-import android.util.Log;
-
-import org.torproject.android.binary.TorServiceConstants;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.util.concurrent.TimeoutException;
-import java.util.zip.ZipEntry;
-import java.util.zip.ZipInputStream;
-
-public class CustomTorResourceInstaller implements TorServiceConstants {
-
-
- private File installFolder;
- private Context context;
-
- private File fileTorrc;
- private File fileTor;
-
- public CustomTorResourceInstaller(Context context, File installFolder) {
- this.installFolder = installFolder;
- this.context = context;
- }
-
- // Return Full path to the directory where native JNI libraries are stored.
- private static String getNativeLibraryDir(Context context) {
- ApplicationInfo appInfo = context.getApplicationInfo();
- return appInfo.nativeLibraryDir;
- }
-
- /*
- * Write the inputstream contents to the file
- */
- private 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;
-
- }
-
-
-
-
- /*
- * Extract the Tor binary from the APK file using ZIP
- */
-
- private static File[] listf(String directoryName) {
-
- // .............list file
- File directory = new File(directoryName);
-
- // get all the files from a directory
- File[] fList = directory.listFiles();
-
- if (fList != null)
- for (File file : fList) {
- if (file.isFile()) {
- Log.d(TAG, file.getAbsolutePath());
- } else if (file.isDirectory()) {
- listf(file.getAbsolutePath());
- }
- }
-
- return fList;
- }
-
- //
- /*
- * Extract the Tor resources from the APK file using ZIP
- *
- * @File path to the Tor executable
- */
- public File installResources() throws IOException, TimeoutException {
-
- fileTor = new File(installFolder, TOR_ASSET_KEY);
-
- if (!installFolder.exists())
- installFolder.mkdirs();
-
- installGeoIP();
- fileTorrc = assetToFile(COMMON_ASSET_KEY + TORRC_ASSET_KEY, TORRC_ASSET_KEY, false, false);
-
- File fileNativeDir = new File(getNativeLibraryDir(context));
- fileTor = new File(fileNativeDir, TOR_ASSET_KEY + ".so");
-
- if (fileTor.exists()) {
- if (fileTor.canExecute())
- return fileTor;
- else {
- setExecutable(fileTor);
-
- if (fileTor.canExecute())
- return fileTor;
- }
- }
-
- File fileTorBin = new File(installFolder, TOR_BINARY_KEY);
-
- //it exists but we can't execute it, so copy it to a new path
- if (fileTor.exists()) {
- InputStream is = new FileInputStream(fileTor);
- streamToFile(is, fileTorBin, false, true);
- setExecutable(fileTorBin);
-
- if (fileTorBin.exists() && fileTorBin.canExecute())
- return fileTorBin;
- }
-
- //let's try another approach
- fileTor = CustomNativeLoader.loadNativeBinary(context, TOR_ASSET_KEY, fileTorBin);
-
- if (fileTor != null && fileTor.exists())
- setExecutable(fileTor);
-
- if (fileTor != null && fileTor.exists() && fileTor.canExecute())
- return fileTor;
-
- return null;
- }
-
- private boolean installGeoIP() throws IOException {
-
- assetToFile(COMMON_ASSET_KEY + GEOIP_ASSET_KEY, GEOIP_ASSET_KEY, false, false);
-
- assetToFile(COMMON_ASSET_KEY + GEOIP6_ASSET_KEY, GEOIP6_ASSET_KEY, false, false);
-
- return true;
- }
-
- /*
- * Reads file from assetPath/assetKey writes it to the install folder
- */
- private File assetToFile(String assetPath, String assetKey, boolean isZipped, boolean isExecutable) throws IOException {
- InputStream is = context.getAssets().open(assetPath);
- File outFile = new File(installFolder, assetKey);
- streamToFile(is, outFile, false, isZipped);
- if (isExecutable) {
- setExecutable(outFile);
- }
- return outFile;
- }
-
- private void setExecutable(File fileBin) {
- fileBin.setReadable(true);
- fileBin.setExecutable(true);
- fileBin.setWritable(false);
- fileBin.setWritable(true, true);
- }
-}
-
diff --git a/orbotmanager/src/main/java/org/torproject/android/proxy/util/DummyActivity.java b/orbotmanager/src/main/java/org/torproject/android/proxy/util/DummyActivity.java
deleted file mode 100644
index 8ec51831..00000000
--- a/orbotmanager/src/main/java/org/torproject/android/proxy/util/DummyActivity.java
+++ /dev/null
@@ -1,15 +0,0 @@
-package org.torproject.android.proxy.util;
-
-import android.app.Activity;
-import android.os.Bundle;
-
-/*
- * To combat background service being stopped/swiped
- */
-public class DummyActivity extends Activity {
- @Override
- public void onCreate(Bundle icicle) {
- super.onCreate(icicle);
- finish();
- }
-}
\ No newline at end of file
diff --git a/orbotmanager/src/main/java/org/torproject/android/proxy/util/ExternalIPFetcher.java b/orbotmanager/src/main/java/org/torproject/android/proxy/util/ExternalIPFetcher.java
deleted file mode 100644
index af0bed23..00000000
--- a/orbotmanager/src/main/java/org/torproject/android/proxy/util/ExternalIPFetcher.java
+++ /dev/null
@@ -1,85 +0,0 @@
-package org.torproject.android.proxy.util;
-
-import org.json.JSONArray;
-import org.json.JSONObject;
-import org.torproject.android.proxy.OrbotService;
-import org.torproject.android.proxy.TorEventHandler;
-
-import java.io.BufferedReader;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.net.InetSocketAddress;
-import java.net.Proxy;
-import java.net.URL;
-import java.net.URLConnection;
-
-public class ExternalIPFetcher implements Runnable {
-
- private final static String ONIONOO_BASE_URL = "https://onionoo.torproject.org/details?fields=country_name,as_name,or_addresses&lookup=";
- private OrbotService mService;
- private TorEventHandler.Node mNode;
- private int mLocalHttpProxyPort = 8125;
-
- public ExternalIPFetcher(OrbotService service, TorEventHandler.Node node, int localProxyPort) {
- mService = service;
- mNode = node;
- mLocalHttpProxyPort = localProxyPort;
- }
-
- public void run() {
- try {
-
- URLConnection conn;
-
- Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress("127.0.0.1", mLocalHttpProxyPort));
- conn = new URL(ONIONOO_BASE_URL + mNode.id).openConnection(proxy);
-
- conn.setRequestProperty("Connection", "Close");
- conn.setConnectTimeout(60000);
- conn.setReadTimeout(60000);
-
- InputStream is = conn.getInputStream();
-
- BufferedReader reader = new BufferedReader(new InputStreamReader(is));
-
- // getting JSON string from URL
-
- StringBuffer json = new StringBuffer();
- String line;
-
- while ((line = reader.readLine()) != null)
- json.append(line);
-
- JSONObject jsonNodeInfo = new org.json.JSONObject(json.toString());
-
- JSONArray jsonRelays = jsonNodeInfo.getJSONArray("relays");
-
- if (jsonRelays.length() > 0) {
- mNode.ipAddress = jsonRelays.getJSONObject(0).getJSONArray("or_addresses").getString(0).split(":")[0];
- mNode.country = jsonRelays.getJSONObject(0).getString("country_name");
- mNode.organization = jsonRelays.getJSONObject(0).getString("as_name");
-
- StringBuffer sbInfo = new StringBuffer();
- sbInfo.append(mNode.name).append("(");
- sbInfo.append(mNode.ipAddress).append(")");
-
- if (mNode.country != null)
- sbInfo.append(' ').append(mNode.country);
-
- if (mNode.organization != null)
- sbInfo.append(" (").append(mNode.organization).append(')');
-
- mService.debug(sbInfo.toString());
-
- }
-
- reader.close();
- is.close();
-
-
- } catch (Exception e) {
-
- // mService.debug ("Error getting node details from onionoo: " + e.getMessage());
- }
- }
-}
diff --git a/orbotmanager/src/main/java/org/torproject/android/proxy/util/NativeLoader.java b/orbotmanager/src/main/java/org/torproject/android/proxy/util/NativeLoader.java
deleted file mode 100644
index dc04bdf1..00000000
--- a/orbotmanager/src/main/java/org/torproject/android/proxy/util/NativeLoader.java
+++ /dev/null
@@ -1,98 +0,0 @@
-package org.torproject.android.proxy.util;
-
-import android.annotation.SuppressLint;
-import android.content.Context;
-import android.os.Build;
-import android.util.Log;
-
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.util.zip.ZipEntry;
-import java.util.zip.ZipFile;
-
-public class NativeLoader {
-
- private final static String TAG = "TorNativeLoader";
-
- @SuppressLint("SetWorldReadable")
- private static boolean loadFromZip(Context context, String libName, File destLocalFile, String folder) {
-
-
- ZipFile zipFile = null;
- InputStream stream = null;
- try {
- zipFile = new ZipFile(context.getApplicationInfo().sourceDir);
-
- /**
- Enumeration extends ZipEntry> entries = zipFile.entries();
- while (entries.hasMoreElements())
- {
- ZipEntry entry = entries.nextElement();
- Log.d("Zip","entry: " + entry.getName());
- }
- **/
-
- ZipEntry entry = zipFile.getEntry("lib/" + folder + "/" + libName + ".so");
- if (entry == null) {
- entry = zipFile.getEntry("lib/" + folder + "/" + libName);
- if (entry == null)
- throw new Exception("Unable to find file in apk:" + "lib/" + folder + "/" + libName);
- }
- stream = zipFile.getInputStream(entry);
-
- OutputStream out = new FileOutputStream(destLocalFile);
- byte[] buf = new byte[4096];
- int len;
- while ((len = stream.read(buf)) > 0) {
- Thread.yield();
- out.write(buf, 0, len);
- }
- out.close();
-
- destLocalFile.setReadable(true, false);
- destLocalFile.setExecutable(true, false);
- destLocalFile.setWritable(true);
-
- return true;
- } catch (Exception e) {
- Log.e(TAG, e.getMessage());
- } finally {
- if (stream != null) {
- try {
- stream.close();
- } catch (Exception e) {
- Log.e(TAG, e.getMessage());
- }
- }
- if (zipFile != null) {
- try {
- zipFile.close();
- } catch (Exception e) {
- Log.e(TAG, e.getMessage());
- }
- }
- }
- return false;
- }
-
- public static synchronized boolean initNativeLibs(Context context, String binaryName, File destLocalFile) {
-
- try {
- String folder = Build.CPU_ABI;
-
- String javaArch = System.getProperty("os.arch");
- if (javaArch != null && javaArch.contains("686")) {
- folder = "x86";
- }
-
- return loadFromZip(context, binaryName, destLocalFile, folder);
-
- } catch (Throwable e) {
- e.printStackTrace();
- }
-
- return false;
- }
-}
diff --git a/orbotmanager/src/main/java/org/torproject/android/proxy/util/PortForwarder.java b/orbotmanager/src/main/java/org/torproject/android/proxy/util/PortForwarder.java
deleted file mode 100644
index 216d098c..00000000
--- a/orbotmanager/src/main/java/org/torproject/android/proxy/util/PortForwarder.java
+++ /dev/null
@@ -1,77 +0,0 @@
-package org.torproject.android.proxy.util;
-
-import android.util.Log;
-
-import com.offbynull.portmapper.PortMapperFactory;
-import com.offbynull.portmapper.gateway.Bus;
-import com.offbynull.portmapper.gateway.Gateway;
-import com.offbynull.portmapper.gateways.network.NetworkGateway;
-import com.offbynull.portmapper.gateways.network.internalmessages.KillNetworkRequest;
-import com.offbynull.portmapper.gateways.process.ProcessGateway;
-import com.offbynull.portmapper.gateways.process.internalmessages.KillProcessRequest;
-import com.offbynull.portmapper.mapper.MappedPort;
-import com.offbynull.portmapper.mapper.PortMapper;
-import com.offbynull.portmapper.mapper.PortType;
-
-import java.util.List;
-
-public class PortForwarder {
-
- private boolean shutdown = false;
- private Thread mThread = null;
-
- public void shutdown() {
- shutdown = true;
- }
-
- public void forward(final int internalPort, final int externalPort, final long lifetime) throws InterruptedException {
-
- mThread = new Thread() {
- public void run() {
- try {
- forwardSync(internalPort, externalPort, lifetime);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- };
-
- mThread.start();
- }
-
-
- public void forwardSync(int internalPort, int externalPort, long lifetime) throws InterruptedException {
- // Start gateways
- Gateway network = NetworkGateway.create();
- Gateway process = ProcessGateway.create();
- Bus networkBus = network.getBus();
- Bus processBus = process.getBus();
-
-// Discover port forwarding devices and take the first one found
- List mappers = PortMapperFactory.discover(networkBus, processBus);
- PortMapper mapper = mappers.get(0);
-
-// Map internal port 12345 to some external port (55555 preferred)
-//
-// IMPORTANT NOTE: Many devices prevent you from mapping ports that are <= 1024
-// (both internal and external ports). Be mindful of this when choosing which
-// ports you want to map.
- MappedPort mappedPort = mapper.mapPort(PortType.TCP, internalPort, externalPort, lifetime);
- Log.d(getClass().getName(), "Port mapping added: " + mappedPort);
-
-// Refresh mapping half-way through the lifetime of the mapping (for example,
-// if the mapping is available for 40 seconds, refresh it every 20 seconds)
- while (!shutdown) {
- mappedPort = mapper.refreshPort(mappedPort, mappedPort.getLifetime() / 2L);
- Log.d(getClass().getName(), "Port mapping refreshed: " + mappedPort);
- Thread.sleep(mappedPort.getLifetime() * 1000L);
- }
-
-// Unmap port 12345
- mapper.unmapPort(mappedPort);
-
-// Stop gateways
- networkBus.send(new KillNetworkRequest());
- processBus.send(new KillProcessRequest()); // can kill this after discovery
- }
-}
diff --git a/orbotmanager/src/main/java/org/torproject/android/proxy/util/Prefs.java b/orbotmanager/src/main/java/org/torproject/android/proxy/util/Prefs.java
deleted file mode 100644
index a87e9692..00000000
--- a/orbotmanager/src/main/java/org/torproject/android/proxy/util/Prefs.java
+++ /dev/null
@@ -1,143 +0,0 @@
-package org.torproject.android.proxy.util;
-
-import android.content.Context;
-import android.content.SharedPreferences;
-
-import org.torproject.android.proxy.OrbotConstants;
-import org.torproject.android.proxy.wrapper.orbotLocalConstants;
-
-import java.util.Locale;
-
-public class Prefs {
-
- private final static String PREF_BRIDGES_ENABLED = "pref_bridges_enabled";
- private final static String PREF_BRIDGES_LIST = "pref_bridges_list";
- private final static String PREF_DEFAULT_LOCALE = "pref_default_locale";
- private final static String PREF_ENABLE_LOGGING = "pref_enable_logging";
- private final static String PREF_EXPANDED_NOTIFICATIONS = "pref_expanded_notifications";
- private final static String PREF_PERSIST_NOTIFICATIONS = "pref_persistent_notifications";
- private final static String PREF_START_ON_BOOT = "pref_start_boot";
- private final static String PREF_ALLOW_BACKGROUND_STARTS = "pref_allow_background_starts";
- private final static String PREF_OPEN_PROXY_ON_ALL_INTERFACES = "pref_open_proxy_on_all_interfaces";
- private final static String PREF_USE_VPN = "pref_vpn";
- private final static String PREF_EXIT_NODES = "pref_exit_nodes";
- private final static String PREF_BE_A_SNOWFLAKE = "pref_be_a_snowflake";
-
- private static SharedPreferences prefs;
-
- public static void setContext(Context context) {
- if (prefs == null)
- prefs = getSharedPrefs(context);
- }
-
- private static void putBoolean(String key, boolean value) {
- prefs.edit().putBoolean(key, value).apply();
- }
-
- private static void putString(String key, String value) {
- prefs.edit().putString(key, value).apply();
- }
-
- public static boolean bridgesEnabled() {
- //if phone is in Farsi, enable bridges by default
- boolean bridgesEnabledDefault = Locale.getDefault().getLanguage().equals("fa");
- return prefs.getBoolean(PREF_BRIDGES_ENABLED, bridgesEnabledDefault);
- }
-
- public static void putBridgesEnabled(boolean value) {
- putBoolean(PREF_BRIDGES_ENABLED, value);
- }
-
- public static String getBridgesList() {
- String defaultBridgeType = "obfs4";
- if (Locale.getDefault().getLanguage().equals("fa"))
- defaultBridgeType = "meek"; //if Farsi, use meek as the default bridge type
- if(orbotLocalConstants.mIsManualBridge){
- if(!orbotLocalConstants.mManualBridgeType.equals("")){
- defaultBridgeType = orbotLocalConstants.mManualBridgeType;
- putString(PREF_BRIDGES_LIST, defaultBridgeType);
- return defaultBridgeType;
- }
- }else {
- if(orbotLocalConstants.mBridges.equals("obfs4")){
- defaultBridgeType = "obfs4";
- putString(PREF_BRIDGES_LIST, defaultBridgeType);
- return defaultBridgeType;
- }else if(orbotLocalConstants.mBridges.equals("meek")){
- defaultBridgeType = "meek";
- putString(PREF_BRIDGES_LIST, defaultBridgeType);
- return defaultBridgeType;
- }
- }
-
- return prefs.getString(PREF_BRIDGES_LIST, defaultBridgeType);
- }
-
- public static void setBridgesList(String value) {
- putString(PREF_BRIDGES_LIST, value);
- }
-
- public static String getDefaultLocale() {
- return prefs.getString(PREF_DEFAULT_LOCALE, Locale.getDefault().getLanguage());
- }
-
- public static boolean beSnowflakeProxy () {
- return prefs.getBoolean(PREF_BE_A_SNOWFLAKE,false);
- }
-
- public static void setBeSnowflakeProxy (boolean beSnowflakeProxy) {
- putBoolean(PREF_BE_A_SNOWFLAKE,beSnowflakeProxy);
- }
-
- public static void setDefaultLocale(String value) {
- putString(PREF_DEFAULT_LOCALE, value);
- }
-
- public static boolean expandedNotifications() {
- return prefs.getBoolean(PREF_EXPANDED_NOTIFICATIONS, true);
- }
-
- public static boolean useDebugLogging() {
- return false;//prefs.getBoolean(PREF_ENABLE_LOGGING, false);
- }
-
- public static boolean persistNotifications() {
- return prefs.getBoolean(PREF_PERSIST_NOTIFICATIONS, true);
- }
-
- public static boolean allowBackgroundStarts() {
- return prefs.getBoolean(PREF_ALLOW_BACKGROUND_STARTS, true);
- }
-
- public static boolean openProxyOnAllInterfaces() {
- return prefs.getBoolean(PREF_OPEN_PROXY_ON_ALL_INTERFACES, false);
- }
-
- public static boolean useVpn() {
- return prefs.getBoolean(PREF_USE_VPN, false);
- }
-
- public static void putUseVpn(boolean value) {
- putBoolean(PREF_USE_VPN, value);
- }
-
- public static boolean startOnBoot() {
- return prefs.getBoolean(PREF_START_ON_BOOT, true);
- }
-
- public static void putStartOnBoot(boolean value) {
- putBoolean(PREF_START_ON_BOOT, value);
- }
-
- public static String getExitNodes() {
- return prefs.getString(PREF_EXIT_NODES, "");
- }
-
- public static void setExitNodes(String exits) {
- putString(PREF_EXIT_NODES, exits);
- }
-
- public static SharedPreferences getSharedPrefs(Context context) {
- return context.getSharedPreferences(OrbotConstants.PREF_TOR_SHARED_PREFS, Context.MODE_MULTI_PROCESS);
- }
-}
diff --git a/orbotmanager/src/main/java/org/torproject/android/proxy/util/TCPSourceApp.java b/orbotmanager/src/main/java/org/torproject/android/proxy/util/TCPSourceApp.java
deleted file mode 100644
index 83af3e3b..00000000
--- a/orbotmanager/src/main/java/org/torproject/android/proxy/util/TCPSourceApp.java
+++ /dev/null
@@ -1,307 +0,0 @@
-package org.torproject.android.proxy.util;
-
-/***********************************************************************
- *
- * Copyright (c) 2013, Sebastiano Gottardo
- * All rights reserved.
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * * Neither the name of the MegaDevs nor the
- * names of its contributors may be used to endorse or promote products
- * derived from this software without specific prior written permission.
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL SEBASTIANO GOTTARDO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-import android.annotation.SuppressLint;
-import android.content.Context;
-import android.content.pm.PackageInfo;
-import android.content.pm.PackageManager;
-import android.content.pm.PackageManager.NameNotFoundException;
-
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.FileReader;
-import java.io.IOException;
-import java.net.Inet4Address;
-import java.net.InetAddress;
-import java.net.NetworkInterface;
-import java.net.SocketException;
-import java.util.Collections;
-import java.util.List;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-/**
- * Main class for the TCPSourceApp library.
- *
- * @author Sebastiano Gottardo
- */
-public class TCPSourceApp {
-
- /*
- * In a Linux-based OS, each active TCP socket is mapped in the following
- * two files. A socket may be mapped in the '/proc/net/tcp' file in case
- * of a simple IPv4 address, or in the '/proc/net/tcp6' if an IPv6 address
- * is available.
- */
- private static final String TCP_4_FILE_PATH = "/proc/net/tcp";
- private static final String TCP_6_FILE_PATH = "/proc/net/tcp6";
- /*
- * Two regular expressions that are able to extract valuable informations
- * from the two /proc/net/tcp* files. More specifically, there are three
- * fields that are extracted:
- * - address
- * - port
- * - PID
- */
- private static final String TCP_6_PATTERN = "\\d+:\\s([0-9A-F]{32}):([0-9A-F]{4})\\s[0-9A-F]{32}:[0-9A-F]{4}\\s[0-9A-F]{2}\\s[0-9]{8}:[0-9]{8}\\s[0-9]{2}:[0-9]{8}\\s[0-9]{8}\\s+([0-9]+)";
- private static final String TCP_4_PATTERN = "\\d+:\\s([0-9A-F]{8}):([0-9A-F]{4})\\s[0-9A-F]{8}:[0-9A-F]{4}\\s[0-9A-F]{2}\\s[0-9A-F]{8}:[0-9A-F]{8}\\s[0-9]{2}:[0-9]{8}\\s[0-9A-F]{8}\\s+([0-9]+)";
-//sargo:/ $ cat /proc/net/tcp6
-// sl local_address remote_address st tx_queue rx_queue tr tm->when retrnsmt uid timeout inode
-// 0: 00000000000000000000000000000000:C36A 00000000000000000000000000000000:0000 8A 00000000:00000000 00:00000000 00000000 1001 0 35059 1 0000000000000000 99 0 0 10 0
-// 1: 00000000000000000000000000000000:A64B 00000000000000000000000000000000:0000 8A 00000000:00000000 00:00000000 00000000 1001 0 910009 1 0000000000000000 99 0 0 10 0
- /*
- * Optimises the socket lookup by checking if the connected network
- * interface has a 'valid' IPv6 address (a global address, not a link-local
- * one).
- */
- private static boolean checkConnectedIfaces = true;
-// sl local_address rem_address st tx_queue rx_queue tr tm->when retrnsmt uid timeout inode
-// 0: 00000000:C368 00000000:0000 8A 00000000:00000000 00:00000000 00000000 1001 0 34999 1 0000000000000000 99 0 0 10 0
-
- /**
- * The main method of the TCPSourceApp library. This method receives an
- * Android Context instance, which is used to access the PackageManager.
- * It parses the /proc/net/tcp* files, looking for a socket entry that
- * matches the given port. If it finds an entry, this method extracts the
- * PID value and it uses the PackageManager.getPackagesFromPid() method to
- * find the originating application.
- *
- * @param context a valid Android Context instance
- * @param daddr the (logical) address of the destination
- * @param dport the (logical) port of the destination
- * @return an AppDescriptor object, representing the found application; null
- * if no application could be found
- */
- public static AppDescriptor getApplicationInfo(Context context, String saddr, int sport, String daddr, int dport) {
-
- File tcp;
- BufferedReader reader;
- String line;
- StringBuilder builder;
- String content;
-
- try {
- boolean hasIPv6 = true;
-
- // if true, checks for a connected network interface with a valid
- // IPv4 / IPv6 address
- if (checkConnectedIfaces) {
- String ipv4Address = getIPAddress(true);
- String ipv6Address = getIPAddress(false);
-
- hasIPv6 = (ipv6Address.length() > 0);
- }
-
- tcp = new File(TCP_6_FILE_PATH);
- reader = new BufferedReader(new FileReader(tcp));
- builder = new StringBuilder();
-
- while ((line = reader.readLine()) != null) {
- builder.append(line);
- }
-
- content = builder.toString();
-
- Matcher m6 = Pattern.compile(TCP_6_PATTERN, Pattern.CASE_INSENSITIVE | Pattern.UNIX_LINES | Pattern.DOTALL).matcher(content);
-
- if (hasIPv6)
- while (m6.find()) {
- String addressEntry = m6.group(1);
- String portEntry = m6.group(2);
- int pidEntry = Integer.valueOf(m6.group(3));
-
- if (Integer.parseInt(portEntry, 16) == dport) {
- PackageManager manager = context.getPackageManager();
- String[] packagesForUid = manager.getPackagesForUid(pidEntry);
-
- if (packagesForUid != null) {
- String packageName = packagesForUid[0];
- PackageInfo pInfo = manager.getPackageInfo(packageName, 0);
- String version = pInfo.versionName;
-
- return new AppDescriptor(pidEntry, packageName, version);
- }
- }
- }
-
- } catch (SocketException e) {
- e.printStackTrace();
- } catch (FileNotFoundException e) {
- e.printStackTrace();
- } catch (IOException e) {
- e.printStackTrace();
- } catch (NameNotFoundException e) {
- e.printStackTrace();
- } catch (Exception e) {
- e.printStackTrace();
- }
-
- // From here, no connection with the given port could be found in the tcp6 file
- // So let's try the tcp (IPv4) one
-
- try {
- tcp = new File(TCP_4_FILE_PATH);
- reader = new BufferedReader(new FileReader(tcp));
- builder = new StringBuilder();
-
- while ((line = reader.readLine()) != null) {
- builder.append(line);
- }
-
- content = builder.toString();
-
- Matcher m4 = Pattern.compile(TCP_4_PATTERN, Pattern.CASE_INSENSITIVE | Pattern.UNIX_LINES | Pattern.DOTALL).matcher(content);
-
- while (m4.find()) {
- String addressEntry = m4.group(1);
- String portEntry = m4.group(2);
- int pidEntry = Integer.valueOf(m4.group(3));
-
- if (Integer.parseInt(portEntry, 16) == dport) {
- PackageManager manager = context.getPackageManager();
- String[] packagesForUid = manager.getPackagesForUid(pidEntry);
-
- if (packagesForUid != null) {
- String packageName = packagesForUid[0];
- PackageInfo pInfo = manager.getPackageInfo(packageName, 0);
- String version = pInfo.versionName;
-
- return new AppDescriptor(pidEntry, packageName, version);
- }
- }
- }
-
- } catch (SocketException e) {
- e.printStackTrace();
- } catch (FileNotFoundException e) {
- e.printStackTrace();
- } catch (IOException e) {
- e.printStackTrace();
- } catch (NameNotFoundException e) {
- e.printStackTrace();
- } catch (Exception e) {
- e.printStackTrace();
- }
-
- return null;
- }
-
- @SuppressLint("DefaultLocale")
- public static String getIPAddress(boolean useIPv4) throws SocketException {
-
- List interfaces = Collections.list(NetworkInterface.getNetworkInterfaces());
-
- for (NetworkInterface intf : interfaces) {
- List addrs = Collections.list(intf.getInetAddresses());
-
- for (InetAddress addr : addrs) {
- if (!addr.isLoopbackAddress()) {
- String sAddr = addr.getHostAddress().toUpperCase();
-
- boolean isIPv4 = addr instanceof Inet4Address;
-
- if (useIPv4) {
- if (isIPv4)
- return sAddr;
- } else {
- if (!isIPv4) {
- if (sAddr.startsWith("fe80") || sAddr.startsWith("FE80")) // skipping link-local addresses
- continue;
-
- int delim = sAddr.indexOf('%'); // drop ip6 port suffix
- return delim < 0 ? sAddr : sAddr.substring(0, delim);
- }
- }
- }
- }
- }
-
- return "";
- }
-
- /*
- * Sets the connected interfaces optimisation.
- */
- public static void setCheckConnectedIfaces(boolean value) {
- checkConnectedIfaces = value;
- }
-
- /*
- * This class represents an Android application. Each application is
- * uniquely identified by its package name (e.g. com.megadevs.tcpsourceapp)
- * and its version (e.g. 1.0).
- */
- public static class AppDescriptor {
-
- private String packageName;
- private String version;
- private int uid;
-
- public AppDescriptor(int uid, String pName, String ver) {
- this.uid = uid;
- packageName = pName;
- version = ver;
- }
-
- public int getUid() {
- return uid;
- }
-
- public String getPackageName() {
- return packageName;
- }
-
- public String getVersion() {
- return version;
- }
-
- /*
- * Override of the 'equals' method, in order to have a proper
- * comparison between two AppDescriptor objects.
- *
- * (non-Javadoc)
- * @see java.lang.Object#equals(java.lang.Object)
- */
- @Override
- public boolean equals(Object o) {
-
- if (o instanceof AppDescriptor) {
- boolean c1 = ((AppDescriptor) o).packageName.compareTo(this.packageName) == 0;
- boolean c2 = ((AppDescriptor) o).version.compareTo(this.version) == 0;
-
- return c1 && c2;
- }
-
- return false;
- }
-
- }
-
-}
\ No newline at end of file
diff --git a/orbotmanager/src/main/java/org/torproject/android/proxy/util/TorServiceUtils.java b/orbotmanager/src/main/java/org/torproject/android/proxy/util/TorServiceUtils.java
deleted file mode 100644
index 155869f8..00000000
--- a/orbotmanager/src/main/java/org/torproject/android/proxy/util/TorServiceUtils.java
+++ /dev/null
@@ -1,27 +0,0 @@
-/* Copyright (c) 2009, Nathan Freitas, Orbot / The Guardian Project - http://openideals.com/guardian */
-/* See LICENSE for licensing information */
-package org.torproject.android.proxy.util;
-
-import org.torproject.android.proxy.TorServiceConstants;
-
-import java.net.ConnectException;
-import java.net.InetSocketAddress;
-import java.net.Socket;
-
-public class TorServiceUtils implements TorServiceConstants {
-
- public static boolean isPortOpen(final String ip, final int port, final int timeout) {
- try {
- Socket socket = new Socket();
- socket.connect(new InetSocketAddress(ip, port), timeout);
- socket.close();
- return true;
- } catch (ConnectException ce) {
- //ce.printStackTrace();
- return false;
- } catch (Exception ex) {
- //ex.printStackTrace();
- return false;
- }
- }
-}
diff --git a/orbotmanager/src/main/java/org/torproject/android/proxy/util/Utils.java b/orbotmanager/src/main/java/org/torproject/android/proxy/util/Utils.java
deleted file mode 100644
index 6e3bbbb9..00000000
--- a/orbotmanager/src/main/java/org/torproject/android/proxy/util/Utils.java
+++ /dev/null
@@ -1,183 +0,0 @@
-/* Copyright (c) 2009, Nathan Freitas, Orbot / The Guardian Project - http://openideals.com/guardian */
-/* See LICENSE for licensing information */
-
-
-package org.torproject.android.proxy.util;
-
-import java.io.BufferedInputStream;
-import java.io.BufferedOutputStream;
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.FileReader;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.util.zip.ZipEntry;
-import java.util.zip.ZipOutputStream;
-
-public class Utils {
-
-
- public static String readString(InputStream stream) {
- String line;
-
- StringBuffer out = new StringBuffer();
-
- try {
- BufferedReader reader = new BufferedReader(new InputStreamReader(stream));
-
- while ((line = reader.readLine()) != null) {
- out.append(line);
- out.append('\n');
-
- }
- } catch (IOException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
-
- return out.toString();
-
- }
-
- /*
- * Load the log file text
- */
- public static String loadTextFile(String path) {
- String line;
-
- StringBuffer out = new StringBuffer();
-
- try {
- BufferedReader reader = new BufferedReader((new FileReader(new File(path))));
-
- while ((line = reader.readLine()) != null) {
- out.append(line);
- out.append('\n');
-
- }
-
- reader.close();
- } catch (IOException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
-
- return out.toString();
-
- }
-
-
- /*
- * Load the log file text
- */
- public static boolean saveTextFile(String path, String contents) {
-
- try {
-
- FileWriter writer = new FileWriter(path, false);
- writer.write(contents);
-
- writer.close();
-
-
- return true;
-
- } catch (IOException e) {
- // Log.d(TAG, "error writing file: " + path, e);
- e.printStackTrace();
- return false;
- }
-
-
- }
-
-
- /*
- *
- * Zips a file at a location and places the resulting zip file at the toLocation
- * Example: zipFileAtPath("downloads/myfolder", "downloads/myFolder.zip");
- */
-
- public static boolean zipFileAtPath(String sourcePath, String toLocation) {
- final int BUFFER = 2048;
-
- File sourceFile = new File(sourcePath);
- try {
- BufferedInputStream origin;
- FileOutputStream dest = new FileOutputStream(toLocation);
- ZipOutputStream out = new ZipOutputStream(new BufferedOutputStream(
- dest));
- if (sourceFile.isDirectory()) {
- zipSubFolder(out, sourceFile, sourceFile.getParent().length());
- } else {
- byte[] data = new byte[BUFFER];
- FileInputStream fi = new FileInputStream(sourcePath);
- origin = new BufferedInputStream(fi, BUFFER);
- ZipEntry entry = new ZipEntry(getLastPathComponent(sourcePath));
- entry.setTime(sourceFile.lastModified()); // to keep modification time after unzipping
- out.putNextEntry(entry);
- int count;
- while ((count = origin.read(data, 0, BUFFER)) != -1) {
- out.write(data, 0, count);
- }
- }
- out.close();
- } catch (Exception e) {
- e.printStackTrace();
- return false;
- }
- return true;
- }
-
- /*
- *
- * Zips a subfolder
- *
- */
-
- private static void zipSubFolder(ZipOutputStream out, File folder,
- int basePathLength) throws IOException {
-
- final int BUFFER = 2048;
-
- File[] fileList = folder.listFiles();
- BufferedInputStream origin;
- for (File file : fileList) {
- if (file.isDirectory()) {
- zipSubFolder(out, file, basePathLength);
- } else {
- byte[] data = new byte[BUFFER];
- String unmodifiedFilePath = file.getPath();
- String relativePath = unmodifiedFilePath
- .substring(basePathLength);
- FileInputStream fi = new FileInputStream(unmodifiedFilePath);
- origin = new BufferedInputStream(fi, BUFFER);
- ZipEntry entry = new ZipEntry(relativePath);
- entry.setTime(file.lastModified()); // to keep modification time after unzipping
- out.putNextEntry(entry);
- int count;
- while ((count = origin.read(data, 0, BUFFER)) != -1) {
- out.write(data, 0, count);
- }
- origin.close();
- }
- }
- }
-
- /*
- * gets the last path component
- *
- * Example: getLastPathComponent("downloads/example/fileToZip");
- * Result: "fileToZip"
- */
- public static String getLastPathComponent(String filePath) {
- String[] segments = filePath.split("/");
- if (segments.length == 0)
- return "";
- return segments[segments.length - 1];
- }
-}
diff --git a/orbotmanager/src/main/java/org/torproject/android/proxy/vpn/OrbotVpnManager.java b/orbotmanager/src/main/java/org/torproject/android/proxy/vpn/OrbotVpnManager.java
deleted file mode 100644
index b58bdc52..00000000
--- a/orbotmanager/src/main/java/org/torproject/android/proxy/vpn/OrbotVpnManager.java
+++ /dev/null
@@ -1,408 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.torproject.android.proxy.vpn;
-
-import android.annotation.TargetApi;
-import android.app.Service;
-import android.content.Context;
-import android.content.Intent;
-import android.content.SharedPreferences;
-import android.content.pm.PackageManager.NameNotFoundException;
-import android.net.VpnService;
-import android.os.Build;
-import android.os.Handler;
-import android.os.Message;
-import android.os.ParcelFileDescriptor;
-import android.util.Log;
-import android.widget.Toast;
-
-import com.runjva.sourceforge.jsocks.protocol.ProxyServer;
-import com.runjva.sourceforge.jsocks.server.ServerAuthenticatorNone;
-
-import org.torproject.android.proxy.OrbotConstants;
-import org.torproject.android.proxy.OrbotService;
-import org.torproject.android.proxy.TorServiceConstants;
-import org.torproject.android.proxy.util.CustomNativeLoader;
-import org.torproject.android.proxy.util.Prefs;
-import org.torproject.android.service.R;
-
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.FileReader;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.io.PrintStream;
-import java.net.InetAddress;
-import java.util.ArrayList;
-import java.util.concurrent.TimeoutException;
-
-import static org.torproject.android.proxy.TorServiceConstants.ACTION_START;
-import static org.torproject.android.proxy.TorServiceConstants.ACTION_START_VPN;
-import static org.torproject.android.proxy.TorServiceConstants.ACTION_STOP_VPN;
-
-public class OrbotVpnManager implements Handler.Callback {
- private static final String TAG = "OrbotVpnService";
- private final static int VPN_MTU = 1500;
- private final static boolean mIsLollipop = Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP;
- private final static String PDNSD_BIN = "pdnsd";
- public static int sSocksProxyServerPort = -1;
- public static String sSocksProxyLocalhost = null;
- boolean isStarted = false;
-
- File filePdnsPid;
- private Thread mThreadVPN;
- private final static String mSessionName = "OrbotVPN";
- private ParcelFileDescriptor mInterface;
- private int mTorSocks = -1;
- private int mTorDns = -1;
- private int pdnsdPort = 8091;
- private ProxyServer mSocksProxyServer;
- private final File filePdnsd;
- private boolean isRestart = false;
- private final VpnService mService;
-
- public OrbotVpnManager(VpnService service) {
- mService = service;
- filePdnsd = CustomNativeLoader.loadNativeBinary(service.getApplicationContext(), PDNSD_BIN, new File(service.getFilesDir(), PDNSD_BIN));
- Tun2Socks.init();
- }
-
- public static File makePdnsdConf(Context context, File fileDir, String torDnsHost, int torDnsPort, String pdnsdHost, int pdnsdPort) throws IOException {
- String conf = String.format(context.getString(R.string.pdnsd_conf), torDnsHost, torDnsPort, fileDir.getCanonicalPath(), pdnsdHost, pdnsdPort);
-
- Log.d(TAG, "pdsnd conf:" + conf);
-
- File fPid = new File(fileDir, pdnsdPort + "pdnsd.conf");
-
- if (fPid.exists()) {
- fPid.delete();
- }
-
- FileOutputStream fos = new FileOutputStream(fPid, false);
- PrintStream ps = new PrintStream(fos);
- ps.print(conf);
- ps.close();
-
- File cache = new File(fileDir, "pdnsd.cache");
-
- if (!cache.exists()) {
- try {
- cache.createNewFile();
- } catch (Exception e) {
- }
- }
- return fPid;
- }
-
- public int handleIntent(VpnService.Builder builder, Intent intent) {
- if (intent != null) {
- String action = intent.getAction();
-
- if (action != null) {
- if (action.equals(ACTION_START_VPN) || action.equals(ACTION_START)) {
- Log.d(TAG, "starting VPN");
-
- isStarted = true;
-
- // Stop the previous session by interrupting the thread.
- if (mThreadVPN != null && mThreadVPN.isAlive())
- stopVPN();
-
- if (mTorSocks != -1) {
- if (!mIsLollipop) {
- startSocksBypass();
- }
-
- setupTun2Socks(builder);
- }
-
- } else if (action.equals(ACTION_STOP_VPN)) {
- isStarted = false;
-
- Log.d(TAG, "stopping VPN");
-
- stopVPN();
- } else if (action.equals(TorServiceConstants.LOCAL_ACTION_PORTS)) {
- Log.d(TAG, "setting VPN ports");
-
- int torSocks = intent.getIntExtra(OrbotService.EXTRA_SOCKS_PROXY_PORT, -1);
- int torDns = intent.getIntExtra(OrbotService.EXTRA_DNS_PORT, -1);
-
- //if running, we need to restart
- if ((torSocks != mTorSocks || torDns != mTorDns)) {
-
- mTorSocks = torSocks;
- mTorDns = torDns;
-
- if (!mIsLollipop) {
- stopSocksBypass();
- startSocksBypass();
- }
-
- setupTun2Socks(builder);
- }
- }
- }
-
- }
-
-
- return Service.START_STICKY;
- }
-
- private void startSocksBypass() {
- new Thread() {
- public void run() {
-
- //generate the proxy port that the
- if (sSocksProxyServerPort == -1) {
- try {
-
- sSocksProxyLocalhost = "127.0.0.1";// InetAddress.getLocalHost().getHostAddress();
- sSocksProxyServerPort = (int) ((Math.random() * 1000) + 10000);
-
- } catch (Exception e) {
- Log.e(TAG, "Unable to access localhost", e);
- throw new RuntimeException("Unable to access localhost: " + e);
-
- }
-
- }
-
-
- if (mSocksProxyServer != null) {
- stopSocksBypass();
- }
-
- try {
- mSocksProxyServer = new ProxyServer(new ServerAuthenticatorNone(null, null));
- ProxyServer.setVpnService(mService);
- mSocksProxyServer.start(sSocksProxyServerPort, 5, InetAddress.getLocalHost());
-
- } catch (Exception e) {
- Log.e(TAG, "error getting host", e);
- }
- }
- }.start();
- }
-
- private synchronized void stopSocksBypass() {
- if (mSocksProxyServer != null) {
- mSocksProxyServer.stop();
- mSocksProxyServer = null;
- }
- }
-
- private void stopVPN() {
- if (mIsLollipop)
- stopSocksBypass();
-
- Tun2Socks.Stop();
-
- if (mInterface != null) {
- try {
- Log.d(TAG, "closing interface, destroying VPN interface");
-
- mInterface.close();
- mInterface = null;
-
- } catch (Exception e) {
- Log.d(TAG, "error stopping tun2socks", e);
- } catch (Error e) {
- Log.d(TAG, "error stopping tun2socks", e);
- }
- }
- stopDns();
- mThreadVPN = null;
- }
-
- @Override
- public boolean handleMessage(Message message) {
- if (message != null) {
- Toast.makeText(mService, message.what, Toast.LENGTH_SHORT).show();
- }
- return true;
- }
-
- private synchronized void setupTun2Socks(final VpnService.Builder builder) {
- if (mInterface != null) //stop tun2socks now to give it time to clean up
- {
- isRestart = true;
- Tun2Socks.Stop();
-
- stopDns();
-
- }
-
- mThreadVPN = new Thread() {
-
- public void run() {
- try {
-
- if (isRestart) {
- Log.d(TAG, "is a restart... let's wait for a few seconds");
- Thread.sleep(3000);
- }
-
- final String vpnName = "GenesisVPN";
- final String localhost = "127.0.0.1";
-
- final String virtualGateway = "10.10.10.1";
- final String virtualIP = "10.10.10.2";
- final String virtualNetMask = "255.255.255.0";
- final String dummyDNS = "8.8.8.8"; //this is intercepted by the tun2socks library, but we must put in a valid DNS to start
- final String defaultRoute = "0.0.0.0";
-
- final String localSocks = localhost + ':' + mTorSocks;
-
- builder.setMtu(VPN_MTU);
- builder.addAddress(virtualGateway, 32);
-
- builder.setSession(vpnName);
-
- //route all traffic through VPN (we might offer country specific exclude lists in the future)
- builder.addRoute(defaultRoute, 0);
-
- builder.addDnsServer(dummyDNS);
- builder.addRoute(dummyDNS, 32);
-
- //handle ipv6
- //builder.addAddress("fdfe:dcba:9876::1", 126);
- //builder.addRoute("::", 0);
-
- if (mIsLollipop)
- doLollipopAppRouting(builder);
-
- // https://developer.android.com/reference/android/net/VpnService.Builder#setMetered(boolean)
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
- builder.setMetered(false);
- }
-
- // Create a new interface using the builder and save the parameters.
- ParcelFileDescriptor newInterface = builder.setSession(mSessionName)
- .setConfigureIntent(null) // previously this was set to a null member variable
- .establish();
-
- if (mInterface != null) {
- Log.d(TAG, "Stopping existing VPN interface");
- mInterface.close();
- mInterface = null;
- }
-
- mInterface = newInterface;
-
- isRestart = false;
-
- //start PDNSD daemon pointing to actual DNS
- if (filePdnsd != null) {
-
- pdnsdPort++;
- startDNS(filePdnsd.getCanonicalPath(), localhost, mTorDns, virtualGateway, pdnsdPort);
- final boolean localDnsTransparentProxy = true;
-
- Tun2Socks.Start(mService, mInterface, VPN_MTU, virtualIP, virtualNetMask, localSocks, virtualGateway + ":" + pdnsdPort, localDnsTransparentProxy);
- }
-
- } catch (Exception e) {
- Log.d(TAG, "tun2Socks has stopped", e);
- }
- }
-
- };
-
- mThreadVPN.start();
-
- }
-
- @TargetApi(Build.VERSION_CODES.LOLLIPOP)
- private void doLollipopAppRouting(VpnService.Builder builder) throws NameNotFoundException {
- SharedPreferences prefs = Prefs.getSharedPrefs(mService.getApplicationContext());
- ArrayList apps = TorifiedApp.getApps(mService, prefs);
-
-
- boolean perAppEnabled = false;
-
- for (TorifiedApp app : apps) {
- if (app.isTorified() && (!app.getPackageName().equals(mService.getPackageName()))) {
- if (prefs.getBoolean(app.getPackageName() + OrbotConstants.APP_TOR_KEY, true)) {
-
- builder.addAllowedApplication(app.getPackageName());
-
- }
-
- perAppEnabled = true;
-
- }
- }
-
- if (!perAppEnabled)
- builder.addDisallowedApplication(mService.getPackageName());
-
- }
-
- private void startDNS(String pdnsPath, String torDnsHost, int torDnsPort, String pdnsdHost, int pdnsdPort) throws IOException, TimeoutException {
-
- File fileConf = makePdnsdConf(mService, mService.getFilesDir(), torDnsHost, torDnsPort, pdnsdHost, pdnsdPort);
-
- String[] cmdString = {pdnsPath, "-c", fileConf.toString(), "-g", "-v2"};
- ProcessBuilder pb = new ProcessBuilder(cmdString);
- pb.redirectErrorStream(true);
- Process proc = pb.start();
- try {
- proc.waitFor();
- } catch (Exception e) {
- }
-
- Log.i(TAG, "PDNSD: " + proc.exitValue());
-
- if (proc.exitValue() != 0) {
- BufferedReader br = new BufferedReader(new InputStreamReader(proc.getInputStream()));
-
- String line;
- while ((line = br.readLine()) != null) {
- Log.d(TAG, "pdnsd: " + line);
- }
- }
-
-
- }
-
- private void stopDns() {
- if (filePdnsPid != null && filePdnsPid.exists()) {
- ArrayList lines = new ArrayList<>();
- try {
- BufferedReader reader = new BufferedReader(new FileReader(filePdnsPid));
-
- String line = null;
- while ((line = reader.readLine())!= null)
- lines.add(line);
-
- String dnsPid = lines.get(0);
- VpnUtils.killProcess(dnsPid, "");
- filePdnsPid.delete();
- filePdnsPid = null;
- } catch (Exception e) {
- Log.e("OrbotVPN", "error killing dns process", e);
- }
- }
- }
-
- public boolean isStarted() {
- return isStarted;
- }
-}
diff --git a/orbotmanager/src/main/java/org/torproject/android/proxy/vpn/TorifiedApp.java b/orbotmanager/src/main/java/org/torproject/android/proxy/vpn/TorifiedApp.java
deleted file mode 100644
index a144cd33..00000000
--- a/orbotmanager/src/main/java/org/torproject/android/proxy/vpn/TorifiedApp.java
+++ /dev/null
@@ -1,260 +0,0 @@
-package org.torproject.android.proxy.vpn;
-
-import android.Manifest;
-import android.content.Context;
-import android.content.SharedPreferences;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageInfo;
-import android.content.pm.PackageManager;
-import android.graphics.drawable.Drawable;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.List;
-import java.util.StringTokenizer;
-
-import static org.torproject.android.proxy.vpn.VpnPrefs.PREFS_KEY_TORIFIED;
-
-public class TorifiedApp implements Comparable {
-
- private boolean enabled;
- private int uid;
- private String username;
- private String procname;
- private String name;
- private Drawable icon;
- private String packageName;
-
- private boolean torified = false;
- private boolean usesInternet = false;
- private int[] enabledPorts;
-
- public static ArrayList getApps(Context context, SharedPreferences prefs) {
-
- String tordAppString = prefs.getString(PREFS_KEY_TORIFIED, "");
- String[] tordApps;
-
- StringTokenizer st = new StringTokenizer(tordAppString, "|");
- tordApps = new String[st.countTokens()];
- int tordIdx = 0;
- while (st.hasMoreTokens()) {
- tordApps[tordIdx++] = st.nextToken();
- }
-
- Arrays.sort(tordApps);
-
- //else load the apps up
- PackageManager pMgr = context.getPackageManager();
-
- List lAppInfo = pMgr.getInstalledApplications(0);
-
- Iterator itAppInfo = lAppInfo.iterator();
-
- ArrayList apps = new ArrayList<>();
-
- ApplicationInfo aInfo;
-
- int appIdx = 0;
- TorifiedApp app;
-
- while (itAppInfo.hasNext()) {
- aInfo = itAppInfo.next();
-
- app = new TorifiedApp();
-
- try {
- PackageInfo pInfo = pMgr.getPackageInfo(aInfo.packageName, PackageManager.GET_PERMISSIONS);
-
- if (pInfo != null && pInfo.requestedPermissions != null) {
- for (String permInfo : pInfo.requestedPermissions) {
- if (permInfo.equals(Manifest.permission.INTERNET)) {
- app.setUsesInternet(true);
-
- }
- }
-
- }
-
-
- } catch (Exception e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
-
- if ((aInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 1) {
- //System app
- app.setUsesInternet(true);
- }
-
-
- if (!app.usesInternet())
- continue;
- else {
- apps.add(app);
- }
-
-
- app.setEnabled(aInfo.enabled);
- app.setUid(aInfo.uid);
- app.setUsername(pMgr.getNameForUid(app.getUid()));
- app.setProcname(aInfo.processName);
- app.setPackageName(aInfo.packageName);
-
- try {
- app.setName(pMgr.getApplicationLabel(aInfo).toString());
- } catch (Exception e) {
- app.setName(aInfo.packageName);
- }
-
-
- //app.setIcon(pMgr.getApplicationIcon(aInfo));
-
- // check if this application is allowed
- if (Arrays.binarySearch(tordApps, app.getUsername()) >= 0) {
- app.setTorified(true);
- } else {
- app.setTorified(false);
- }
-
- appIdx++;
- }
-
- Collections.sort(apps);
-
- return apps;
- }
-
- public boolean usesInternet() {
- return usesInternet;
- }
-
- public void setUsesInternet(boolean usesInternet) {
- this.usesInternet = usesInternet;
- }
-
- /**
- * @return the torified
- */
- public boolean isTorified() {
- return torified;
- }
-
- /**
- * @param torified the torified to set
- */
- public void setTorified(boolean torified) {
- this.torified = torified;
- }
-
- /**
- * @return the enabledPorts
- */
- public int[] getEnabledPorts() {
- return enabledPorts;
- }
-
- /**
- * @param enabledPorts the enabledPorts to set
- */
- public void setEnabledPorts(int[] enabledPorts) {
- this.enabledPorts = enabledPorts;
- }
-
- /**
- * @return the enabled
- */
- public boolean isEnabled() {
- return enabled;
- }
-
- /**
- * @param enabled the enabled to set
- */
- public void setEnabled(boolean enabled) {
- this.enabled = enabled;
- }
-
- /**
- * @return the uid
- */
- public int getUid() {
- return uid;
- }
-
- /**
- * @param uid the uid to set
- */
- public void setUid(int uid) {
- this.uid = uid;
- }
-
- /**
- * @return the username
- */
- public String getUsername() {
- return username;
- }
-
- /**
- * @param username the username to set
- */
- public void setUsername(String username) {
- this.username = username;
- }
-
- /**
- * @return the procname
- */
- public String getProcname() {
- return procname;
- }
-
- /**
- * @param procname the procname to set
- */
- public void setProcname(String procname) {
- this.procname = procname;
- }
-
- /**
- * @return the name
- */
- public String getName() {
- return name;
- }
-
- /**
- * @param name the name to set
- */
- public void setName(String name) {
- this.name = name;
- }
-
- public Drawable getIcon() {
- return icon;
- }
-
- public void setIcon(Drawable icon) {
- this.icon = icon;
- }
-
- @Override
- public int compareTo(Object another) {
- return this.toString().compareToIgnoreCase(another.toString());
- }
-
- @Override
- public String toString() {
- return getName();
- }
-
- public String getPackageName() {
- return packageName;
- }
-
- public void setPackageName(String packageName) {
- this.packageName = packageName;
- }
-}
diff --git a/orbotmanager/src/main/java/org/torproject/android/proxy/vpn/Tun2Socks.java b/orbotmanager/src/main/java/org/torproject/android/proxy/vpn/Tun2Socks.java
deleted file mode 100644
index 0d2f0bad..00000000
--- a/orbotmanager/src/main/java/org/torproject/android/proxy/vpn/Tun2Socks.java
+++ /dev/null
@@ -1,173 +0,0 @@
-package org.torproject.android.proxy.vpn;
-
-/*
- * Copyright (c) 2013, Psiphon Inc.
- * All rights reserved.
- *
- * 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 .
- *
- */
-
-import android.annotation.TargetApi;
-import android.content.Context;
-import android.net.ConnectivityManager;
-import android.os.Build;
-import android.os.ParcelFileDescriptor;
-import android.util.Log;
-
-import org.torproject.android.proxy.util.TCPSourceApp;
-
-import java.net.DatagramSocket;
-import java.net.InetSocketAddress;
-import java.net.Socket;
-import java.util.HashMap;
-
-import static android.content.Context.CONNECTIVITY_SERVICE;
-
-public class Tun2Socks {
-
- private static final String TAG = Tun2Socks.class.getSimpleName();
- private static final boolean LOGD = true;
-
- private static ParcelFileDescriptor mVpnInterfaceFileDescriptor;
- private static int mVpnInterfaceMTU;
- private static String mVpnIpAddress;
- private static String mVpnNetMask;
- private static String mSocksServerAddress;
- private static String mUdpgwServerAddress;
- private static boolean mUdpgwTransparentDNS;
- private static HashMap mAppUidBlacklist = new HashMap<>();
-
- static {
- System.loadLibrary("tun2socks");
- }
-
- public static void init() {
- }
- // Note: this class isn't a singleton, but you can't run more
- // than one instance due to the use of global state (the lwip
- // module, etc.) in the native code.
-
- public static void Start(
- Context context,
- ParcelFileDescriptor vpnInterfaceFileDescriptor,
- int vpnInterfaceMTU,
- String vpnIpAddress,
- String vpnNetMask,
- String socksServerAddress,
- String udpgwServerAddress,
- boolean udpgwTransparentDNS) {
-
- mVpnInterfaceFileDescriptor = vpnInterfaceFileDescriptor;
- mVpnInterfaceMTU = vpnInterfaceMTU;
- mVpnIpAddress = vpnIpAddress;
- mVpnNetMask = vpnNetMask;
- mSocksServerAddress = socksServerAddress;
- mUdpgwServerAddress = udpgwServerAddress;
- mUdpgwTransparentDNS = udpgwTransparentDNS;
-
- if (mVpnInterfaceFileDescriptor != null)
- runTun2Socks(
- mVpnInterfaceFileDescriptor.detachFd(),
- mVpnInterfaceMTU,
- mVpnIpAddress,
- mVpnNetMask,
- mSocksServerAddress,
- mUdpgwServerAddress,
- mUdpgwTransparentDNS ? 1 : 0);
- }
-
- public static void Stop() {
-
- terminateTun2Socks();
-
- }
-
- public static void logTun2Socks(
- String level,
- String channel,
- String msg) {
- String logMsg = level + "(" + channel + "): " + msg;
- if (0 == level.compareTo("ERROR")) {
- Log.e(TAG, logMsg);
- } else {
- if (LOGD) Log.d(TAG, logMsg);
- }
- }
-
- private native static int runTun2Socks(
- int vpnInterfaceFileDescriptor,
- int vpnInterfaceMTU,
- String vpnIpAddress,
- String vpnNetMask,
- String socksServerAddress,
- String udpgwServerAddress,
- int udpgwTransparentDNS);
-
- private native static void terminateTun2Socks();
-
- public static boolean checkIsAllowed(Context context, int protocol, String sourceAddr, int sourcePort, String destAddr, int destPort) {
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
- return isAllowedQ(context, protocol, sourceAddr, sourcePort, destAddr, destPort);
- } else
- return isAllowed(context, protocol, sourceAddr, sourcePort, destAddr, destPort);
- }
-
- public static boolean isAllowed(Context context, int protocol, String sourceAddr, int sourcePort, String destAddr, int destPort) {
-
- TCPSourceApp.AppDescriptor aInfo = TCPSourceApp.getApplicationInfo(context, sourceAddr, sourcePort, destAddr, destPort);
-
- if (aInfo != null) {
- int uid = aInfo.getUid();
- return mAppUidBlacklist.containsKey(uid);
- } else
- return true;
- }
-
- @TargetApi(Build.VERSION_CODES.Q)
- public static boolean isAllowedQ(Context context, int protocol, String sourceAddr, int sourcePort, String destAddr, int destPort) {
- ConnectivityManager cm = (ConnectivityManager) context.getSystemService(CONNECTIVITY_SERVICE);
- if (cm == null)
- return false;
-
- InetSocketAddress local = new InetSocketAddress(sourceAddr, sourcePort);
- InetSocketAddress remote = new InetSocketAddress(destAddr, destPort);
-
- int uid = cm.getConnectionOwnerUid(protocol, local, remote);
- return mAppUidBlacklist.containsKey(uid);
- }
-
- public static void setBlacklist(HashMap appUidBlacklist) {
- mAppUidBlacklist = appUidBlacklist;
- }
-
- public static void clearBlacklist() {
- mAppUidBlacklist.clear();
- }
-
- public static void addToBlacklist(int uid, String pkgId) {
- mAppUidBlacklist.put(uid, pkgId);
- }
-
- public static void removeFromBlacklist(int uid) {
- mAppUidBlacklist.remove(uid);
- }
-
- public interface IProtectSocket {
- boolean doVpnProtect(Socket socket);
-
- boolean doVpnProtect(DatagramSocket socket);
- }
-
-}
\ No newline at end of file
diff --git a/orbotmanager/src/main/java/org/torproject/android/proxy/vpn/VpnPrefs.java b/orbotmanager/src/main/java/org/torproject/android/proxy/vpn/VpnPrefs.java
deleted file mode 100644
index 135ff967..00000000
--- a/orbotmanager/src/main/java/org/torproject/android/proxy/vpn/VpnPrefs.java
+++ /dev/null
@@ -1,8 +0,0 @@
-package org.torproject.android.proxy.vpn;
-
-public interface VpnPrefs {
-
- String PREFS_DNS_PORT = "PREFS_DNS_PORT";
-
- String PREFS_KEY_TORIFIED = "PrefTord";
-}
diff --git a/orbotmanager/src/main/java/org/torproject/android/proxy/vpn/VpnUtils.java b/orbotmanager/src/main/java/org/torproject/android/proxy/vpn/VpnUtils.java
deleted file mode 100644
index 0ce7e5ae..00000000
--- a/orbotmanager/src/main/java/org/torproject/android/proxy/vpn/VpnUtils.java
+++ /dev/null
@@ -1,136 +0,0 @@
-package org.torproject.android.proxy.vpn;
-
-import android.util.Log;
-
-import org.apache.commons.io.IOUtils;
-
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.util.List;
-
-import static java.lang.Runtime.getRuntime;
-
-public class VpnUtils {
-
- public static int findProcessId(String command) throws IOException {
-
- String[] cmds = {"ps -ef", "ps -A", "toolbox ps"};
-
- for (int i = 0; i < cmds.length; i++) {
- Process procPs = getRuntime().exec(cmds[i]);
-
- BufferedReader reader = new BufferedReader(new InputStreamReader(procPs.getInputStream()));
-
- String line;
- while ((line = reader.readLine()) != null) {
- if (!line.contains("PID") && line.contains(command)) {
- String[] lineParts = line.split("\\s+");
- try {
- return Integer.parseInt(lineParts[1]); //for most devices it is the second
- } catch (NumberFormatException e) {
- return Integer.parseInt(lineParts[0]); //but for samsungs it is the first
- } finally {
- try {
- procPs.destroy();
- } catch (Exception e) {
- }
- }
- }
- }
- }
-
- return -1;
- }
-
- public static void killProcess(File fileProcBin) throws Exception {
- killProcess(fileProcBin, "-9"); // this is -KILL
- }
-
- public static int killProcess(File fileProcBin, String signal) throws Exception {
-
- int procId = -1;
- int killAttempts = 0;
-
- while ((procId = findProcessId(fileProcBin.getName())) != -1) {
- killAttempts++;
- String pidString = String.valueOf(procId);
- boolean itBeDead = killProcess(pidString, signal);
-
- if (!itBeDead) {
-
- String[] cmds = {"", "busybox ", "toolbox "};
-
- for (int i = 0; i < cmds.length; i++) {
-
- Process proc;
-
- try {
- proc = getRuntime().exec(cmds[i] + "killall " + signal + " " + fileProcBin.getName
- ());
- int exitValue = proc.waitFor();
- if (exitValue == 0)
- break;
-
- } catch (IOException ioe) {
- }
- try {
- proc = getRuntime().exec(cmds[i] + "killall " + signal + " " + fileProcBin.getCanonicalPath());
- int exitValue = proc.waitFor();
- if (exitValue == 0)
- break;
-
- } catch (IOException ioe) {
- }
- }
-
-
- try {
- Thread.sleep(1000);
- } catch (InterruptedException e) {
- // ignored
- }
-
- }
-
- if (killAttempts > 4)
- throw new Exception("Cannot kill: " + fileProcBin.getAbsolutePath());
- }
-
- return procId;
- }
-
- public static boolean killProcess(String pidString, String signal) throws Exception {
-
- String[] cmds = {"", "toolbox ", "busybox "};
-
- for (int i = 0; i < cmds.length; i++) {
- try {
- Process proc = getRuntime().exec(cmds[i] + "kill " + signal + " " + pidString);
- int exitVal = proc.waitFor();
- List lineErrors = IOUtils.readLines(proc.getErrorStream());
- List lineInputs = IOUtils.readLines(proc.getInputStream());
-
- if (exitVal != 0) {
- Log.d("Orbot.killProcess", "exit=" + exitVal);
- for (String line : lineErrors)
- Log.d("Orbot.killProcess", line);
-
- for (String line : lineInputs)
- Log.d("Orbot.killProcess", line);
-
- } else {
- //it worked, let's exit
- return true;
- }
-
-
- } catch (IOException ioe) {
- Log.e("Orbot.killprcess", "error killing process: " + pidString, ioe);
- }
- }
-
- return false;
- }
-}
diff --git a/orbotmanager/src/main/java/org/torproject/android/proxy/OrbotService.java b/orbotmanager/src/main/java/org/torproject/android/service/OrbotService.java
similarity index 64%
rename from orbotmanager/src/main/java/org/torproject/android/proxy/OrbotService.java
rename to orbotmanager/src/main/java/org/torproject/android/service/OrbotService.java
index 97474b27..39f1a6a9 100644
--- a/orbotmanager/src/main/java/org/torproject/android/proxy/OrbotService.java
+++ b/orbotmanager/src/main/java/org/torproject/android/service/OrbotService.java
@@ -5,7 +5,7 @@
* Copyright (C) 2009-2010 Rodrigo Zechin Rosauro
*/
-package org.torproject.android.proxy;
+package org.torproject.android.service;
import android.annotation.SuppressLint;
import android.app.Application;
@@ -15,12 +15,14 @@ import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.BroadcastReceiver;
+import android.content.ComponentName;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
import android.content.ContextWrapper;
import android.content.Intent;
import android.content.IntentFilter;
+import android.content.ServiceConnection;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.database.Cursor;
@@ -30,28 +32,16 @@ import android.net.Uri;
import android.net.VpnService;
import android.os.Build;
import android.os.Handler;
+import android.os.HandlerThread;
import android.os.IBinder;
+import android.os.Looper;
import android.provider.BaseColumns;
import android.text.TextUtils;
import android.util.Log;
-import androidx.annotation.RequiresApi;
-import androidx.core.app.NotificationCompat;
-import androidx.core.app.NotificationManagerCompat;
-import androidx.localbroadcastmanager.content.LocalBroadcastManager;
-
-import com.jaredrummler.android.shell.CommandResult;
-
-import net.freehaven.tor.control.ConfigEntry;
import net.freehaven.tor.control.TorControlCommands;
import net.freehaven.tor.control.TorControlConnection;
-import org.apache.commons.io.FileUtils;
-import org.torproject.android.service.R;
-import org.torproject.android.proxy.wrapper.localHelperMethod;
-import org.torproject.android.proxy.wrapper.logRowModel;
-import org.torproject.android.proxy.wrapper.orbotLocalConstants;
-import org.torproject.android.service.util.CustomShell;
import org.torproject.android.service.util.CustomTorResourceInstaller;
import org.torproject.android.service.util.DummyActivity;
import org.torproject.android.service.util.Prefs;
@@ -59,61 +49,95 @@ import org.torproject.android.service.util.TorServiceUtils;
import org.torproject.android.service.util.Utils;
import org.torproject.android.service.vpn.OrbotVpnManager;
import org.torproject.android.service.vpn.VpnPrefs;
+import org.torproject.android.service.wrapper.localHelperMethod;
+import org.torproject.android.service.wrapper.logRowModel;
+import org.torproject.android.service.wrapper.orbotLocalConstants;
+import org.torproject.jni.TorService;
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
-import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
-import java.io.FileReader;
+import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.io.PrintWriter;
-import java.io.Reader;
-import java.io.StringReader;
-import java.net.Socket;
+import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
-import java.util.Date;
import java.util.HashMap;
-import java.util.Iterator;
import java.util.List;
+import java.util.Locale;
+import java.util.Objects;
import java.util.Random;
import java.util.StringTokenizer;
+import java.util.UUID;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeoutException;
-import info.pluggabletransports.dispatch.util.TransportListener;
-import info.pluggabletransports.dispatch.util.TransportManager;
+import IPtProxy.IPtProxy;
+import androidx.annotation.RequiresApi;
+import androidx.core.app.NotificationCompat;
+import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
public class OrbotService extends VpnService implements TorServiceConstants, OrbotConstants {
- public final static String BINARY_TOR_VERSION = org.torproject.android.binary.TorServiceConstants.BINARY_TOR_VERSION;
- private final static int CONTROL_SOCKET_TIMEOUT = 60000;
+ public final static String BINARY_TOR_VERSION = TorService.VERSION_NAME;
+
static final int NOTIFY_ID = 1;
private static final int ERROR_NOTIFY_ID = 3;
private static final int HS_NOTIFY_ID = 4;
- private static final Uri HS_CONTENT_URI = Uri.parse("content://org.torproject.android.ui.hiddenservices.providers/hs");
+ private static final Uri V2_HS_CONTENT_URI = Uri.parse("content://org.torproject.android.ui.hiddenservices.providers/hs");
+ private static final Uri V3_ONION_SERVICES_CONTENT_URI = Uri.parse("content://org.torproject.android.ui.v3onionservice/v3");
private static final Uri COOKIE_CONTENT_URI = Uri.parse("content://org.torproject.android.ui.hiddenservices.providers.cookie/cookie");
+ private static final Uri V3_CLIENT_AUTH_URI = Uri.parse("content://org.torproject.android.ui.v3onionservice.clientauth/v3auth");
private final static String NOTIFICATION_CHANNEL_ID = "orbot_channel_1";
- private final static String RESET_STRING = "=\"\"";
+ private static final String[] LEGACY_V2_ONION_SERVICE_PROJECTION = new String[]{
+ OnionService._ID,
+ OnionService.NAME,
+ OnionService.DOMAIN,
+ OnionService.PORT,
+ OnionService.AUTH_COOKIE,
+ OnionService.AUTH_COOKIE_VALUE,
+ OnionService.ONION_PORT,
+ OnionService.ENABLED,
+ OnionService.PATH};
+ private static final String[] V3_ONION_SERVICE_PROJECTION = new String[]{
+ OnionService._ID,
+ OnionService.NAME,
+ OnionService.DOMAIN,
+ OnionService.PORT,
+ OnionService.ONION_PORT,
+ OnionService.ENABLED,
+ OnionService.PATH
+ };
+ private static final String[] LEGACY_COOKIE_PROJECTION = new String[]{
+ ClientCookie._ID,
+ ClientCookie.DOMAIN,
+ ClientCookie.AUTH_COOKIE_VALUE,
+ ClientCookie.ENABLED};
+ private static final String[] V3_CLIENT_AUTH_PROJECTION = new String[]{
+ V3ClientAuth._ID,
+ V3ClientAuth.DOMAIN,
+ V3ClientAuth.HASH,
+ V3ClientAuth.ENABLED
+ };
+
+ public boolean isAppClosed = false;
public static int mPortSOCKS = -1;
public static int mPortHTTP = -1;
public static int mPortDns = TOR_DNS_PORT_DEFAULT;
public static int mPortTrans = TOR_TRANSPROXY_PORT_DEFAULT;
public static File appBinHome;
public static File appCacheHome;
- public static File fileTor;
- public static File fileObfsclient;
- public boolean isAppClosed = false;
- public static File fileTorRc;
+ private final ExecutorService mExecutor = Executors.newCachedThreadPool();
boolean mIsLollipop = Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP;
TorEventHandler mEventHandler;
OrbotVpnManager mVpnManager;
@@ -123,30 +147,14 @@ public class OrbotService extends VpnService implements TorServiceConstants, Orb
ActionBroadcastReceiver mActionBroadcastReceiver;
private String mCurrentStatus = STATUS_OFF;
private TorControlConnection conn = null;
- private int mLastProcessId = -1;
- private ArrayList configBuffer = null;
- private ArrayList resetBuffer = null;
- private File fileControlPort, filePid;
+ private ServiceConnection torServiceConnection;
+ private TorService torService;
+ private boolean shouldUnbindTorService;
private NotificationManager mNotificationManager = null;
private NotificationCompat.Builder mNotifyBuilder;
private boolean mNotificationShowing = false;
- private final ExecutorService mExecutor = Executors.newFixedThreadPool(3);
- private File mHSBasePath;
+ private File mHSBasePath, mV3OnionBasePath, mV3AuthBasePath;
private ArrayList alBridges = null;
- private final String[] hsProjection = new String[]{
- HiddenService._ID,
- HiddenService.NAME,
- HiddenService.DOMAIN,
- HiddenService.PORT,
- HiddenService.AUTH_COOKIE,
- HiddenService.AUTH_COOKIE_VALUE,
- HiddenService.ONION_PORT,
- HiddenService.ENABLED};
- private final String[] cookieProjection = new String[]{
- ClientCookie._ID,
- ClientCookie.DOMAIN,
- ClientCookie.AUTH_COOKIE_VALUE,
- ClientCookie.ENABLED};
/**
* @param bridgeList bridges that were manually entered into Orbot settings
@@ -159,19 +167,13 @@ public class OrbotService extends VpnService implements TorServiceConstants, Orb
}
public void debug(String msg) {
-
Log.d(OrbotConstants.TAG, msg);
if (Prefs.useDebugLogging()) {
sendCallbackLogMessage(msg);
-
}
}
- public int getNotifyId() {
- return NOTIFY_ID;
- }
-
public void logException(String msg, Exception e) {
if (Prefs.useDebugLogging()) {
Log.e(OrbotConstants.TAG, msg, e);
@@ -186,34 +188,13 @@ public class OrbotService extends VpnService implements TorServiceConstants, Orb
}
private void showConnectedToTorNetworkNotification() {
- showToolbarNotification(getString(R.string.status_activated), NOTIFY_ID, R.drawable.ic_stat_tor);
+ showToolbarNotification(getString(R.string.status_activated), NOTIFY_ID, R.mipmap.ic_stat_tor_logo);
}
- private boolean findExistingTorDaemon() {
- try {
- mLastProcessId = initControlConnection(3, true);
-
- if (mLastProcessId != -1 && conn != null) {
- sendCallbackLogMessage(getString(R.string.found_existing_tor_process));
- sendCallbackStatus(STATUS_ON);
- showConnectedToTorNetworkNotification();
- return true;
- }
- } catch (Exception e) {
- Log.i("sda","ASd");
- }
- return false;
- }
-
- /* (non-Javadoc)
- * @see android.app.Service#onLowMemory()
- */
@Override
public void onLowMemory() {
super.onLowMemory();
-
logNotice("Low Memory Warning!");
-
}
private void clearNotifications() {
@@ -223,7 +204,6 @@ public class OrbotService extends VpnService implements TorServiceConstants, Orb
if (mEventHandler != null)
mEventHandler.getNodes().clear();
- NotificationManagerCompat.from(this).cancelAll();
mNotificationShowing = false;
}
@@ -265,7 +245,7 @@ public class OrbotService extends VpnService implements TorServiceConstants, Orb
mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
mNotifyBuilder = new NotificationCompat.Builder(this, NOTIFICATION_CHANNEL_ID)
.setContentTitle(getString(R.string.app_name))
- .setSmallIcon(R.drawable.ic_stat_tor)
+ .setSmallIcon(R.mipmap.ic_stat_tor_logo)
.setContentIntent(pendIntent)
.setCategory(Notification.CATEGORY_SERVICE)
.setOngoing(Prefs.persistNotifications());
@@ -299,22 +279,20 @@ public class OrbotService extends VpnService implements TorServiceConstants, Orb
} else {
mNotificationManager.notify(NOTIFY_ID, notification);
}
- }catch (Exception ignored){}
+ }catch (Exception ex){
+ Log.i("sad","asd");
+ }
mNotificationShowing = true;
mToolbarUpdating = false;
}
- /* (non-Javadoc)
- * @see android.app.Service#onStart(android.content.Intent, int)
- */
public int onStartCommand(Intent intent, int flags, int startId) {
+ showToolbarNotification("", NOTIFY_ID, R.mipmap.ic_stat_tor_logo);
+
self = this;
-
- showToolbarNotification("", NOTIFY_ID, R.drawable.ic_stat_tor);
-
if (intent != null)
- exec(new IncomingIntentRouter(intent));
+ mExecutor.execute(new IncomingIntentRouter(intent));
else
Log.d(OrbotConstants.TAG, "Got null onStartCommand() intent");
@@ -342,6 +320,7 @@ public class OrbotService extends VpnService implements TorServiceConstants, Orb
unregisterReceiver(mNetworkStateReceiver);
unregisterReceiver(mActionBroadcastReceiver);
}catch (Exception ex){
+ Log.i("sad","asd");
ex.printStackTrace();
}
@@ -363,33 +342,6 @@ public class OrbotService extends VpnService implements TorServiceConstants, Orb
super.onDestroy();
}
-
- private void stopTor() {
- new Thread(this::stopTorAsync).start();
- }
-
- private void stopTorAsync() {
- Log.i("OrbotService", "stopTor");
- try {
- sendCallbackStatus(STATUS_STOPPING);
- sendCallbackLogMessage(getString(R.string.status_shutting_down));
-
- killAllDaemons();
-
- //stop the foreground priority and make sure to remove the persistant notification
- stopForeground(true);
-
- sendCallbackLogMessage(getString(R.string.status_disabled));
- } catch (Exception e) {
- logNotice("An error occured stopping Tor: " + e.getMessage());
- sendCallbackLogMessage(getString(R.string.something_bad_happened));
- }
- clearNotifications();
- sendCallbackStatus(STATUS_OFF);
-
-
- }
-
private void killAllDaemons() throws Exception {
if (conn != null) {
@@ -407,24 +359,143 @@ public class OrbotService extends VpnService implements TorServiceConstants, Orb
}
}
- private void requestTorRereadConfig() {
- try {
- if (conn != null)
- conn.signal("HUP");
+ private void stopTorAsync() {
- } catch (IOException e) {
- e.printStackTrace();
+ Log.i("OrbotService", "stopTor");
+ try {
+ sendCallbackStatus(STATUS_STOPPING);
+ sendCallbackLogMessage(getString(R.string.status_shutting_down));
+
+ if (useIPtObfsMeekProxy())
+ IPtProxy.stopObfs4Proxy();
+
+ if (useIPtSnowflakeProxy())
+ IPtProxy.stopSnowflake();
+
+ stopTor();
+
+ //stop the foreground priority and make sure to remove the persistant notification
+ stopForeground(true);
+
+ sendCallbackLogMessage(getString(R.string.status_disabled));
+ } catch (Exception e) {
+ logNotice("An error occured stopping Tor: " + e.getMessage());
+ sendCallbackLogMessage(getString(R.string.something_bad_happened));
}
- /**
- // if that fails, try again using native utils
- try {
- killProcess(fileTor, "-1"); // this is -HUP
- } catch (Exception e) {
- e.printStackTrace();
- }**/
+ clearNotifications();
+ sendCallbackStatus(STATUS_OFF);
}
- public void logNotice(String msg) {
+ private void stopTorOnError(String message) {
+ stopTorAsync();
+ showToolbarNotification(
+ getString(R.string.unable_to_start_tor) + ": " + message,
+ ERROR_NOTIFY_ID, R.drawable.ic_stat_notifyerr);
+ }
+
+ private static boolean useIPtObfsMeekProxy() {
+ String bridgeList = Prefs.getBridgesList();
+ return bridgeList.contains("obfs") || bridgeList.contains("meek");
+ }
+
+ private static boolean useIPtSnowflakeProxy() {
+ String bridgeList = Prefs.getBridgesList();
+ return bridgeList.contains("snowflake");
+ }
+
+ private static HashMap mFronts;
+
+ public static void loadCdnFronts (Context context) {
+ if (mFronts == null) {
+ mFronts = new HashMap<>();
+
+ try {
+ BufferedReader reader = new BufferedReader(new InputStreamReader(context.getAssets().open("fronts")));
+ String line;
+ while ((line = reader.readLine())!=null) {
+ String[] front = line.split(" ");
+
+ //add some code to test the connection here
+
+ mFronts.put(front[0],front[1]);
+ }
+ } catch (IOException e) {
+ Log.i("sad","asd");
+ e.printStackTrace();
+ }
+ }
+ }
+
+ public static String getCdnFront(String service) {
+ return mFronts.get(service);
+ }
+
+
+ private void startSnowflakeClient() {
+ //this is using the current, default Tor snowflake infrastructure
+ String target = getCdnFront("snowflake-target");
+ String front = getCdnFront("snowflake-front");
+ String stunServer = getCdnFront("snowflake-stun");
+
+ IPtProxy.startSnowflake(stunServer, target, front,
+ null, true, false, true, 3);
+
+ }
+
+ /*
+ This is to host a snowflake entrance node / bridge
+ */
+ private void runSnowflakeProxy () {
+ int capacity = 3;
+ String broker = "https://snowflake-broker.bamsoftware.com/";
+ String relay = "wss://snowflake.bamsoftware.com/";
+ String stun = "stun:stun.stunprotocol.org:3478";
+ String logFile = null;
+ boolean keepLocalAddresses = true;
+ boolean unsafeLogging = false;
+ IPtProxy.startSnowflakeProxy(capacity, broker, relay, stun, logFile, keepLocalAddresses, unsafeLogging);
+ }
+
+ private void stopSnowflakeProxy () {
+ IPtProxy.stopSnowflakeProxy();
+ }
+ /**
+ * if someone stops during startup, we may have to wait for the conn port to be setup, so we can properly shutdown tor
+ */
+ private synchronized void stopTor() throws Exception {
+
+ if (conn != null) {
+ logNotice("Using control port to shutdown Tor");
+
+ try {
+ logNotice("sending HALT signal to Tor process");
+ conn.shutdownTor(TorControlCommands.SIGNAL_SHUTDOWN);
+
+ } catch (IOException e) {
+ Log.d(OrbotConstants.TAG, "error shutting down Tor via connection", e);
+ }
+
+ if (shouldUnbindTorService) {
+ unbindService(torServiceConnection);
+ shouldUnbindTorService = false;
+ }
+
+ conn = null;
+ }
+ }
+
+ private void requestTorRereadConfig() {
+ try {
+ if (conn != null) {
+ conn.signal(TorControlCommands.SIGNAL_RELOAD);
+ }
+ } catch (IOException e) {
+ Log.i("sad","asd");
+ e.printStackTrace();
+ }
+ }
+
+ protected void logNotice(String msg) {
if (msg != null && msg.trim().length() > 0) {
if (Prefs.useDebugLogging())
Log.d(OrbotConstants.TAG, msg);
@@ -453,32 +524,17 @@ public class OrbotService extends VpnService implements TorServiceConstants, Orb
if (!appCacheHome.exists())
appCacheHome.mkdirs();
-
- debug("listing files in DataDirectory: " + appCacheHome.getAbsolutePath());
- Iterator files = FileUtils.iterateFiles(appCacheHome, null, true);
- while (files.hasNext()) {
- File fileNext = files.next();
- debug(fileNext.getAbsolutePath()
- + " length=" + fileNext.length()
- + " rw=" + fileNext.canRead() + "/" + fileNext.canWrite()
- + " lastMod=" + new Date(fileNext.lastModified()).toLocaleString()
-
- );
- }
-
- fileTorRc = new File(appBinHome, TORRC_ASSET_KEY);
- fileControlPort = new File(getFilesDir(), TOR_CONTROL_PORT_FILE);
- filePid = new File(getFilesDir(), TOR_PID_FILE);
-
- mHSBasePath = new File(
- getFilesDir().getAbsolutePath(),
- TorServiceConstants.HIDDEN_SERVICES_DIR
- );
-
+ mHSBasePath = new File(getFilesDir().getAbsolutePath(), TorServiceConstants.HIDDEN_SERVICES_DIR);
if (!mHSBasePath.isDirectory())
mHSBasePath.mkdirs();
- mEventHandler = new TorEventHandler(this);
+ mV3OnionBasePath = new File(getFilesDir().getAbsolutePath(), TorServiceConstants.ONION_SERVICES_DIR);
+ if (!mV3OnionBasePath.isDirectory())
+ mV3OnionBasePath.mkdirs();
+
+ mV3AuthBasePath = new File(getFilesDir().getAbsolutePath(), TorServiceConstants.V3_CLIENT_AUTH_DIR);
+ if (!mV3AuthBasePath.isDirectory())
+ mV3AuthBasePath.mkdirs();
if (mNotificationManager == null) {
mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
@@ -497,27 +553,15 @@ public class OrbotService extends VpnService implements TorServiceConstants, Orb
if (Build.VERSION.SDK_INT >= 26)
createNotificationChannel();
- torUpgradeAndConfig();
+ CustomTorResourceInstaller installer = new CustomTorResourceInstaller(this, appBinHome);
+ installer.installGeoIP();
pluggableTransportInstall();
- new Thread(() -> {
- try {
- findExistingTorDaemon();
- } catch (Exception e) {
- Log.e(OrbotConstants.TAG, "error onBind", e);
- logNotice("error finding exiting process: " + e.toString());
- }
+ mVpnManager = new OrbotVpnManager(this);
- }).start();
+ loadCdnFronts(this);
- try {
- mVpnManager = new OrbotVpnManager(this);
- } catch (IOException e) {
- e.printStackTrace();
- } catch (TimeoutException e) {
- e.printStackTrace();
- }
} catch (Exception e) {
//what error here
Log.e(OrbotConstants.TAG, "Error installing Orbot binaries", e);
@@ -527,50 +571,19 @@ public class OrbotService extends VpnService implements TorServiceConstants, Orb
Log.i("OrbotService", "onCreate end");
}
- public String getCurrentStatus() {
+ protected String getCurrentStatus() {
return mCurrentStatus;
}
private boolean pluggableTransportInstall() {
- fileObfsclient = new TransportManager() {
- @Override
- public void startTransportSync(TransportListener transportListener) {
-
- }
- }.installTransport(this, OBFSCLIENT_ASSET_KEY);
-
- if (fileObfsclient != null && fileObfsclient.exists()) {
-
- fileObfsclient.setReadable(true);
- fileObfsclient.setExecutable(true);
- fileObfsclient.setWritable(false);
- fileObfsclient.setWritable(true, true);
-
- return fileObfsclient.canExecute();
- }
-
- return false;
- }
-
- private boolean torUpgradeAndConfig() throws IOException, TimeoutException {
-
- SharedPreferences prefs = Prefs.getSharedPrefs(getApplicationContext());
- String version = prefs.getString(PREF_BINARY_TOR_VERSION_INSTALLED, null);
-
- logNotice("checking binary version: " + version);
-
- CustomTorResourceInstaller installer = new CustomTorResourceInstaller(this, appBinHome);
- logNotice("upgrading binaries to latest version: " + BINARY_TOR_VERSION);
-
- fileTor = installer.installResources();
-
- if (fileTor != null && fileTor.canExecute()) {
- prefs.edit().putString(PREF_BINARY_TOR_VERSION_INSTALLED, BINARY_TOR_VERSION).apply();
-
- fileTorRc = new File(appBinHome, "torrc");//installer.getTorrcFile();
- return fileTorRc.exists();
- }
+ File fileCacheDir = new File(getCacheDir(), "pt");
+ if (!fileCacheDir.exists())
+ //noinspection ResultOfMethodCallIgnored
+ fileCacheDir.mkdir();
+ IPtProxy.setStateLocation(fileCacheDir.getAbsolutePath());
+ String fileTestState = IPtProxy.getStateLocation();
+ debug("IPtProxy state: " + fileTestState);
return false;
}
@@ -581,12 +594,9 @@ public class OrbotService extends VpnService implements TorServiceConstants, Orb
StringBuffer extraLines = new StringBuffer();
extraLines.append("\n");
- extraLines.append("ControlPortWriteToFile").append(' ').append(fileControlPort.getCanonicalPath()).append('\n');
- extraLines.append("PidFile").append(' ').append(filePid.getCanonicalPath()).append('\n');
-
- extraLines.append("RunAsDaemon 1").append('\n');
- extraLines.append("AvoidDiskWrites 1").append('\n');
+ extraLines.append("RunAsDaemon 0").append('\n');
+ extraLines.append("AvoidDiskWrites 0").append('\n');
String socksPortPref = prefs.getString(OrbotConstants.PREF_SOCKS, (TorServiceConstants.SOCKS_PROXY_PORT_DEFAULT));
@@ -677,15 +687,9 @@ public class OrbotService extends VpnService implements TorServiceConstants, Orb
debug("torrc.custom=" + extraLines.toString());
- File fileTorRcCustom = new File(fileTorRc.getAbsolutePath() + ".custom");
- boolean success = updateTorConfigCustom(fileTorRcCustom, extraLines.toString());
-
- if (success && fileTorRcCustom.exists()) {
- logNotice("success.");
- return fileTorRcCustom;
- } else
- return null;
-
+ File fileTorRcCustom = TorService.getTorrc(this);
+ updateTorConfigCustom(fileTorRcCustom, extraLines.toString());
+ return fileTorRcCustom;
}
private String checkPortOrAuto(String portString) {
@@ -699,13 +703,10 @@ public class OrbotService extends VpnService implements TorServiceConstants, Orb
if (isPortUsed) //the specified port is not available, so let Tor find one instead
port++;
}
-
-
return port + "";
}
return portString;
-
}
public boolean updateTorConfigCustom(File fileTorRcCustom, String extraLines) throws IOException, TimeoutException {
@@ -752,39 +753,24 @@ public class OrbotService extends VpnService implements TorServiceConstants, Orb
* The entire process for starting tor and related services is run from this method.
*/
private void startTor() {
-
- String torProcId = null;
-
- try {
- if (conn != null) torProcId = conn.getInfo("process/pid");
- } catch (Exception e) {
- Log.i("sda","ASd");
- }
-
try {
// STATUS_STARTING is set in onCreate()
- if (mCurrentStatus == STATUS_STOPPING) {
+ if (mCurrentStatus.equals(STATUS_STOPPING)) {
// these states should probably be handled better
sendCallbackLogMessage("Ignoring start request, currently " + mCurrentStatus);
return;
- } else if (mCurrentStatus == STATUS_ON && (torProcId != null)) {
+ } else if (mCurrentStatus.equals(STATUS_ON)) {
showConnectedToTorNetworkNotification();
sendCallbackLogMessage("Ignoring start request, already started.");
- // setTorNetworkEnabled (true);
-
return;
}
+ sendCallbackStatus(STATUS_STARTING);
// make sure there are no stray daemons running
- killAllDaemons();
+ stopTor();
- SharedPreferences prefs = Prefs.getSharedPrefs(getApplicationContext());
- String version = prefs.getString(PREF_BINARY_TOR_VERSION_INSTALLED, null);
- logNotice("checking binary version: " + version);
-
- sendCallbackStatus(STATUS_STARTING);
showToolbarNotification(getString(R.string.status_starting_up), NOTIFY_ID, R.drawable.ic_stat_starting_tor_logo);
//sendCallbackLogMessage(getString(R.string.status_starting_up));
//logNotice(getString(R.string.status_starting_up));
@@ -796,62 +782,91 @@ public class OrbotService extends VpnService implements TorServiceConstants, Orb
customEnv.add("TOR_PT_PROXY=socks5://" + OrbotVpnManager.sSocksProxyLocalhost + ":" + OrbotVpnManager.sSocksProxyServerPort);
}
- boolean success = runTorShellCmd();
+ startTorService();
- if (success) {
+ /* if (Prefs.hostOnionServicesEnabled()) {
try {
- updateOnionNames();
+ updateLegacyV2OnionNames();
} catch (SecurityException se) {
- logNotice("unable to upload onion names");
+ logNotice("unable to upload legacy v2 onion names");
}
- }
-
+ try {
+ updateV3OnionNames();
+ } catch (SecurityException se) {
+ logNotice("unable to upload v3 onion names");
+ }
+ } */
} catch (Exception e) {
+ Log.i("sad","asd");
logException("Unable to start Tor: " + e.toString(), e);
- stopTor();
- showToolbarNotification(
- getString(R.string.unable_to_start_tor) + ": " + e.getMessage(),
- ERROR_NOTIFY_ID, R.drawable.ic_stat_notifyerr);
-
+ stopTorOnError(e.getLocalizedMessage());
}
}
- private void updateOnionNames() throws SecurityException {
+
+ private void updateV3OnionNames() throws SecurityException {
+ ContentResolver contentResolver = getApplicationContext().getContentResolver();
+ Cursor onionServices = contentResolver.query(V3_ONION_SERVICES_CONTENT_URI, null, null, null, null);
+ if (onionServices != null) {
+ try {
+ while (onionServices.moveToNext()) {
+ String domain = onionServices.getString(onionServices.getColumnIndex(OnionService.DOMAIN));
+ if (domain == null || TextUtils.isEmpty(domain)) {
+ String path = onionServices.getString(onionServices.getColumnIndex(OnionService.PATH));
+ String v3OnionDirPath = new File(mV3OnionBasePath.getAbsolutePath(), path).getCanonicalPath();
+ File hostname = new File(v3OnionDirPath, "hostname");
+ if (hostname.exists()) {
+ int id = onionServices.getInt(onionServices.getColumnIndex(OnionService._ID));
+ domain = Utils.readString(new FileInputStream(hostname)).trim();
+ ContentValues fields = new ContentValues();
+ fields.put(OnionService.DOMAIN, domain);
+ contentResolver.update(V3_ONION_SERVICES_CONTENT_URI, fields, OnionService._ID + "=" + id, null);
+ }
+ }
+
+ }
+ } catch (Exception e) {
+ Log.i("sad","asd");
+ e.printStackTrace();
+ }
+ onionServices.close();
+ }
+ }
+
+ private void updateLegacyV2OnionNames() throws SecurityException {
// Tor is running, update new .onion names at db
ContentResolver mCR = getApplicationContext().getContentResolver();
- Cursor hidden_services = mCR.query(HS_CONTENT_URI, hsProjection, null, null, null);
+ Cursor hidden_services = mCR.query(V2_HS_CONTENT_URI, LEGACY_V2_ONION_SERVICE_PROJECTION, null, null, null);
if (hidden_services != null) {
try {
while (hidden_services.moveToNext()) {
- String HSDomain = hidden_services.getString(hidden_services.getColumnIndex(HiddenService.DOMAIN));
- Integer HSLocalPort = hidden_services.getInt(hidden_services.getColumnIndex(HiddenService.PORT));
- Integer HSAuthCookie = hidden_services.getInt(hidden_services.getColumnIndex(HiddenService.AUTH_COOKIE));
- String HSAuthCookieValue = hidden_services.getString(hidden_services.getColumnIndex(HiddenService.AUTH_COOKIE_VALUE));
-
+ String HSDomain = hidden_services.getString(hidden_services.getColumnIndex(OnionService.DOMAIN));
+ int HSAuthCookie = hidden_services.getInt(hidden_services.getColumnIndex(OnionService.AUTH_COOKIE));
+ String HSAuthCookieValue = hidden_services.getString(hidden_services.getColumnIndex(OnionService.AUTH_COOKIE_VALUE));
// Update only new domains or restored from backup with auth cookie
if ((HSDomain == null || HSDomain.length() < 1) || (HSAuthCookie == 1 && (HSAuthCookieValue == null || HSAuthCookieValue.length() < 1))) {
- String hsDirPath = new File(mHSBasePath.getAbsolutePath(), "hs" + HSLocalPort).getCanonicalPath();
+ String hsDirPath = new File(mHSBasePath.getAbsolutePath(), hidden_services.getString(hidden_services.getColumnIndex(OnionService.PATH))).getCanonicalPath();
File file = new File(hsDirPath, "hostname");
if (file.exists()) {
ContentValues fields = new ContentValues();
try {
+ int id = hidden_services.getInt(hidden_services.getColumnIndex(OnionService._ID));
String onionHostname = Utils.readString(new FileInputStream(file)).trim();
if (HSAuthCookie == 1) {
String[] aux = onionHostname.split(" ");
onionHostname = aux[0];
- fields.put(HiddenService.AUTH_COOKIE_VALUE, aux[1]);
+ fields.put(OnionService.AUTH_COOKIE_VALUE, aux[1]);
}
- fields.put(HiddenService.DOMAIN, onionHostname);
- mCR.update(HS_CONTENT_URI, fields, "port=" + HSLocalPort, null);
+ fields.put(OnionService.DOMAIN, onionHostname);
+ mCR.update(V2_HS_CONTENT_URI, fields, OnionService._ID + "=" + id, null);
} catch (FileNotFoundException e) {
logException("unable to read onion hostname file", e);
showToolbarNotification(getString(R.string.unable_to_read_hidden_service_name), HS_NOTIFY_ID, R.drawable.ic_stat_notifyerr);
}
} else {
showToolbarNotification(getString(R.string.unable_to_read_hidden_service_name), HS_NOTIFY_ID, R.drawable.ic_stat_notifyerr);
-
}
}
}
@@ -866,507 +881,135 @@ public class OrbotService extends VpnService implements TorServiceConstants, Orb
}
}
- private boolean runTorShellCmd() throws Exception {
- boolean result = true;
+ private synchronized void startTorService() throws Exception {
+ updateTorConfigCustom(TorService.getDefaultsTorrc(this),
+ "DNSPort 0\n" +
+ "TransPort 0\n" +
+ "DisableNetwork 1\n");
File fileTorrcCustom = updateTorrcCustomFile();
-
- //make sure Tor exists and we can execute it
- if (fileTor == null || (!fileTor.exists()) || (!fileTor.canExecute()))
- return false;
-
- if ((!fileTorRc.exists()) || (!fileTorRc.canRead()))
- return false;
-
if ((!fileTorrcCustom.exists()) || (!fileTorrcCustom.canRead()))
- return false;
+ return;
sendCallbackLogMessage(getString(R.string.status_starting_up));
- String torCmdString = fileTor.getAbsolutePath()
- + " DataDirectory " + appCacheHome.getAbsolutePath()
- + " --defaults-torrc " + fileTorRc.getAbsolutePath()
- + " -f " + fileTorrcCustom.getAbsolutePath();
+ torServiceConnection = new ServiceConnection() {
+ @Override
+ public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
+ torService = ((TorService.LocalBinder) iBinder).getService();
+ try {
+ conn = torService.getTorControlConnection();
+ while (conn == null) {
+ Log.v(TAG, "Waiting for Tor Control Connection...");
+ Thread.sleep(500);
+ conn = torService.getTorControlConnection();
+ }
+ mEventHandler = new TorEventHandler(OrbotService.this);
+ logNotice("adding control port event handler");
+ conn.setEventHandler(mEventHandler);
+ ArrayList events = new ArrayList<>(Arrays.asList(
+ TorControlCommands.EVENT_OR_CONN_STATUS,
+ TorControlCommands.EVENT_CIRCUIT_STATUS,
+ TorControlCommands.EVENT_NOTICE_MSG,
+ TorControlCommands.EVENT_WARN_MSG,
+ TorControlCommands.EVENT_ERR_MSG,
+ TorControlCommands.EVENT_BANDWIDTH_USED,
+ TorControlCommands.EVENT_NEW_DESC,
+ TorControlCommands.EVENT_ADDRMAP));
+ if (Prefs.useDebugLogging()) {
+ events.add(TorControlCommands.EVENT_DEBUG_MSG);
+ events.add(TorControlCommands.EVENT_INFO_MSG);
+ }
- int exitCode = -1;
+ int mDelay = 3000;
+ if(orbotLocalConstants.mIsTorInitialized){
+ mDelay = 0;
+ }
+ Thread.sleep(mDelay);
- try {
- exitCode = exec(torCmdString + " --verify-config", true);
- } catch (Exception e) {
- logNotice("Tor configuration did not verify: " + e.getMessage());
- return false;
+ conn.setEvents(events);
+ logNotice("SUCCESS added control port event handler");
+ } catch (InterruptedException | IOException e) {
+ e.printStackTrace();
+ stopTorOnError(e.getLocalizedMessage());
+ conn = null;
+ }
+ }
+
+ @Override
+ public void onServiceDisconnected(ComponentName componentName) {
+ conn = null;
+ torService = null;
+ mEventHandler = null;
+ }
+
+ @Override
+ public void onNullBinding(ComponentName componentName) {
+ stopTorOnError("Tor was unable to start: " + "onNullBinding");
+ conn = null;
+ torService = null;
+ mEventHandler = null;
+ }
+
+ @Override
+ public void onBindingDied(ComponentName componentName) {
+ stopTorOnError("Tor was unable to start: " + "onBindingDied");
+ conn = null;
+ torService = null;
+ mEventHandler = null;
+ }
+ };
+
+ BroadcastReceiver receiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ if (TorService.ACTION_STATUS.equals(intent.getAction())
+ && TorService.STATUS_ON.equals(intent.getStringExtra(TorService.EXTRA_STATUS))) {
+ initControlConnection();
+ unregisterReceiver(this);
+ }
+ }
+ };
+ // run the BroadcastReceiver in its own thread
+ HandlerThread handlerThread = new HandlerThread(receiver.getClass().getSimpleName());
+ handlerThread.start();
+ Looper looper = handlerThread.getLooper();
+ Handler handler = new Handler(looper);
+ registerReceiver(receiver, new IntentFilter(TorService.ACTION_STATUS), null, handler);
+
+ Intent serviceIntent = new Intent(this, TorService.class);
+ if (Build.VERSION.SDK_INT < 29) {
+ shouldUnbindTorService = bindService(serviceIntent, torServiceConnection, BIND_AUTO_CREATE);
+ } else {
+ shouldUnbindTorService = bindService(serviceIntent, BIND_AUTO_CREATE, mExecutor, torServiceConnection);
}
-
- if (exitCode == 0) {
- logNotice("Tor configuration VERIFIED.");
- try {
- exitCode = exec(torCmdString, false);
- } catch (Exception e) {
- logNotice("Tor was unable to start: " + e.getMessage());
-
- throw new Exception("Tor was unable to start: " + e.getMessage());
-
- }
-
- if (exitCode != 0) {
- logNotice("Tor did not start. Exit:" + exitCode);
- return false;
- }
-
- //now try to connect
- mLastProcessId = initControlConnection(10, false);
-
- if (mLastProcessId == -1) {
- logNotice(getString(R.string.couldn_t_start_tor_process_) + "; exit=" + exitCode);
- throw new Exception(getString(R.string.couldn_t_start_tor_process_) + "; exit=" + exitCode);
- } else {
-
- logNotice("Tor started; process id=" + mLastProcessId);
- result = true;
- }
- }
-
- return result;
}
- public void exec(Runnable runn) {
+ protected void exec(Runnable runn) {
mExecutor.execute(runn);
}
- private int exec(String cmd, boolean wait) throws Exception {
- HashMap mapEnv = new HashMap<>();
- mapEnv.put("HOME", appBinHome.getAbsolutePath());
-
- CommandResult result = CustomShell.run("sh", wait, mapEnv, cmd);
- debug("executing: " + cmd);
- debug("stdout: " + result.getStdout());
- debug("stderr: " + result.getStderr());
-
- return result.exitCode;
+ public int getNotifyId() {
+ return NOTIFY_ID;
}
- private int initControlConnection(int maxTries, boolean isReconnect) throws Exception {
- int controlPort = -1;
- int attempt = 0;
-
- logNotice("Waiting for control port...");
-
- while (conn == null && attempt++ < maxTries && (mCurrentStatus != STATUS_OFF)) {
- try {
-
- controlPort = getControlPort();
-
- if (controlPort != -1) {
- logNotice("Connecting to control port: " + controlPort);
-
-
- break;
- }
-
- } catch (Exception ce) {
- conn = null;
- // logException( "Error connecting to Tor local control port: " + ce.getMessage(),ce);
-
- }
-
-
- try {
- // logNotice("waiting...");
- Thread.sleep(2000);
- } catch (Exception e) {
- Log.i("sda","ASd");
- }
- }
-
-
- if (controlPort != -1) {
- Socket torConnSocket = new Socket(IP_LOCALHOST, controlPort);
- torConnSocket.setSoTimeout(CONTROL_SOCKET_TIMEOUT);
-
- conn = new TorControlConnection(torConnSocket);
-
- conn.launchThread(true);//is daemon
-
- }
-
- if (conn != null) {
-
- logNotice("SUCCESS connected to Tor control port.");
-
- File fileCookie = new File(appCacheHome, TOR_CONTROL_COOKIE);
-
- if (fileCookie.exists()) {
-
- // We extend NullEventHandler so that we don't need to provide empty
- // implementations for all the events we don't care about.
- logNotice("adding control port event handler");
-
- conn.setEventHandler(mEventHandler);
-
- logNotice("SUCCESS added control port event handler");
- byte[] cookie = new byte[(int) fileCookie.length()];
- DataInputStream fis = new DataInputStream(new FileInputStream(fileCookie));
- fis.read(cookie);
- fis.close();
- conn.authenticate(cookie);
-
- logNotice("SUCCESS - authenticated to control port.");
-
- // conn.setEvents(Arrays.asList(new String[]{"DEBUG","STATUS_CLIENT","STATUS_GENERAL","BW"}));
-
- if (Prefs.useDebugLogging())
- conn.setEvents(Arrays.asList("CIRC", "STREAM", "ORCONN", "BW", "INFO", "NOTICE", "WARN", "DEBUG", "ERR", "NEWDESC", "ADDRMAP"));
- else
- conn.setEvents(Arrays.asList("CIRC", "STREAM", "ORCONN", "BW", "NOTICE", "ERR", "NEWDESC", "ADDRMAP"));
-
- // sendCallbackLogMessage(getString(R.string.tor_process_starting) + ' ' + getString(R.string.tor_process_complete));
-
- String torProcId = conn.getInfo("process/pid");
-
- String confSocks = conn.getInfo("net/listeners/socks");
- StringTokenizer st = new StringTokenizer(confSocks, " ");
-
- confSocks = st.nextToken().split(":")[1];
- confSocks = confSocks.substring(0, confSocks.length() - 1);
- mPortSOCKS = Integer.parseInt(confSocks);
-
- String confHttp = conn.getInfo("net/listeners/httptunnel");
- st = new StringTokenizer(confHttp, " ");
-
- confHttp = st.nextToken().split(":")[1];
- confHttp = confHttp.substring(0, confHttp.length() - 1);
- mPortHTTP = Integer.parseInt(confHttp);
-
- String confDns = conn.getInfo("net/listeners/dns");
- st = new StringTokenizer(confDns, " ");
- if (st.hasMoreTokens()) {
- confDns = st.nextToken().split(":")[1];
- confDns = confDns.substring(0, confDns.length() - 1);
- mPortDns = Integer.parseInt(confDns);
- Prefs.getSharedPrefs(getApplicationContext()).edit().putInt(VpnPrefs.PREFS_DNS_PORT, mPortDns).apply();
- }
-
- String confTrans = conn.getInfo("net/listeners/trans");
- st = new StringTokenizer(confTrans, " ");
- if (st.hasMoreTokens()) {
- confTrans = st.nextToken().split(":")[1];
- confTrans = confTrans.substring(0, confTrans.length() - 1);
- mPortTrans = Integer.parseInt(confTrans);
- }
-
- sendCallbackPorts(mPortSOCKS, mPortHTTP, mPortDns, mPortTrans);
-
- setTorNetworkEnabled(true);
-
- return Integer.parseInt(torProcId);
-
- } else {
- logNotice("Tor authentication cookie does not exist yet");
- conn = null;
-
- }
- }
-
- throw new Exception("Tor control port could not be found");
+ public String getProxyStatus() {
+ return mCurrentStatus;
}
- private int getControlPort() {
- int result = -1;
+ private static OrbotService self = null;
- try {
- if (fileControlPort.exists()) {
- debug("Reading control port config file: " + fileControlPort.getCanonicalPath());
- BufferedReader bufferedReader = new BufferedReader(new FileReader(fileControlPort));
- String line = bufferedReader.readLine();
-
- if (line != null) {
- String[] lineParts = line.split(":");
- result = Integer.parseInt(lineParts[1]);
- }
-
-
- bufferedReader.close();
-
- //store last valid control port
- SharedPreferences prefs = Prefs.getSharedPrefs(getApplicationContext());
- prefs.edit().putInt("controlport", result).apply();
- } else {
- debug("Control Port config file does not yet exist (waiting for tor): " + fileControlPort.getCanonicalPath());
- }
- } catch (FileNotFoundException e) {
- debug("unable to get control port; file not found");
- } catch (Exception e) {
- debug("unable to read control port config file");
- }
-
- return result;
+ public static OrbotService getServiceObject(){
+ return self;
}
- /**
- * Returns the port number that the HTTP proxy is running on
- */
- public int getHTTPPort() {
- return mPortHTTP;
- }
-
- /**
- * Returns the port number that the HTTP proxy is running on
- */
- public int getSOCKSPort() {
- return mPortSOCKS;
- }
-
- public String getInfo(String key) {
- try {
- if (conn != null) {
- return conn.getInfo(key);
- }
- } catch (Exception ioe) {
- // Log.e(TAG,"Unable to get Tor information",ioe);
- logNotice("Unable to get Tor information" + ioe.getMessage());
- }
- return null;
- }
-
- public String getConfiguration(String name) {
- try {
- if (conn != null) {
- StringBuffer result = new StringBuffer();
-
- List listCe = conn.getConf(name);
-
- Iterator itCe = listCe.iterator();
- ConfigEntry ce;
-
-
- while (itCe.hasNext()) {
- ce = itCe.next();
-
- result.append(ce.key);
- result.append(' ');
- result.append(ce.value);
- result.append('\n');
- }
-
- return result.toString();
- }
- } catch (Exception ioe) {
-
- logException("Unable to get Tor configuration: " + ioe.getMessage(), ioe);
- }
-
- return null;
- }
-
- /**
- * Set configuration
- **/
- public boolean updateConfiguration(String name, String value, boolean saveToDisk) {
-
-
- if (configBuffer == null)
- configBuffer = new ArrayList<>();
-
- if (resetBuffer == null)
- resetBuffer = new ArrayList<>();
-
- if (value == null || value.length() == 0) {
- resetBuffer.add(name + RESET_STRING);
-
- } else {
-
- String sbConf = name +
- ' ' +
- value;
- configBuffer.add(sbConf);
- }
-
- return false;
- }
-
-
- public void setTorNetworkEnabled(final boolean isEnabled) throws IOException {
-
- //it is possible to not have a connection yet, and someone might try to newnym
- if (conn != null) {
- new Thread() {
- public void run() {
- try {
-
- final String newValue = isEnabled ? "0" : "1";
- conn.setConf("DisableNetwork", newValue);
- } catch (Exception ioe) {
- debug("error requesting newnym: " + ioe.getLocalizedMessage());
- }
- }
- }.start();
- }
-
- }
-
- public void sendSignalActive() {
- if (conn != null && mCurrentStatus == STATUS_ON) {
- try {
- conn.signal("ACTIVE");
- } catch (IOException e) {
- debug("error send active: " + e.getLocalizedMessage());
- }
- }
- }
-
- public void newIdentity() {
- //it is possible to not have a connection yet, and someone might try to newnym
- if (conn != null) {
- new Thread() {
- public void run() {
- try {
- int iconId = R.drawable.ic_stat_tor;
-
- if (conn != null && mCurrentStatus == STATUS_ON && Prefs.expandedNotifications() && mConnectivity)
- showToolbarNotification(getString(R.string.newnym), NOTIFY_ID, R.drawable.ic_stat_starting_tor_logo);
-
- conn.signal(TorControlCommands.SIGNAL_NEWNYM);
-
- sleep(1000);
- if(mConnectivity)
- enableNotification();
-
- } catch (Exception ioe) {
- debug("error requesting newnym: " + ioe.getLocalizedMessage());
- }
- }
- }.start();
- }
- }
-
- public boolean saveConfiguration() {
- try {
- if (conn != null) {
-
- if (resetBuffer != null && resetBuffer.size() > 0) {
- for (String value : configBuffer) {
-
- // debug("removing torrc conf: " + value);
-
-
- }
-
- // conn.resetConf(resetBuffer);
- resetBuffer = null;
- }
-
- if (configBuffer != null && configBuffer.size() > 0) {
-
- for (String value : configBuffer) {
-
- debug("Setting torrc conf: " + value);
-
-
- }
-
- conn.setConf(configBuffer);
-
- configBuffer = null;
- }
-
- // Flush the configuration to disk.
- //this is doing bad things right now NF 22/07/10
- //conn.saveConf();
-
- return true;
- }
- } catch (Exception ioe) {
- logException("Unable to update Tor configuration: " + ioe.getMessage(), ioe);
- }
-
- return false;
- }
-
- public void sendCallbackBandwidth(long upload, long download, long written, long read) {
- Intent intent = new Intent(LOCAL_ACTION_BANDWIDTH);
-
- intent.putExtra("up", upload);
- intent.putExtra("down", download);
- intent.putExtra("written", written);
- intent.putExtra("read", read);
- intent.putExtra(EXTRA_STATUS, mCurrentStatus);
-
- LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
- }
-
- private void sendCallbackLogMessage(String logMessage)
- {
-
- if(logMessage.contains("Bootstrapped 100%")){
- orbotLocalConstants.mIsTorInitialized = true;
- }
- mHandler.post(() -> {
- Intent intent = new Intent(LOCAL_ACTION_LOG);
- intent.putExtra(LOCAL_EXTRA_LOG, logMessage);
- intent.putExtra(EXTRA_STATUS, mCurrentStatus);
- orbotLocalConstants.mTorLogsHistory.add(new logRowModel(logMessage, localHelperMethod.getCurrentTime()));
-
- if(!mConnectivity){
- orbotLocalConstants.mTorLogsStatus = "No internet connection";
- }else {
- orbotLocalConstants.mTorLogsStatus = logMessage;
- }
- LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
- });
-
- }
-
- private void sendCallbackPorts(int socksPort, int httpPort, int dnsPort, int transPort) {
-
- Intent intent = new Intent(LOCAL_ACTION_PORTS);
- // You can also include some extra data.
- intent.putExtra(EXTRA_SOCKS_PROXY_PORT, socksPort);
- intent.putExtra(EXTRA_HTTP_PROXY_PORT, httpPort);
- intent.putExtra(EXTRA_DNS_PORT, dnsPort);
- intent.putExtra(EXTRA_TRANS_PORT, transPort);
-
- LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
-
- if (Prefs.useVpn())
- mVpnManager.handleIntent(new Builder(), intent);
-
- }
-
- public void sendCallbackStatus(String currentStatus) {
- mCurrentStatus = currentStatus;
- Intent intent = getActionStatusIntent(currentStatus);
- sendBroadcastOnlyToOrbot(intent); // send for Orbot internals, using secure local broadcast
- sendBroadcast(intent); // send for any apps that are interested
- }
-
- /**
- * Send a secure broadcast only to Orbot itself
- *
- * @see {@link ContextWrapper#sendBroadcast(Intent)}
- * @see {@link LocalBroadcastManager}
- */
- private boolean sendBroadcastOnlyToOrbot(Intent intent) {
- return LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
- }
-
- private Intent getActionStatusIntent(String currentStatus) {
- Intent intent = new Intent(ACTION_STATUS);
- intent.putExtra(EXTRA_STATUS, currentStatus);
- return intent;
- }
-
- /*
- * Another way to do this would be to use the Observer pattern by defining the
- * BroadcastReciever in the Android manifest.
- */
-
private boolean mConnectivity = true;
private int mNetworkType = -1;
private final BroadcastReceiver mNetworkStateReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
- SharedPreferences prefs = org.torproject.android.proxy.util.Prefs.getSharedPrefs(getApplicationContext());
+ SharedPreferences prefs = Prefs.getSharedPrefs(getApplicationContext());
if(prefs==null){
}
@@ -1376,7 +1019,7 @@ public class OrbotService extends VpnService implements TorServiceConstants, Orb
final ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
final NetworkInfo netInfo = cm.getActiveNetworkInfo();
- boolean newConnectivityState = false;
+ boolean newConnectivityState;
int newNetType = -1;
if (netInfo!=null)
@@ -1411,7 +1054,7 @@ public class OrbotService extends VpnService implements TorServiceConstants, Orb
orbotLocalConstants.mTorLogsStatus = "No internet connection";
if(orbotLocalConstants.mNotificationStatus!=0){
showToolbarNotification(getString(R.string.newnym), getNotifyId(), R.drawable.ic_stat_tor_off);
- showToolbarNotification("Genesis is sleeping",NOTIFY_ID,R.drawable.ic_stat_tor_off);
+ showToolbarNotification("Genesis is sleeping | Internet connectivity issue",NOTIFY_ID,R.drawable.ic_stat_tor_off);
}
}
else
@@ -1427,28 +1070,179 @@ public class OrbotService extends VpnService implements TorServiceConstants, Orb
}
};
+ private void initControlConnection() {
+ if (conn != null) {
+ logNotice("SUCCESS connected to Tor control port.");
+ try {
+ String confSocks = conn.getInfo("net/listeners/socks");
+ StringTokenizer st = new StringTokenizer(confSocks, " ");
+
+ confSocks = st.nextToken().split(":")[1];
+ confSocks = confSocks.substring(0, confSocks.length() - 1);
+ mPortSOCKS = Integer.parseInt(confSocks);
+
+ String confHttp = conn.getInfo("net/listeners/httptunnel");
+ st = new StringTokenizer(confHttp, " ");
+
+ confHttp = st.nextToken().split(":")[1];
+ confHttp = confHttp.substring(0, confHttp.length() - 1);
+ mPortHTTP = Integer.parseInt(confHttp);
+
+ String confDns = conn.getInfo("net/listeners/dns");
+ st = new StringTokenizer(confDns, " ");
+ if (st.hasMoreTokens()) {
+ confDns = st.nextToken().split(":")[1];
+ confDns = confDns.substring(0, confDns.length() - 1);
+ mPortDns = Integer.parseInt(confDns);
+ Prefs.getSharedPrefs(getApplicationContext()).edit().putInt(VpnPrefs.PREFS_DNS_PORT, mPortDns).apply();
+ }
+
+ String confTrans = conn.getInfo("net/listeners/trans");
+ st = new StringTokenizer(confTrans, " ");
+ if (st.hasMoreTokens()) {
+ confTrans = st.nextToken().split(":")[1];
+ confTrans = confTrans.substring(0, confTrans.length() - 1);
+ mPortTrans = Integer.parseInt(confTrans);
+ }
+
+ sendCallbackPorts(mPortSOCKS, mPortHTTP, mPortDns, mPortTrans);
+ orbotLocalConstants.mIsTorInitialized = true;
+
+ } catch (IOException e) {
+ Log.i("sad","asd");
+ e.printStackTrace();
+ stopTorOnError(e.getLocalizedMessage());
+ conn = null;
+ }
+ }
+ }
+
+ public void sendSignalActive() {
+ if (conn != null && mCurrentStatus == STATUS_ON) {
+ try {
+ conn.signal("ACTIVE");
+ } catch (IOException e) {
+ debug("error send active: " + e.getLocalizedMessage());
+ }
+ }
+ }
+
+ public void newIdentity() {
+ //it is possible to not have a connection yet, and someone might try to newnym
+ if (conn != null) {
+ new Thread() {
+ public void run() {
+ try {
+ int iconId = R.mipmap.ic_stat_tor_logo;
+
+ if (conn != null && mCurrentStatus == STATUS_ON && Prefs.expandedNotifications() && mConnectivity)
+ showToolbarNotification(getString(R.string.newnym), NOTIFY_ID, R.drawable.ic_stat_starting_tor_logo);
+
+ conn.signal(TorControlCommands.SIGNAL_NEWNYM);
+
+ sleep(1000);
+ if(mConnectivity)
+ enableNotification();
+
+ } catch (Exception ioe) {
+ debug("error requesting newnym: " + ioe.getLocalizedMessage());
+ }
+ }
+ }.start();
+ }
+ }
+
+ protected void sendCallbackBandwidth(long lastWritten, long lastRead, long totalWritten, long totalRead) {
+ Intent intent = new Intent(LOCAL_ACTION_BANDWIDTH);
+
+ intent.putExtra("totalWritten", totalWritten);
+ intent.putExtra("totalRead", totalRead);
+ intent.putExtra("lastWritten", lastWritten);
+ intent.putExtra("lastRead", lastRead);
+ intent.putExtra(EXTRA_STATUS, mCurrentStatus);
+
+ LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
+ }
+
+ int e=0;
+ private void sendCallbackLogMessage(String logMessage)
+ {
+
+ if(logMessage.contains("Bootstrapped 100%")){
+ orbotLocalConstants.mIsTorInitialized = true;
+ }
+ mHandler.post(() -> {
+ Intent intent = new Intent(LOCAL_ACTION_LOG);
+ intent.putExtra(LOCAL_EXTRA_LOG, logMessage);
+ intent.putExtra(EXTRA_STATUS, mCurrentStatus);
+ orbotLocalConstants.mTorLogsHistory.add(new logRowModel(logMessage, localHelperMethod.getCurrentTime()));
+
+ if(!mConnectivity){
+ orbotLocalConstants.mTorLogsStatus = "No internet connection";
+ }else {
+ orbotLocalConstants.mTorLogsStatus = logMessage;
+ }
+ LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
+ });
+
+ }
+
+ public boolean getConnectivity(){
+ return mConnectivity;
+ }
+
+ private void sendCallbackPorts(int socksPort, int httpPort, int dnsPort, int transPort) {
+ Intent intent = new Intent(LOCAL_ACTION_PORTS); // You can also include some extra data.
+ intent.putExtra(EXTRA_SOCKS_PROXY_PORT, socksPort);
+ intent.putExtra(EXTRA_HTTP_PROXY_PORT, httpPort);
+ intent.putExtra(EXTRA_DNS_PORT, dnsPort);
+ intent.putExtra(EXTRA_TRANS_PORT, transPort);
+
+ LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
+
+ if (Prefs.useVpn())
+ mVpnManager.handleIntent(new Builder(), intent);
+
+ }
+
+ protected void sendCallbackStatus(String currentStatus) {
+ mCurrentStatus = currentStatus;
+ Intent intent = getActionStatusIntent(currentStatus);
+ sendBroadcastOnlyToOrbot(intent); // send for Orbot internals, using secure local broadcast
+ sendBroadcast(intent); // send for any apps that are interested
+ }
+
+ /**
+ * Send a secure broadcast only to Orbot itself
+ *
+ * @see {@link ContextWrapper#sendBroadcast(Intent)}
+ * @see {@link LocalBroadcastManager}
+ */
+ private boolean sendBroadcastOnlyToOrbot(Intent intent) {
+ return LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
+ }
+
+ private Intent getActionStatusIntent(String currentStatus) {
+ Intent intent = new Intent(ACTION_STATUS);
+ intent.putExtra(EXTRA_STATUS, currentStatus);
+ return intent;
+ }
+
private StringBuffer processSettingsImpl(StringBuffer extraLines) throws IOException {
logNotice(getString(R.string.updating_settings_in_tor_service));
-
SharedPreferences prefs = Prefs.getSharedPrefs(getApplicationContext());
boolean useBridges = Prefs.bridgesEnabled();
-
boolean becomeRelay = prefs.getBoolean(OrbotConstants.PREF_OR, false);
boolean ReachableAddresses = prefs.getBoolean(OrbotConstants.PREF_REACHABLE_ADDRESSES, false);
-
boolean enableStrictNodes = prefs.getBoolean("pref_strict_nodes", false);
String entranceNodes = prefs.getString("pref_entrance_nodes", "");
String exitNodes = prefs.getString("pref_exit_nodes", "");
String excludeNodes = prefs.getString("pref_exclude_nodes", "");
if (!useBridges) {
-
extraLines.append("UseBridges 0").append('\n');
-
- if (Prefs.useVpn()) //set the proxy here if we aren't using a bridge
- {
-
+ if (Prefs.useVpn()) { //set the proxy here if we aren't using a bridge
if (!mIsLollipop) {
String proxyType = "socks5";
extraLines.append(proxyType + "Proxy" + ' ' + OrbotVpnManager.sSocksProxyLocalhost + ':' + OrbotVpnManager.sSocksProxyServerPort).append('\n');
@@ -1463,159 +1257,203 @@ public class OrbotService extends VpnService implements TorServiceConstants, Orb
String proxyPass = prefs.getString("pref_proxy_password", null);
if ((proxyHost != null && proxyHost.length() > 0) && (proxyPort != null && proxyPort.length() > 0)) {
- extraLines.append(proxyType + "Proxy" + ' ' + proxyHost + ':' + proxyPort).append('\n');
+ extraLines.append(proxyType).append("Proxy").append(' ').append(proxyHost).append(':').append(proxyPort).append('\n');
if (proxyUser != null && proxyPass != null) {
if (proxyType.equalsIgnoreCase("socks5")) {
- extraLines.append("Socks5ProxyUsername" + ' ' + proxyUser).append('\n');
- extraLines.append("Socks5ProxyPassword" + ' ' + proxyPass).append('\n');
+ extraLines.append("Socks5ProxyUsername").append(' ').append(proxyUser).append('\n');
+ extraLines.append("Socks5ProxyPassword").append(' ').append(proxyPass).append('\n');
} else
- extraLines.append(proxyType + "ProxyAuthenticator" + ' ' + proxyUser + ':' + proxyPort).append('\n');
+ extraLines.append(proxyType).append("ProxyAuthenticator").append(' ').append(proxyUser).append(':').append(proxyPort).append('\n');
} else if (proxyPass != null)
- extraLines.append(proxyType + "ProxyAuthenticator" + ' ' + proxyUser + ':' + proxyPort).append('\n');
-
-
+ extraLines.append(proxyType).append("ProxyAuthenticator").append(' ').append(proxyUser).append(':').append(proxyPort).append('\n');
}
}
}
} else {
- if (fileObfsclient != null
- && fileObfsclient.exists()
- && fileObfsclient.canExecute()) {
- loadBridgeDefaults();
+ loadBridgeDefaults();
+ extraLines.append("UseBridges 1").append('\n');
+ // extraLines.append("UpdateBridgesFromAuthority 1").append('\n');
- extraLines.append("UseBridges 1").append('\n');
- // extraLines.append("UpdateBridgesFromAuthority 1").append('\n');
+ String bridgeList = Prefs.getBridgesList();
- String bridgeList = Prefs.getBridgesList();
- boolean obfs3Bridges = bridgeList.contains("obfs3");
- boolean obfs4Bridges = bridgeList.contains("obfs4");
- boolean meekBridges = bridgeList.contains("meek");
+ String builtInBridgeType = null;
- //check if any PT bridges are needed
- if (obfs3Bridges)
- extraLines.append("ClientTransportPlugin obfs3 exec ")
- .append(fileObfsclient.getAbsolutePath()).append('\n');
+ //check if any PT bridges are needed
+ if (bridgeList.contains("obfs")) {
- if (obfs4Bridges)
- extraLines.append("ClientTransportPlugin obfs4 exec ")
- .append(fileObfsclient.getAbsolutePath()).append('\n');
+ extraLines.append("ClientTransportPlugin obfs3 socks5 127.0.0.1:" + IPtProxy.obfs3Port()).append('\n');
+ extraLines.append("ClientTransportPlugin obfs4 socks5 127.0.0.1:" + IPtProxy.obfs4Port()).append('\n');
- if (meekBridges)
- extraLines.append("ClientTransportPlugin meek_lite exec " + fileObfsclient.getCanonicalPath()).append('\n');
+ if (bridgeList.equals("obfs4"))
+ builtInBridgeType = "obfs4";
+ }
- if (bridgeList != null && bridgeList.length() > 5) //longer then 1 = some real values here
- {
- String[] bridgeListLines = parseBridgesFromSettings(bridgeList);
- int bridgeIdx = (int) Math.floor(Math.random() * ((double) bridgeListLines.length));
- String bridgeLine = bridgeListLines[bridgeIdx];
- extraLines.append("Bridge ");
- extraLines.append(bridgeLine);
- extraLines.append("\n");
- /**
- for (String bridgeConfigLine : bridgeListLines) {
- if (!TextUtils.isEmpty(bridgeConfigLine)) {
- extraLines.append("Bridge ");
- extraLines.append(bridgeConfigLine.trim());
- extraLines.append("\n");
- }
+ if (bridgeList.equals("meek")) {
+ extraLines.append("ClientTransportPlugin meek_lite socks5 127.0.0.1:" + IPtProxy.meekPort()).append('\n');
+ builtInBridgeType = "meek_lite";
+ }
- }**/
- } else {
+ if (bridgeList.equals("snowflake")) {
+ extraLines.append("ClientTransportPlugin snowflake socks5 127.0.0.1:" + IPtProxy.snowflakePort()).append('\n');
+ builtInBridgeType = "snowflake";
+ }
- String type = "obfs4";
-
- if (meekBridges)
- type = "meek_lite";
-
- getBridges(type, extraLines);
-
- }
- } else {
- throw new IOException("Bridge binary does not exist: " + fileObfsclient.getCanonicalPath());
+ if (!TextUtils.isEmpty(builtInBridgeType))
+ getBridges(builtInBridgeType, extraLines);
+ else {
+ String[] bridgeListLines = parseBridgesFromSettings(bridgeList);
+ int bridgeIdx = (int) Math.floor(Math.random() * ((double) bridgeListLines.length));
+ String bridgeLine = bridgeListLines[bridgeIdx];
+ extraLines.append("Bridge ");
+ extraLines.append(bridgeLine);
+ extraLines.append("\n");
}
}
-
//only apply GeoIP if you need it
File fileGeoIP = new File(appBinHome, GEOIP_ASSET_KEY);
File fileGeoIP6 = new File(appBinHome, GEOIP6_ASSET_KEY);
if (fileGeoIP.exists()) {
- extraLines.append("GeoIPFile" + ' ' + fileGeoIP.getCanonicalPath()).append('\n');
- extraLines.append("GeoIPv6File" + ' ' + fileGeoIP6.getCanonicalPath()).append('\n');
+ extraLines.append("GeoIPFile" + ' ').append(fileGeoIP.getCanonicalPath()).append('\n');
+ extraLines.append("GeoIPv6File" + ' ').append(fileGeoIP6.getCanonicalPath()).append('\n');
}
if (!TextUtils.isEmpty(entranceNodes))
- extraLines.append("EntryNodes" + ' ' + entranceNodes).append('\n');
+ extraLines.append("EntryNodes" + ' ').append(entranceNodes).append('\n');
if (!TextUtils.isEmpty(exitNodes))
- extraLines.append("ExitNodes" + ' ' + exitNodes).append('\n');
+ extraLines.append("ExitNodes" + ' ').append(exitNodes).append('\n');
if (!TextUtils.isEmpty(excludeNodes))
- extraLines.append("ExcludeNodes" + ' ' + excludeNodes).append('\n');
+ extraLines.append("ExcludeNodes" + ' ').append(excludeNodes).append('\n');
- extraLines.append("StrictNodes" + ' ' + (enableStrictNodes ? "1" : "0")).append('\n');
+ extraLines.append("StrictNodes" + ' ').append(enableStrictNodes ? "1" : "0").append('\n');
try {
if (ReachableAddresses) {
- String ReachableAddressesPorts =
- prefs.getString(OrbotConstants.PREF_REACHABLE_ADDRESSES_PORTS, "*:80,*:443");
-
- extraLines.append("ReachableAddresses" + ' ' + ReachableAddressesPorts).append('\n');
-
+ String ReachableAddressesPorts = prefs.getString(OrbotConstants.PREF_REACHABLE_ADDRESSES_PORTS, "*:80,*:443");
+ extraLines.append("ReachableAddresses" + ' ').append(ReachableAddressesPorts).append('\n');
}
} catch (Exception e) {
showToolbarNotification(getString(R.string.your_reachableaddresses_settings_caused_an_exception_), ERROR_NOTIFY_ID, R.drawable.ic_stat_notifyerr);
-
return null;
}
try {
if (becomeRelay && (!useBridges) && (!ReachableAddresses)) {
- int ORPort = Integer.parseInt(prefs.getString(OrbotConstants.PREF_OR_PORT, "9001"));
+ int ORPort = Integer.parseInt(Objects.requireNonNull(prefs.getString(OrbotConstants.PREF_OR_PORT, "9001")));
String nickname = prefs.getString(OrbotConstants.PREF_OR_NICKNAME, "Orbot");
-
String dnsFile = writeDNSFile();
- extraLines.append("ServerDNSResolvConfFile" + ' ' + dnsFile).append('\n');
- extraLines.append("ORPort" + ' ' + ORPort).append('\n');
- extraLines.append("Nickname" + ' ' + nickname).append('\n');
- extraLines.append("ExitPolicy" + ' ' + "reject *:*").append('\n');
+ extraLines.append("ServerDNSResolvConfFile").append(' ').append(dnsFile).append('\n');
+ extraLines.append("ORPort").append(' ').append(ORPort).append('\n');
+ extraLines.append("Nickname").append(' ').append(nickname).append('\n');
+ extraLines.append("ExitPolicy").append(' ').append("reject *:*").append('\n');
}
} catch (Exception e) {
showToolbarNotification(getString(R.string.your_relay_settings_caused_an_exception_), ERROR_NOTIFY_ID, R.drawable.ic_stat_notifyerr);
-
-
return null;
}
- ContentResolver mCR = getApplicationContext().getContentResolver();
+ if (false) {
+ ContentResolver contentResolver = getApplicationContext().getContentResolver();
+ addV3OnionServicesToTorrc(extraLines, contentResolver);
+ addV3ClientAuthToTorrc(extraLines, contentResolver);
+ addV2HiddenServicesToTorrc(extraLines, contentResolver);
+ addV2ClientCookiesToTorrc(extraLines, contentResolver);
+ }
+ return extraLines;
+ }
+
+ public static String formatBandwidthCount(Context context, long bitsPerSecond) {
+ NumberFormat nf = NumberFormat.getInstance(Locale.getDefault());
+ if (bitsPerSecond < 1e6)
+ return nf.format(Math.round(((float) ((int) (bitsPerSecond * 10 / 1024)) / 10)))
+ + "kbps";
+ else
+ return nf.format(Math.round(((float) ((int) (bitsPerSecond * 100 / 1024 / 1024)) / 100)))
+ + "mbps";
+ }
+
+ private void addV3OnionServicesToTorrc(StringBuffer torrc, ContentResolver contentResolver) {
try {
- /* ---- Hidden Services ---- */
- Cursor hidden_services = mCR.query(HS_CONTENT_URI, hsProjection, HiddenService.ENABLED + "=1", null, null);
+ Cursor onionServices = contentResolver.query(V3_ONION_SERVICES_CONTENT_URI, V3_ONION_SERVICE_PROJECTION, OnionService.ENABLED + "=1", null, null);
+ if (onionServices != null) {
+ while (onionServices.moveToNext()) {
+ int id = onionServices.getInt(onionServices.getColumnIndex(OnionService._ID));
+ int localPort = onionServices.getInt(onionServices.getColumnIndex(OnionService.PORT));
+ int onionPort = onionServices.getInt(onionServices.getColumnIndex(OnionService.ONION_PORT));
+ String path = onionServices.getString(onionServices.getColumnIndex(OnionService.PATH));
+ String domain = onionServices.getString(onionServices.getColumnIndex(OnionService.DOMAIN));
+ if (path == null) {
+ path = "v3";
+ if (domain == null)
+ path += UUID.randomUUID().toString();
+ else
+ path += localPort;
+ ContentValues cv = new ContentValues();
+ cv.put(OnionService.PATH, path);
+ contentResolver.update(V3_ONION_SERVICES_CONTENT_URI, cv, OnionService._ID + "=" + id, null);
+ }
+ String v3DirPath = new File(mV3OnionBasePath.getAbsolutePath(), path).getCanonicalPath();
+ torrc.append("HiddenServiceDir ").append(v3DirPath).append("\n");
+ torrc.append("HiddenServiceVersion 3").append("\n");
+ torrc.append("HiddenServicePort ").append(onionPort).append(" 127.0.0.1:").append(localPort).append("\n");
+ }
+ onionServices.close();
+ }
+ } catch (Exception e) {
+ Log.i("sad","asd");
+ Log.e(TAG, e.getLocalizedMessage());
+ }
+ }
+
+ private void addV2HiddenServicesToTorrc(StringBuffer torrc, ContentResolver contentResolver) {
+ try {
+ Cursor hidden_services = contentResolver.query(V2_HS_CONTENT_URI, LEGACY_V2_ONION_SERVICE_PROJECTION, OnionService.ENABLED + "=1", null, null);
if (hidden_services != null) {
try {
while (hidden_services.moveToNext()) {
- String HSname = hidden_services.getString(hidden_services.getColumnIndex(HiddenService.NAME));
- Integer HSLocalPort = hidden_services.getInt(hidden_services.getColumnIndex(HiddenService.PORT));
- Integer HSOnionPort = hidden_services.getInt(hidden_services.getColumnIndex(HiddenService.ONION_PORT));
- Integer HSAuthCookie = hidden_services.getInt(hidden_services.getColumnIndex(HiddenService.AUTH_COOKIE));
- String hsDirPath = new File(mHSBasePath.getAbsolutePath(), "hs" + HSLocalPort).getCanonicalPath();
+ int id = hidden_services.getInt(hidden_services.getColumnIndex(OnionService._ID));
+ String HSname = hidden_services.getString(hidden_services.getColumnIndex(OnionService.NAME));
+ String domain = hidden_services.getString(hidden_services.getColumnIndex(OnionService.DOMAIN));
+ int HSLocalPort = hidden_services.getInt(hidden_services.getColumnIndex(OnionService.PORT));
+ int HSOnionPort = hidden_services.getInt(hidden_services.getColumnIndex(OnionService.ONION_PORT));
+ int HSAuthCookie = hidden_services.getInt(hidden_services.getColumnIndex(OnionService.AUTH_COOKIE));
+ String path = hidden_services.getString(hidden_services.getColumnIndex(OnionService.PATH));
+
+ // logic to fix bug where you can't have 2+ hidden services on same local port without breaking services that were configured before the bug fix
+ if (path == null) {
+ String newPath = "hs";
+ if (domain == null)
+ newPath +=UUID.randomUUID().toString();
+ else
+ newPath += HSLocalPort;
+
+ ContentValues cv = new ContentValues();
+ cv.put(OnionService.PATH, newPath);
+ contentResolver.update(V2_HS_CONTENT_URI, cv, OnionService._ID + "=" + id, null);
+ path = newPath;
+ }
+
+ String hsDirPath = new File(mHSBasePath.getAbsolutePath(), path).getCanonicalPath();
+
debug("Adding hidden service on port: " + HSLocalPort);
- extraLines.append("HiddenServiceDir" + ' ' + hsDirPath).append('\n');
- extraLines.append("HiddenServicePort" + ' ' + HSOnionPort + " 127.0.0.1:" + HSLocalPort).append('\n');
- extraLines.append("HiddenServiceVersion 2").append('\n');
+ torrc.append("HiddenServiceDir" + ' ' + hsDirPath).append('\n');
+ torrc.append("HiddenServiceVersion 2").append('\n');
+ torrc.append("HiddenServicePort" + ' ' + HSOnionPort + " 127.0.0.1:" + HSLocalPort).append('\n');
if (HSAuthCookie == 1)
- extraLines.append("HiddenServiceAuthorizeClient stealth " + HSname).append('\n');
+ torrc.append("HiddenServiceAuthorizeClient stealth " + HSname).append('\n');
}
} catch (NumberFormatException e) {
Log.e(OrbotConstants.TAG, "error parsing hsport", e);
@@ -1626,31 +1464,57 @@ public class OrbotService extends VpnService implements TorServiceConstants, Orb
hidden_services.close();
}
} catch (SecurityException se) {
- Log.i("sda","ASd");
+ Log.i("sad","asd");
}
+ }
+ public static String buildV3ClientAuthFile(String domain, String keyHash) {
+ return domain + ":descriptor:x25519:" + keyHash;
+ }
+
+ private void addV3ClientAuthToTorrc(StringBuffer torrc, ContentResolver contentResolver) {
+ Cursor v3auths = contentResolver.query(V3_CLIENT_AUTH_URI, V3_CLIENT_AUTH_PROJECTION, V3ClientAuth.ENABLED + "=1", null, null);
+ if (v3auths != null) {
+ for (File file : mV3AuthBasePath.listFiles()) {
+ if (!file.isDirectory())
+ file.delete(); // todo the adapter should maybe just write these files and not do this in service...
+ }
+ torrc.append("ClientOnionAuthDir " + mV3AuthBasePath.getAbsolutePath()).append('\n');
+ try {
+ int i = 0;
+ while (v3auths.moveToNext()) {
+ String domain = v3auths.getString(v3auths.getColumnIndex(V3ClientAuth.DOMAIN));
+ String hash = v3auths.getString(v3auths.getColumnIndex(V3ClientAuth.HASH));
+ File authFile = new File(mV3AuthBasePath, (i++) + ".auth_private");
+ authFile.createNewFile();
+ FileOutputStream fos = new FileOutputStream(authFile);
+ fos.write(buildV3ClientAuthFile(domain, hash).getBytes());
+ fos.close();
+ }
+ } catch (Exception e) {
+ Log.e(TAG, "error adding v3 client auth...");
+ }
+ }
+ }
+
+ private void addV2ClientCookiesToTorrc(StringBuffer torrc, ContentResolver contentResolver) {
try {
-
- /* ---- Client Cookies ---- */
- Cursor client_cookies = mCR.query(COOKIE_CONTENT_URI, cookieProjection, ClientCookie.ENABLED + "=1", null, null);
+ Cursor client_cookies = contentResolver.query(COOKIE_CONTENT_URI, LEGACY_COOKIE_PROJECTION, ClientCookie.ENABLED + "=1", null, null);
if (client_cookies != null) {
try {
while (client_cookies.moveToNext()) {
String domain = client_cookies.getString(client_cookies.getColumnIndex(ClientCookie.DOMAIN));
String cookie = client_cookies.getString(client_cookies.getColumnIndex(ClientCookie.AUTH_COOKIE_VALUE));
- extraLines.append("HidServAuth" + ' ' + domain + ' ' + cookie).append('\n');
+ torrc.append("HidServAuth" + ' ' + domain + ' ' + cookie).append('\n');
}
} catch (Exception e) {
Log.e(OrbotConstants.TAG, "error starting share server", e);
}
-
client_cookies.close();
}
} catch (SecurityException se) {
- Log.i("sda","ASd");
+ Log.i("sad","asd");
}
-
- return extraLines;
}
//using Google DNS for now as the public DNS server
@@ -1704,7 +1568,6 @@ public class OrbotService extends VpnService implements TorServiceConstants, Orb
@Override
public IBinder onBind(Intent intent) {
Log.e(TAG, "onBind");
- //do nothing here
return super.onBind(intent); // invoking super class will call onRevoke() when appropriate
}
@@ -1791,6 +1654,7 @@ public class OrbotService extends VpnService implements TorServiceConstants, Orb
in.close();
} catch (Exception e) {
+ Log.i("sad","asd");
e.printStackTrace();
}
}
@@ -1847,27 +1711,28 @@ public class OrbotService extends VpnService implements TorServiceConstants, Orb
}
}
- public static final class HiddenService implements BaseColumns {
+
+ public static final class OnionService implements BaseColumns {
public static final String NAME = "name";
public static final String PORT = "port";
public static final String ONION_PORT = "onion_port";
public static final String DOMAIN = "domain";
public static final String AUTH_COOKIE = "auth_cookie";
public static final String AUTH_COOKIE_VALUE = "auth_cookie_value";
- public static final String CREATED_BY_USER = "created_by_user";
public static final String ENABLED = "enabled";
+ public static final String PATH = "filepath";
+ }
- private HiddenService() {
- }
+ public static final class V3ClientAuth implements BaseColumns {
+ public static final String DOMAIN = "domain";
+ public static final String HASH = "hash";
+ public static final String ENABLED = "enabled";
}
public static final class ClientCookie implements BaseColumns {
public static final String DOMAIN = "domain";
public static final String AUTH_COOKIE_VALUE = "auth_cookie_value";
public static final String ENABLED = "enabled";
-
- private ClientCookie() {
- }
}
// for bridge loading from the assets default bridges.txt file
@@ -1883,6 +1748,7 @@ public class OrbotService extends VpnService implements TorServiceConstants, Orb
public Bridge(){
}
}
+
private class IncomingIntentRouter implements Runnable {
Intent mIntent;
@@ -1891,11 +1757,20 @@ public class OrbotService extends VpnService implements TorServiceConstants, Orb
}
public void run() {
-
String action = mIntent.getAction();
if (!TextUtils.isEmpty(action)) {
if (action.equals(ACTION_START) || action.equals(ACTION_START_ON_BOOT)) {
+
+ //if (useIPtObfsMeekProxy())
+ // IPtProxy.startObfs4Proxy("DEBUG", true, false);
+
+ if (useIPtSnowflakeProxy())
+ startSnowflakeClient();
+
+ if (Prefs.beSnowflakeProxy())
+ runSnowflakeProxy();
+
startTor();
replyWithStatus(mIntent);
@@ -1919,11 +1794,8 @@ public class OrbotService extends VpnService implements TorServiceConstants, Orb
if (mVpnManager != null && (!mVpnManager.isStarted())) {
//start VPN here
Intent vpnIntent = VpnService.prepare(OrbotService.this);
- if (vpnIntent == null) //then we can run the VPN
- {
+ if (vpnIntent == null) { //then we can run the VPN
mVpnManager.handleIntent(new Builder(), mIntent);
-
-
}
}
@@ -1936,10 +1808,11 @@ public class OrbotService extends VpnService implements TorServiceConstants, Orb
mVpnManager.handleIntent(new Builder(), mIntent);
} else if (action.equals(ACTION_STATUS)) {
replyWithStatus(mIntent);
- } else if (action.equals(CMD_SIGNAL_HUP)) {
+ } else if (action.equals(TorControlCommands.SIGNAL_RELOAD)) {
requestTorRereadConfig();
- } else if (action.equals(CMD_NEWNYM)) {
- newIdentity();
+ }
+ else if (action.equals(CMD_NEWNYM)) {
+ newIdentity();
}
else if (action.equals(CMD_SETTING)) {
onSettingRegister();
@@ -1947,9 +1820,7 @@ public class OrbotService extends VpnService implements TorServiceConstants, Orb
else if (action.equals(CMD_ACTIVE)) {
sendSignalActive();
} else if (action.equals(CMD_SET_EXIT)) {
-
setExitNode(mIntent.getStringExtra("exit"));
-
} else {
Log.w(OrbotConstants.TAG, "unhandled OrbotService Intent: " + action);
}
@@ -1957,27 +1828,6 @@ public class OrbotService extends VpnService implements TorServiceConstants, Orb
}
}
- public String getProxyStatus() {
- return mCurrentStatus;
- }
-
- private static OrbotService self = null;
-
- public static OrbotService getServiceObject(){
- return self;
- }
-
- public void onSettingRegister(){
- try {
- Intent intent = null;
- intent = new Intent(this, Class.forName("com.darkweb.genesissearchengine.appManager.settingManager.notificationManager.settingNotificationController"));
- intent.setFlags(FLAG_ACTIVITY_NEW_TASK);
- getApplicationContext().startActivity(intent);
- } catch (ClassNotFoundException e) {
- e.printStackTrace();
- }
- }
-
public void disableNotification(){
if(mNotificationManager!=null){
mNotificationManager.cancel(NOTIFY_ID);
@@ -1992,8 +1842,22 @@ public class OrbotService extends VpnService implements TorServiceConstants, Orb
}
public void enableNotification(){
- orbotLocalConstants.mNotificationStatus = 1;
- showToolbarNotification(0+"kbps ⇣ / " +0+"kbps ⇡", HS_NOTIFY_ID, R.mipmap.ic_stat_tor_logo);
+ if(mConnectivity && orbotLocalConstants.mIsTorInitialized){
+ orbotLocalConstants.mNotificationStatus = 1;
+ showToolbarNotification(0+"kbps ⇣ / " +0+"kbps ⇡", HS_NOTIFY_ID, R.mipmap.ic_stat_tor_logo);
+ }
+ }
+
+ public void onSettingRegister(){
+ try {
+ Intent intent = null;
+ intent = new Intent(this, Class.forName("com.darkweb.genesissearchengine.appManager.settingManager.notificationManager.settingNotificationController"));
+ intent.setFlags(FLAG_ACTIVITY_NEW_TASK);
+ getApplicationContext().startActivity(intent);
+ } catch (ClassNotFoundException e) {
+ Log.i("sad","asd");
+ e.printStackTrace();
+ }
}
private class ActionBroadcastReceiver extends BroadcastReceiver {
diff --git a/orbotmanager/src/main/java/org/torproject/android/service/StartTorReceiver.java b/orbotmanager/src/main/java/org/torproject/android/service/StartTorReceiver.java
index cbfb58a0..3fb77e91 100644
--- a/orbotmanager/src/main/java/org/torproject/android/service/StartTorReceiver.java
+++ b/orbotmanager/src/main/java/org/torproject/android/service/StartTorReceiver.java
@@ -6,7 +6,6 @@ import android.content.Intent;
import android.os.Build;
import android.text.TextUtils;
-import org.torproject.android.proxy.OrbotService;
import org.torproject.android.service.util.Prefs;
diff --git a/orbotmanager/src/main/java/org/torproject/android/proxy/TorEventHandler.java b/orbotmanager/src/main/java/org/torproject/android/service/TorEventHandler.java
similarity index 72%
rename from orbotmanager/src/main/java/org/torproject/android/proxy/TorEventHandler.java
rename to orbotmanager/src/main/java/org/torproject/android/service/TorEventHandler.java
index 1a15c0e3..5340732b 100644
--- a/orbotmanager/src/main/java/org/torproject/android/proxy/TorEventHandler.java
+++ b/orbotmanager/src/main/java/org/torproject/android/service/TorEventHandler.java
@@ -1,251 +1,220 @@
-package org.torproject.android.proxy;
-
-import android.text.TextUtils;
-
-import net.freehaven.tor.control.EventHandler;
-
-import org.torproject.android.proxy.util.ExternalIPFetcher;
-import org.torproject.android.proxy.util.Prefs;
-import org.torproject.android.service.R;
-import org.torproject.android.proxy.wrapper.orbotLocalConstants;
-
-import java.text.NumberFormat;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Locale;
-import java.util.StringTokenizer;
-
-/**
- * Created by n8fr8 on 9/25/16.
- */
-public class TorEventHandler implements EventHandler, TorServiceConstants {
-
- private final static int BW_THRESDHOLD = 10000;
- private OrbotService mService;
- private long lastRead = -1;
- private long lastWritten = -1;
- private long mTotalTrafficWritten = 0;
- private long mTotalTrafficRead = 0;
- private NumberFormat mNumberFormat;
- private HashMap hmBuiltNodes = new HashMap<>();
-
- public TorEventHandler(OrbotService service) {
- mService = service;
- mNumberFormat = NumberFormat.getInstance(Locale.getDefault()); //localized numbers!
-
- }
-
- public HashMap getNodes() {
- return hmBuiltNodes;
- }
-
- @Override
- public void message(String severity, String msg) {
-
- if (severity.equalsIgnoreCase("debug"))
- mService.debug(severity + ": " + msg);
- else
- mService.logNotice(severity + ": " + msg);
- }
-
- @Override
- public void newDescriptors(List orList) {
-
- for (String desc : orList)
- mService.debug("descriptors: " + desc);
-
- }
-
- @Override
- public void orConnStatus(String status, String orName) {
-
- String sb = "orConnStatus (" +
- parseNodeName(orName) +
- "): " +
- status;
- mService.debug(sb);
- }
-
- @Override
- public void streamStatus(String status, String streamID, String target) {
-
- String sb = "StreamStatus (" +
- (streamID) +
- "): " +
- status;
- mService.debug(sb);
- }
-
- @Override
- public void unrecognized(String type, String msg) {
-
- String sb = "Message (" +
- type +
- "): " +
- msg;
- mService.logNotice(sb);
- }
-
- @Override
- public void bandwidthUsed(long read, long written) {
-
- if (lastWritten > BW_THRESDHOLD || lastRead > BW_THRESDHOLD) {
-
- int iconId = R.mipmap.ic_stat_tor_logo;
-
- if (read > 0 || written > 0){
- if(orbotLocalConstants.mIsTorInitialized){
- iconId = R.mipmap.ic_stat_tor_logo;
- }else {
- iconId = R.drawable.ic_stat_starting_tor_logo;
- }
- }
-
- String sb = formatCount(read) +
- " \u2193" +
- " / " +
- formatCount(written) +
- " \u2191";
- mService.showToolbarNotification(sb, mService.getNotifyId(), iconId);
-
- mTotalTrafficWritten += written;
- mTotalTrafficRead += read;
-
- mService.sendCallbackBandwidth(lastWritten, lastRead, mTotalTrafficWritten, mTotalTrafficRead);
-
- lastWritten = 0;
- lastRead = 0;
- }
-
- lastWritten += written;
- lastRead += read;
-
- }
-
- private String formatCount(long count) {
- // Converts the supplied argument into a string.
-
- // Under 2Mb, returns "xxx.xKb"
- // Over 2Mb, returns "xxx.xxMb"
- if (mNumberFormat != null)
- if (count < 1e6)
- return mNumberFormat.format(Math.round((float) ((int) (count * 10 / 1024)) / 10)) + "kbps";
- else
- return mNumberFormat.format(Math.round((float) ((int) (count * 100 / 1024 / 1024)) / 100)) + "mbps";
- else
- return "";
-
- //return count+" kB";
- }
-
- public void circuitStatus(String status, String circID, String path) {
-
- /* once the first circuit is complete, then announce that Orbot is on*/
- if (mService.getCurrentStatus() == STATUS_STARTING && TextUtils.equals(status, "BUILT")) {
- mService.sendCallbackStatus(STATUS_ON);
- }
-
- if (Prefs.useDebugLogging()) {
- StringBuilder sb = new StringBuilder();
- sb.append("Circuit (");
- sb.append((circID));
- sb.append(") ");
- sb.append(status);
- sb.append(": ");
-
- StringTokenizer st = new StringTokenizer(path, ",");
- Node node;
-
- boolean isFirstNode = true;
- int nodeCount = st.countTokens();
-
- while (st.hasMoreTokens()) {
- String nodePath = st.nextToken();
- String nodeId = null, nodeName = null;
-
- String[] nodeParts;
-
- if (nodePath.contains("="))
- nodeParts = nodePath.split("=");
- else
- nodeParts = nodePath.split("~");
-
- if (nodeParts.length == 1) {
- nodeId = nodeParts[0].substring(1);
- nodeName = nodeId;
- } else if (nodeParts.length == 2) {
- nodeId = nodeParts[0].substring(1);
- nodeName = nodeParts[1];
- }
-
- if (nodeId == null)
- continue;
-
- node = hmBuiltNodes.get(nodeId);
-
- if (node == null) {
- node = new Node();
- node.id = nodeId;
- node.name = nodeName;
- }
-
- node.status = status;
-
- sb.append(node.name);
-
- if (!TextUtils.isEmpty(node.ipAddress))
- sb.append("(").append(node.ipAddress).append(")");
-
- if (st.hasMoreTokens())
- sb.append(" > ");
-
- if (status.equals("EXTENDED")) {
-
- if (isFirstNode) {
- hmBuiltNodes.put(node.id, node);
-
- if (node.ipAddress == null && (!node.isFetchingInfo) && Prefs.useDebugLogging()) {
- node.isFetchingInfo = true;
- mService.exec(new ExternalIPFetcher(mService, node, OrbotService.mPortHTTP));
- }
-
- isFirstNode = false;
- }
- } else if (status.equals("BUILT")) {
- // mService.logNotice(sb.toString());
-
- if (Prefs.useDebugLogging() && nodeCount > 3)
- mService.debug(sb.toString());
- } else if (status.equals("CLOSED")) {
- // mService.logNotice(sb.toString());
- hmBuiltNodes.remove(node.id);
- }
-
- }
-
-
- }
-
-
- }
-
- private String parseNodeName(String node) {
- if (node.indexOf('=') != -1) {
- return (node.substring(node.indexOf("=") + 1));
- } else if (node.indexOf('~') != -1) {
- return (node.substring(node.indexOf("~") + 1));
- } else
- return node;
- }
-
- public static class Node {
- public String status;
- public String id;
- public String name;
- public String ipAddress;
- public String country;
- public String organization;
-
- public boolean isFetchingInfo = false;
- }
-}
+package org.torproject.android.service;
+
+import android.text.TextUtils;
+
+import net.freehaven.tor.control.EventHandler;
+
+import org.torproject.android.service.util.ExternalIPFetcher;
+import org.torproject.android.service.util.Prefs;
+import org.torproject.android.service.wrapper.orbotLocalConstants;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.StringTokenizer;
+
+/**
+ * Created by n8fr8 on 9/25/16.
+ */
+public class TorEventHandler implements EventHandler, TorServiceConstants {
+
+ private final static int BW_THRESDHOLD = 10000;
+ private final OrbotService mService;
+ private long lastRead = -1;
+ private long lastWritten = -1;
+ private long mTotalTrafficWritten = 0;
+ private long mTotalTrafficRead = 0;
+ private final HashMap hmBuiltNodes = new HashMap<>();
+
+ public TorEventHandler(OrbotService service) {
+ mService = service;
+ }
+
+ public HashMap getNodes() {
+ return hmBuiltNodes;
+ }
+
+ @Override
+ public void message(String severity, String msg) {
+ if (severity.equalsIgnoreCase("debug"))
+ mService.debug(severity + ": " + msg);
+ else
+ mService.logNotice(severity + ": " + msg);
+ }
+
+ @Override
+ public void newDescriptors(List orList) {
+
+ for (String desc : orList)
+ mService.debug("descriptors: " + desc);
+
+ }
+
+ @Override
+ public void orConnStatus(String status, String orName) {
+
+ String sb = "orConnStatus (" +
+ parseNodeName(orName) +
+ "): " +
+ status;
+ mService.debug(sb);
+ }
+
+ @Override
+ public void streamStatus(String status, String streamID, String target) {
+
+ String sb = "StreamStatus (" +
+ (streamID) +
+ "): " +
+ status;
+ mService.debug(sb);
+ }
+
+ @Override
+ public void unrecognized(String type, String msg) {
+
+ String sb = "Message (" +
+ type +
+ "): " +
+ msg;
+ mService.logNotice(sb);
+ }
+
+ @Override
+ public void bandwidthUsed(long read, long written) {
+
+ if (lastWritten > BW_THRESDHOLD || lastRead > BW_THRESDHOLD) {
+
+ int iconId = R.drawable.ic_stat_starting_tor_logo;
+
+ if (read > 0 || written > 0 || OrbotService.getServiceObject().getConnectivity())
+ iconId = R.mipmap.ic_stat_tor_logo;
+
+ String sb = OrbotService.formatBandwidthCount(mService, read) + " \u2193" + " / " +
+ OrbotService.formatBandwidthCount(mService, written) + " \u2191";
+ mService.showToolbarNotification(sb, OrbotService.NOTIFY_ID, iconId);
+
+ mTotalTrafficWritten += written;
+ mTotalTrafficRead += read;
+
+ mService.sendCallbackBandwidth(written, read, mTotalTrafficWritten, mTotalTrafficRead);
+
+ lastWritten = 0;
+ lastRead = 0;
+ }
+
+ lastWritten += written;
+ lastRead += read;
+
+ }
+
+ public void circuitStatus(String status, String circID, String path) {
+
+ /* once the first circuit is complete, then announce that Orbot is on*/
+ if (mService.getCurrentStatus() == STATUS_STARTING && TextUtils.equals(status, "BUILT")){
+ mService.sendCallbackStatus(STATUS_ON);
+ }
+
+ if (Prefs.useDebugLogging()) {
+ StringBuilder sb = new StringBuilder();
+ sb.append("Circuit (");
+ sb.append((circID));
+ sb.append(") ");
+ sb.append(status);
+ sb.append(": ");
+
+ StringTokenizer st = new StringTokenizer(path, ",");
+ Node node;
+
+ boolean isFirstNode = true;
+ int nodeCount = st.countTokens();
+
+ while (st.hasMoreTokens()) {
+ String nodePath = st.nextToken();
+ String nodeId = null, nodeName = null;
+
+ String[] nodeParts;
+
+ if (nodePath.contains("="))
+ nodeParts = nodePath.split("=");
+ else
+ nodeParts = nodePath.split("~");
+
+ if (nodeParts.length == 1) {
+ nodeId = nodeParts[0].substring(1);
+ nodeName = nodeId;
+ } else if (nodeParts.length == 2) {
+ nodeId = nodeParts[0].substring(1);
+ nodeName = nodeParts[1];
+ }
+
+ if (nodeId == null)
+ continue;
+
+ node = hmBuiltNodes.get(nodeId);
+
+ if (node == null) {
+ node = new Node();
+ node.id = nodeId;
+ node.name = nodeName;
+ }
+
+ node.status = status;
+
+ sb.append(node.name);
+
+ if (!TextUtils.isEmpty(node.ipAddress))
+ sb.append("(").append(node.ipAddress).append(")");
+
+ if (st.hasMoreTokens())
+ sb.append(" > ");
+
+ if (status.equals("EXTENDED")) {
+
+ if (isFirstNode) {
+ hmBuiltNodes.put(node.id, node);
+
+ if (node.ipAddress == null && (!node.isFetchingInfo) && Prefs.useDebugLogging()) {
+ node.isFetchingInfo = true;
+ mService.exec(new ExternalIPFetcher(mService, node, OrbotService.mPortHTTP));
+ }
+
+ isFirstNode = false;
+ }
+ } else if (status.equals("BUILT")) {
+ // mService.logNotice(sb.toString());
+
+ if (Prefs.useDebugLogging() && nodeCount > 3)
+ mService.debug(sb.toString());
+ } else if (status.equals("CLOSED")) {
+ // mService.logNotice(sb.toString());
+ hmBuiltNodes.remove(node.id);
+ }
+
+ }
+
+
+ }
+
+
+ }
+
+ private String parseNodeName(String node) {
+ if (node.indexOf('=') != -1) {
+ return (node.substring(node.indexOf("=") + 1));
+ } else if (node.indexOf('~') != -1) {
+ return (node.substring(node.indexOf("~") + 1));
+ } else
+ return node;
+ }
+
+ public static class Node {
+ public String status;
+ public String id;
+ public String name;
+ public String ipAddress;
+ public String country;
+ public String organization;
+
+ public boolean isFetchingInfo = false;
+ }
+}
diff --git a/orbotmanager/src/main/java/org/torproject/android/service/TorServiceConstants.java b/orbotmanager/src/main/java/org/torproject/android/service/TorServiceConstants.java
index 82db6c6f..5ee4a778 100644
--- a/orbotmanager/src/main/java/org/torproject/android/service/TorServiceConstants.java
+++ b/orbotmanager/src/main/java/org/torproject/android/service/TorServiceConstants.java
@@ -9,14 +9,6 @@ public interface TorServiceConstants {
String DIRECTORY_TOR_DATA = "tordata";
- String TOR_CONTROL_PORT_FILE = "control.txt";
- String TOR_PID_FILE = "torpid";
-
- //torrc (tor config file)
- String TORRC_ASSET_KEY = "torrc";
-
- String TOR_CONTROL_COOKIE = "control_auth_cookie";
-
//geoip data file asset key
String GEOIP_ASSET_KEY = "geoip";
String GEOIP6_ASSET_KEY = "geoip6";
@@ -26,8 +18,8 @@ public interface TorServiceConstants {
int TOR_DNS_PORT_DEFAULT = 5400;
- String HTTP_PROXY_PORT_DEFAULT = "8125"; // like Privoxy!
- String SOCKS_PROXY_PORT_DEFAULT = "9055";
+ String HTTP_PROXY_PORT_DEFAULT = "8118"; // like Privoxy!
+ String SOCKS_PROXY_PORT_DEFAULT = "9050";
//control port
String LOG_NOTICE_HEADER = "NOTICE";
@@ -101,17 +93,16 @@ public interface TorServiceConstants {
String STATUS_STARTS_DISABLED = "STARTS_DISABLED";
// actions for internal command Intents
- String CMD_SIGNAL_HUP = "signal_hup";
- String CMD_NEWNYM = "newnym";
String CMD_SET_EXIT = "setexit";
String CMD_ACTIVE = "ACTIVE";
- String PREF_BINARY_TOR_VERSION_INSTALLED = "BINARY_TOR_VERSION_INSTALLED";
-
+ String CMD_NEWNYM = "newnym";
+ String CMD_SETTING = "setting";
//obfsproxy
String OBFSCLIENT_ASSET_KEY = "obfs4proxy";
String HIDDEN_SERVICES_DIR = "hidden_services";
-
+ String ONION_SERVICES_DIR = "v3_onion_services";
+ String V3_CLIENT_AUTH_DIR = "v3_client_auth";
}
diff --git a/orbotmanager/src/main/java/org/torproject/android/service/util/CustomNativeLoader.java b/orbotmanager/src/main/java/org/torproject/android/service/util/CustomNativeLoader.java
index 6504b8c7..fb528621 100644
--- a/orbotmanager/src/main/java/org/torproject/android/service/util/CustomNativeLoader.java
+++ b/orbotmanager/src/main/java/org/torproject/android/service/util/CustomNativeLoader.java
@@ -1,5 +1,6 @@
package org.torproject.android.service.util;
+import android.annotation.SuppressLint;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.os.Build;
@@ -16,6 +17,7 @@ public class CustomNativeLoader {
private final static String TAG = "CNL";
+ @SuppressLint("SetWorldReadable")
private static boolean loadFromZip(Context context, String libname, File destLocalFile, String arch) {
diff --git a/orbotmanager/src/main/java/org/torproject/android/service/util/CustomTorResourceInstaller.java b/orbotmanager/src/main/java/org/torproject/android/service/util/CustomTorResourceInstaller.java
index 8bec9ccc..fc8acde1 100644
--- a/orbotmanager/src/main/java/org/torproject/android/service/util/CustomTorResourceInstaller.java
+++ b/orbotmanager/src/main/java/org/torproject/android/service/util/CustomTorResourceInstaller.java
@@ -4,27 +4,23 @@ import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.util.Log;
-import org.torproject.android.binary.TorServiceConstants;
+import org.torproject.android.service.TorServiceConstants;
import java.io.File;
-import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
-import java.util.concurrent.TimeoutException;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
-public class CustomTorResourceInstaller implements TorServiceConstants {
+public class CustomTorResourceInstaller {
+ private static final String TAG = "CustomTorResourceInstaller";
private File installFolder;
private Context context;
- private File fileTorrc;
- private File fileTor;
-
public CustomTorResourceInstaller(Context context, File installFolder) {
this.installFolder = installFolder;
this.context = context;
@@ -40,7 +36,7 @@ public class CustomTorResourceInstaller implements TorServiceConstants {
* Write the inputstream contents to the file
*/
private static boolean streamToFile(InputStream stm, File outFile, boolean append, boolean zip) throws IOException {
- byte[] buffer = new byte[FILE_WRITE_BUFFER_SIZE];
+ byte[] buffer = new byte[1024];
int bytecount;
@@ -98,67 +94,14 @@ public class CustomTorResourceInstaller implements TorServiceConstants {
return fList;
}
- //
/*
* Extract the Tor resources from the APK file using ZIP
- *
- * @File path to the Tor executable
*/
- public File installResources() throws IOException, TimeoutException {
-
- fileTor = new File(installFolder, TOR_ASSET_KEY);
-
+ public void installGeoIP() throws IOException {
if (!installFolder.exists())
installFolder.mkdirs();
-
- installGeoIP();
- fileTorrc = assetToFile(COMMON_ASSET_KEY + TORRC_ASSET_KEY, TORRC_ASSET_KEY, false, false);
-
- File fileNativeDir = new File(getNativeLibraryDir(context));
- fileTor = new File(fileNativeDir, TOR_ASSET_KEY + ".so");
-
- if (fileTor.exists()) {
- if (fileTor.canExecute())
- return fileTor;
- else {
- setExecutable(fileTor);
-
- if (fileTor.canExecute())
- return fileTor;
- }
- }
-
- File fileTorBin = new File(installFolder, TOR_BINARY_KEY);
-
- //it exists but we can't execute it, so copy it to a new path
- if (fileTor.exists()) {
- InputStream is = new FileInputStream(fileTor);
- streamToFile(is, fileTorBin, false, true);
- setExecutable(fileTorBin);
-
- if (fileTorBin.exists() && fileTorBin.canExecute())
- return fileTorBin;
- }
-
- //let's try another approach
- fileTor = CustomNativeLoader.loadNativeBinary(context, TOR_ASSET_KEY, fileTorBin);
-
- if (fileTor != null && fileTor.exists())
- setExecutable(fileTor);
-
- if (fileTor != null && fileTor.exists() && fileTor.canExecute())
- return fileTor;
-
- return null;
- }
-
- private boolean installGeoIP() throws IOException {
-
- assetToFile(COMMON_ASSET_KEY + GEOIP_ASSET_KEY, GEOIP_ASSET_KEY, false, false);
-
- assetToFile(COMMON_ASSET_KEY + GEOIP6_ASSET_KEY, GEOIP6_ASSET_KEY, false, false);
-
- return true;
+ assetToFile(TorServiceConstants.GEOIP_ASSET_KEY, TorServiceConstants.GEOIP_ASSET_KEY, false, false);
+ assetToFile(TorServiceConstants.GEOIP6_ASSET_KEY, TorServiceConstants.GEOIP6_ASSET_KEY, false, false);
}
/*
diff --git a/orbotmanager/src/main/java/org/torproject/android/service/util/ExternalIPFetcher.java b/orbotmanager/src/main/java/org/torproject/android/service/util/ExternalIPFetcher.java
index 4addb2c5..957e1e65 100644
--- a/orbotmanager/src/main/java/org/torproject/android/service/util/ExternalIPFetcher.java
+++ b/orbotmanager/src/main/java/org/torproject/android/service/util/ExternalIPFetcher.java
@@ -2,8 +2,8 @@ package org.torproject.android.service.util;
import org.json.JSONArray;
import org.json.JSONObject;
-import org.torproject.android.proxy.OrbotService;
-import org.torproject.android.proxy.TorEventHandler;
+import org.torproject.android.service.OrbotService;
+import org.torproject.android.service.TorEventHandler;
import java.io.BufferedReader;
import java.io.InputStream;
@@ -18,7 +18,7 @@ public class ExternalIPFetcher implements Runnable {
private final static String ONIONOO_BASE_URL = "https://onionoo.torproject.org/details?fields=country_name,as_name,or_addresses&lookup=";
private OrbotService mService;
private TorEventHandler.Node mNode;
- private int mLocalHttpProxyPort = 8125;
+ private int mLocalHttpProxyPort = 8118;
public ExternalIPFetcher(OrbotService service, TorEventHandler.Node node, int localProxyPort) {
mService = service;
diff --git a/orbotmanager/src/main/java/org/torproject/android/service/util/NativeLoader.java b/orbotmanager/src/main/java/org/torproject/android/service/util/NativeLoader.java
index f97f68e0..c870025a 100644
--- a/orbotmanager/src/main/java/org/torproject/android/service/util/NativeLoader.java
+++ b/orbotmanager/src/main/java/org/torproject/android/service/util/NativeLoader.java
@@ -1,5 +1,6 @@
package org.torproject.android.service.util;
+import android.annotation.SuppressLint;
import android.content.Context;
import android.os.Build;
import android.util.Log;
@@ -15,6 +16,7 @@ public class NativeLoader {
private final static String TAG = "TorNativeLoader";
+ @SuppressLint("SetWorldReadable")
private static boolean loadFromZip(Context context, String libName, File destLocalFile, String folder) {
diff --git a/orbotmanager/src/main/java/org/torproject/android/service/util/Prefs.java b/orbotmanager/src/main/java/org/torproject/android/service/util/Prefs.java
index 8251fc88..aa39b7be 100644
--- a/orbotmanager/src/main/java/org/torproject/android/service/util/Prefs.java
+++ b/orbotmanager/src/main/java/org/torproject/android/service/util/Prefs.java
@@ -2,8 +2,8 @@ package org.torproject.android.service.util;
import android.content.Context;
import android.content.SharedPreferences;
-
import org.torproject.android.service.OrbotConstants;
+import org.torproject.android.service.wrapper.orbotLocalConstants;
import java.util.Locale;
@@ -20,6 +20,7 @@ public class Prefs {
private final static String PREF_OPEN_PROXY_ON_ALL_INTERFACES = "pref_open_proxy_on_all_interfaces";
private final static String PREF_USE_VPN = "pref_vpn";
private final static String PREF_EXIT_NODES = "pref_exit_nodes";
+ private final static String PREF_BE_A_SNOWFLAKE = "pref_be_a_snowflake";
private static SharedPreferences prefs;
@@ -50,6 +51,24 @@ public class Prefs {
String defaultBridgeType = "obfs4";
if (Locale.getDefault().getLanguage().equals("fa"))
defaultBridgeType = "meek"; //if Farsi, use meek as the default bridge type
+ if(orbotLocalConstants.mIsManualBridge){
+ if(!orbotLocalConstants.mManualBridgeType.equals("")){
+ defaultBridgeType = orbotLocalConstants.mManualBridgeType;
+ putString(PREF_BRIDGES_LIST, defaultBridgeType);
+ return defaultBridgeType;
+ }
+ }else {
+ if(orbotLocalConstants.mBridges.equals("obfs4")){
+ defaultBridgeType = "obfs4";
+ putString(PREF_BRIDGES_LIST, defaultBridgeType);
+ return defaultBridgeType;
+ }else if(orbotLocalConstants.mBridges.equals("meek")){
+ defaultBridgeType = "meek";
+ putString(PREF_BRIDGES_LIST, defaultBridgeType);
+ return defaultBridgeType;
+ }
+ }
+
return prefs.getString(PREF_BRIDGES_LIST, defaultBridgeType);
}
@@ -61,6 +80,14 @@ public class Prefs {
return prefs.getString(PREF_DEFAULT_LOCALE, Locale.getDefault().getLanguage());
}
+ public static boolean beSnowflakeProxy () {
+ return prefs.getBoolean(PREF_BE_A_SNOWFLAKE,false);
+ }
+
+ public static void setBeSnowflakeProxy (boolean beSnowflakeProxy) {
+ putBoolean(PREF_BE_A_SNOWFLAKE,beSnowflakeProxy);
+ }
+
public static void setDefaultLocale(String value) {
putString(PREF_DEFAULT_LOCALE, value);
}
@@ -70,16 +97,10 @@ public class Prefs {
}
public static boolean useDebugLogging() {
- if(prefs == null){
- return false;
- }
- return prefs.getBoolean(PREF_ENABLE_LOGGING, false);
+ return false;//prefs.getBoolean(PREF_ENABLE_LOGGING, false);
}
public static boolean persistNotifications() {
- if(prefs==null){
- return false;
- }
return prefs.getBoolean(PREF_PERSIST_NOTIFICATIONS, true);
}
@@ -118,4 +139,4 @@ public class Prefs {
public static SharedPreferences getSharedPrefs(Context context) {
return context.getSharedPreferences(OrbotConstants.PREF_TOR_SHARED_PREFS, Context.MODE_MULTI_PROCESS);
}
-}
+}
\ No newline at end of file
diff --git a/orbotmanager/src/main/java/org/torproject/android/service/vpn/OrbotVpnManager.java b/orbotmanager/src/main/java/org/torproject/android/service/vpn/OrbotVpnManager.java
index d9678b85..66538b04 100644
--- a/orbotmanager/src/main/java/org/torproject/android/service/vpn/OrbotVpnManager.java
+++ b/orbotmanager/src/main/java/org/torproject/android/service/vpn/OrbotVpnManager.java
@@ -34,9 +34,8 @@ import android.widget.Toast;
import com.runjva.sourceforge.jsocks.protocol.ProxyServer;
import com.runjva.sourceforge.jsocks.server.ServerAuthenticatorNone;
-import org.apache.commons.io.IOUtils;
-import org.torproject.android.proxy.OrbotService;
import org.torproject.android.service.OrbotConstants;
+import org.torproject.android.service.OrbotService;
import org.torproject.android.service.R;
import org.torproject.android.service.TorServiceConstants;
import org.torproject.android.service.util.CustomNativeLoader;
@@ -44,7 +43,6 @@ import org.torproject.android.service.util.Prefs;
import java.io.BufferedReader;
import java.io.File;
-import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
@@ -52,7 +50,6 @@ import java.io.InputStreamReader;
import java.io.PrintStream;
import java.net.InetAddress;
import java.util.ArrayList;
-import java.util.List;
import java.util.concurrent.TimeoutException;
import static org.torproject.android.service.TorServiceConstants.ACTION_START;
@@ -69,17 +66,17 @@ public class OrbotVpnManager implements Handler.Callback {
boolean isStarted = false;
File filePdnsPid;
private Thread mThreadVPN;
- private String mSessionName = "OrbotVPN";
+ private final static String mSessionName = "OrbotVPN";
private ParcelFileDescriptor mInterface;
private int mTorSocks = -1;
private int mTorDns = -1;
private int pdnsdPort = 8091;
private ProxyServer mSocksProxyServer;
- private File filePdnsd;
+ private final File filePdnsd;
private boolean isRestart = false;
- private VpnService mService;
+ private final VpnService mService;
- public OrbotVpnManager(VpnService service) throws IOException, TimeoutException {
+ public OrbotVpnManager(VpnService service) {
mService = service;
filePdnsd = CustomNativeLoader.loadNativeBinary(service.getApplicationContext(), PDNSD_BIN, new File(service.getFilesDir(), PDNSD_BIN));
Tun2Socks.init();
@@ -116,7 +113,7 @@ public class OrbotVpnManager implements Handler.Callback {
if (intent != null) {
String action = intent.getAction();
- if (!TextUtils.isEmpty(action)) {
+ if (action != null) {
if (action.equals(ACTION_START_VPN) || action.equals(ACTION_START)) {
Log.d(TAG, "starting VPN");
@@ -291,6 +288,11 @@ public class OrbotVpnManager implements Handler.Callback {
if (mIsLollipop)
doLollipopAppRouting(builder);
+ // https://developer.android.com/reference/android/net/VpnService.Builder#setMetered(boolean)
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
+ builder.setMetered(false);
+ }
+
// Create a new interface using the builder and save the parameters.
ParcelFileDescriptor newInterface = builder.setSession(mSessionName)
.setConfigureIntent(null) // previously this was set to a null member variable
@@ -380,11 +382,16 @@ public class OrbotVpnManager implements Handler.Callback {
}
- private boolean stopDns() {
+ private void stopDns() {
if (filePdnsPid != null && filePdnsPid.exists()) {
- List lines;
+ ArrayList lines = new ArrayList<>();
try {
- lines = IOUtils.readLines(new FileReader(filePdnsPid));
+ BufferedReader reader = new BufferedReader(new FileReader(filePdnsPid));
+
+ String line = null;
+ while ((line = reader.readLine())!= null)
+ lines.add(line);
+
String dnsPid = lines.get(0);
VpnUtils.killProcess(dnsPid, "");
filePdnsPid.delete();
@@ -393,7 +400,6 @@ public class OrbotVpnManager implements Handler.Callback {
Log.e("OrbotVPN", "error killing dns process", e);
}
}
- return false;
}
public boolean isStarted() {
diff --git a/orbotmanager/src/main/java/org/torproject/android/service/vpn/Tun2Socks.java b/orbotmanager/src/main/java/org/torproject/android/service/vpn/Tun2Socks.java
index 461a5a8d..8eda5954 100644
--- a/orbotmanager/src/main/java/org/torproject/android/service/vpn/Tun2Socks.java
+++ b/orbotmanager/src/main/java/org/torproject/android/service/vpn/Tun2Socks.java
@@ -50,7 +50,7 @@ public class Tun2Socks {
private static HashMap mAppUidBlacklist = new HashMap<>();
static {
- System.loadLibrary("tun2socks");
+ //System.loadLibrary("tun2socks");
}
public static void init() {
diff --git a/orbotmanager/src/main/java/org/torproject/android/proxy/wrapper/LocaleHelper.java b/orbotmanager/src/main/java/org/torproject/android/service/wrapper/LocaleHelper.java
similarity index 93%
rename from orbotmanager/src/main/java/org/torproject/android/proxy/wrapper/LocaleHelper.java
rename to orbotmanager/src/main/java/org/torproject/android/service/wrapper/LocaleHelper.java
index 5308f564..25248a72 100644
--- a/orbotmanager/src/main/java/org/torproject/android/proxy/wrapper/LocaleHelper.java
+++ b/orbotmanager/src/main/java/org/torproject/android/service/wrapper/LocaleHelper.java
@@ -1,11 +1,11 @@
-package org.torproject.android.proxy.wrapper;
+package org.torproject.android.service.wrapper;
import android.annotation.TargetApi;
import android.content.Context;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.os.Build;
-import org.torproject.android.proxy.util.Prefs;
+import org.torproject.android.service.util.Prefs;
import java.util.Locale;
diff --git a/orbotmanager/src/main/java/org/torproject/android/proxy/wrapper/localHelperMethod.java b/orbotmanager/src/main/java/org/torproject/android/service/wrapper/localHelperMethod.java
similarity index 91%
rename from orbotmanager/src/main/java/org/torproject/android/proxy/wrapper/localHelperMethod.java
rename to orbotmanager/src/main/java/org/torproject/android/service/wrapper/localHelperMethod.java
index 478edfb0..063a8161 100644
--- a/orbotmanager/src/main/java/org/torproject/android/proxy/wrapper/localHelperMethod.java
+++ b/orbotmanager/src/main/java/org/torproject/android/service/wrapper/localHelperMethod.java
@@ -1,4 +1,4 @@
-package org.torproject.android.proxy.wrapper;
+package org.torproject.android.service.wrapper;
import java.util.Calendar;
diff --git a/orbotmanager/src/main/java/org/torproject/android/proxy/wrapper/logRowModel.java b/orbotmanager/src/main/java/org/torproject/android/service/wrapper/logRowModel.java
similarity index 87%
rename from orbotmanager/src/main/java/org/torproject/android/proxy/wrapper/logRowModel.java
rename to orbotmanager/src/main/java/org/torproject/android/service/wrapper/logRowModel.java
index 48dddd87..3c748669 100644
--- a/orbotmanager/src/main/java/org/torproject/android/proxy/wrapper/logRowModel.java
+++ b/orbotmanager/src/main/java/org/torproject/android/service/wrapper/logRowModel.java
@@ -1,4 +1,4 @@
-package org.torproject.android.proxy.wrapper;
+package org.torproject.android.service.wrapper;
public class logRowModel {
/*Private Variables*/
diff --git a/orbotmanager/src/main/java/org/torproject/android/proxy/wrapper/orbotLocalConstants.java b/orbotmanager/src/main/java/org/torproject/android/service/wrapper/orbotLocalConstants.java
similarity index 91%
rename from orbotmanager/src/main/java/org/torproject/android/proxy/wrapper/orbotLocalConstants.java
rename to orbotmanager/src/main/java/org/torproject/android/service/wrapper/orbotLocalConstants.java
index 6d2873a0..b5b7e4f6 100644
--- a/orbotmanager/src/main/java/org/torproject/android/proxy/wrapper/orbotLocalConstants.java
+++ b/orbotmanager/src/main/java/org/torproject/android/service/wrapper/orbotLocalConstants.java
@@ -1,4 +1,4 @@
-package org.torproject.android.proxy.wrapper;
+package org.torproject.android.service.wrapper;
import android.content.Context;
import android.content.Intent;
diff --git a/orbotmanager/src/main/jniLibs b/orbotmanager/src/main/jniLibs
deleted file mode 100644
index 4dc6caa6..00000000
--- a/orbotmanager/src/main/jniLibs
+++ /dev/null
@@ -1 +0,0 @@
-libs
\ No newline at end of file
diff --git a/orbotmanager/src/main/jniLibs b/orbotmanager/src/main/jniLibs
new file mode 120000
index 00000000..37559697
--- /dev/null
+++ b/orbotmanager/src/main/jniLibs
@@ -0,0 +1 @@
+/home/morgan/Downloads/orbot-master/orbotservice/src/main/libs
\ No newline at end of file
diff --git a/orbotmanager/src/main/res/drawable-hdpi/ic_refresh_white_24dp.png b/orbotmanager/src/main/res/drawable-hdpi/ic_refresh_white_24dp.png
new file mode 100644
index 00000000..19bea38e
Binary files /dev/null and b/orbotmanager/src/main/res/drawable-hdpi/ic_refresh_white_24dp.png differ
diff --git a/orbotmanager/src/main/res/drawable-mdpi/ic_action_settings.png b/orbotmanager/src/main/res/drawable-mdpi/ic_action_settings.png
new file mode 100644
index 00000000..4b965fa7
Binary files /dev/null and b/orbotmanager/src/main/res/drawable-mdpi/ic_action_settings.png differ
diff --git a/orbotmanager/src/main/res/drawable-mdpi/ic_autorenew_black_36dp.png b/orbotmanager/src/main/res/drawable-mdpi/ic_autorenew_black_36dp.png
new file mode 100644
index 00000000..32a688d8
Binary files /dev/null and b/orbotmanager/src/main/res/drawable-mdpi/ic_autorenew_black_36dp.png differ
diff --git a/orbotmanager/src/main/res/drawable-mdpi/ic_filter_none_black_36dp.png b/orbotmanager/src/main/res/drawable-mdpi/ic_filter_none_black_36dp.png
new file mode 100644
index 00000000..c4a6d7d7
Binary files /dev/null and b/orbotmanager/src/main/res/drawable-mdpi/ic_filter_none_black_36dp.png differ
diff --git a/orbotmanager/src/main/res/drawable-mdpi/ic_launcher.png b/orbotmanager/src/main/res/drawable-mdpi/ic_launcher.png
new file mode 100644
index 00000000..d81f1159
Binary files /dev/null and b/orbotmanager/src/main/res/drawable-mdpi/ic_launcher.png differ
diff --git a/orbotmanager/src/main/res/drawable-mdpi/ic_playlist_add_check_black_36dp.png b/orbotmanager/src/main/res/drawable-mdpi/ic_playlist_add_check_black_36dp.png
new file mode 100644
index 00000000..0a3f63b8
Binary files /dev/null and b/orbotmanager/src/main/res/drawable-mdpi/ic_playlist_add_check_black_36dp.png differ
diff --git a/orbotmanager/src/main/res/drawable-mdpi/ic_refresh_white_24dp.png b/orbotmanager/src/main/res/drawable-mdpi/ic_refresh_white_24dp.png
new file mode 100644
index 00000000..99233274
Binary files /dev/null and b/orbotmanager/src/main/res/drawable-mdpi/ic_refresh_white_24dp.png differ
diff --git a/orbotmanager/src/main/res/drawable-mdpi/ic_stat_tor_xfer.png b/orbotmanager/src/main/res/drawable-mdpi/ic_stat_tor_xfer.png
new file mode 100644
index 00000000..ec893235
Binary files /dev/null and b/orbotmanager/src/main/res/drawable-mdpi/ic_stat_tor_xfer.png differ
diff --git a/orbotmanager/src/main/res/drawable-mdpi/inverse.png b/orbotmanager/src/main/res/drawable-mdpi/inverse.png
new file mode 100644
index 00000000..71e1adc5
Binary files /dev/null and b/orbotmanager/src/main/res/drawable-mdpi/inverse.png differ
diff --git a/orbotmanager/src/main/res/drawable-xxhdpi/ic_autorenew_black_36dp.png b/orbotmanager/src/main/res/drawable-xxhdpi/ic_autorenew_black_36dp.png
new file mode 100644
index 00000000..f5fcab1c
Binary files /dev/null and b/orbotmanager/src/main/res/drawable-xxhdpi/ic_autorenew_black_36dp.png differ
diff --git a/orbotmanager/src/main/res/drawable-xxhdpi/ic_filter_none_black_36dp.png b/orbotmanager/src/main/res/drawable-xxhdpi/ic_filter_none_black_36dp.png
new file mode 100644
index 00000000..b7a72182
Binary files /dev/null and b/orbotmanager/src/main/res/drawable-xxhdpi/ic_filter_none_black_36dp.png differ
diff --git a/orbotmanager/src/main/res/drawable-xxhdpi/ic_launcher.png b/orbotmanager/src/main/res/drawable-xxhdpi/ic_launcher.png
new file mode 100644
index 00000000..448c032b
Binary files /dev/null and b/orbotmanager/src/main/res/drawable-xxhdpi/ic_launcher.png differ
diff --git a/orbotmanager/src/main/res/drawable-xxhdpi/ic_playlist_add_check_black_36dp.png b/orbotmanager/src/main/res/drawable-xxhdpi/ic_playlist_add_check_black_36dp.png
new file mode 100644
index 00000000..aae1fc8d
Binary files /dev/null and b/orbotmanager/src/main/res/drawable-xxhdpi/ic_playlist_add_check_black_36dp.png differ
diff --git a/orbotmanager/src/main/res/drawable-xxhdpi/ic_refresh_white_24dp.png b/orbotmanager/src/main/res/drawable-xxhdpi/ic_refresh_white_24dp.png
new file mode 100644
index 00000000..535f3f01
Binary files /dev/null and b/orbotmanager/src/main/res/drawable-xxhdpi/ic_refresh_white_24dp.png differ
diff --git a/orbotmanager/src/main/res/drawable-xxhdpi/ic_stat_tor_xfer.png b/orbotmanager/src/main/res/drawable-xxhdpi/ic_stat_tor_xfer.png
new file mode 100644
index 00000000..b04b18e7
Binary files /dev/null and b/orbotmanager/src/main/res/drawable-xxhdpi/ic_stat_tor_xfer.png differ
diff --git a/orbotmanager/src/main/res/drawable-xxhdpi/inverse.png b/orbotmanager/src/main/res/drawable-xxhdpi/inverse.png
new file mode 100644
index 00000000..71e1adc5
Binary files /dev/null and b/orbotmanager/src/main/res/drawable-xxhdpi/inverse.png differ
diff --git a/orbotmanager/src/main/res/drawable-xxxhdpi/ic_autorenew_black_36dp.png b/orbotmanager/src/main/res/drawable-xxxhdpi/ic_autorenew_black_36dp.png
new file mode 100644
index 00000000..9c9a1f66
Binary files /dev/null and b/orbotmanager/src/main/res/drawable-xxxhdpi/ic_autorenew_black_36dp.png differ
diff --git a/orbotmanager/src/main/res/drawable-xxxhdpi/ic_filter_none_black_36dp.png b/orbotmanager/src/main/res/drawable-xxxhdpi/ic_filter_none_black_36dp.png
new file mode 100644
index 00000000..963e1951
Binary files /dev/null and b/orbotmanager/src/main/res/drawable-xxxhdpi/ic_filter_none_black_36dp.png differ
diff --git a/orbotmanager/src/main/res/drawable-xxxhdpi/ic_launcher.png b/orbotmanager/src/main/res/drawable-xxxhdpi/ic_launcher.png
new file mode 100644
index 00000000..6ae04dbf
Binary files /dev/null and b/orbotmanager/src/main/res/drawable-xxxhdpi/ic_launcher.png differ
diff --git a/orbotmanager/src/main/res/drawable-xxxhdpi/ic_playlist_add_check_black_36dp.png b/orbotmanager/src/main/res/drawable-xxxhdpi/ic_playlist_add_check_black_36dp.png
new file mode 100644
index 00000000..9a544026
Binary files /dev/null and b/orbotmanager/src/main/res/drawable-xxxhdpi/ic_playlist_add_check_black_36dp.png differ
diff --git a/orbotmanager/src/main/res/drawable-xxxhdpi/ic_refresh_white_24dp.png b/orbotmanager/src/main/res/drawable-xxxhdpi/ic_refresh_white_24dp.png
new file mode 100644
index 00000000..a9db32db
Binary files /dev/null and b/orbotmanager/src/main/res/drawable-xxxhdpi/ic_refresh_white_24dp.png differ
diff --git a/orbotmanager/src/main/res/drawable-xxxhdpi/ic_stat_tor_xfer.png b/orbotmanager/src/main/res/drawable-xxxhdpi/ic_stat_tor_xfer.png
new file mode 100644
index 00000000..82bb917c
Binary files /dev/null and b/orbotmanager/src/main/res/drawable-xxxhdpi/ic_stat_tor_xfer.png differ
diff --git a/orbotmanager/src/main/res/drawable-xxxhdpi/inverse.png b/orbotmanager/src/main/res/drawable-xxxhdpi/inverse.png
new file mode 100644
index 00000000..71e1adc5
Binary files /dev/null and b/orbotmanager/src/main/res/drawable-xxxhdpi/inverse.png differ
diff --git a/orbotmanager/src/test/java/org/torproject/android/control/.cvsignore b/orbotmanager/src/test/java/org/torproject/android/control/.cvsignore
deleted file mode 100644
index 6b468b62..00000000
--- a/orbotmanager/src/test/java/org/torproject/android/control/.cvsignore
+++ /dev/null
@@ -1 +0,0 @@
-*.class
diff --git a/orbotmanager/src/test/java/org/torproject/android/control/Bytes.java b/orbotmanager/src/test/java/org/torproject/android/control/Bytes.java
deleted file mode 100644
index e754d907..00000000
--- a/orbotmanager/src/test/java/org/torproject/android/control/Bytes.java
+++ /dev/null
@@ -1,114 +0,0 @@
-// Copyright 2005 Nick Mathewson, Roger Dingledine
-// See LICENSE file for copying information
-package org.torproject.android.control;
-
-import java.util.Arrays;
-import java.util.List;
-
-/**
- * Static class to do bytewise structure manipulation in Java.
- */
-/* XXXX There must be a better way to do most of this.
- * XXXX The string logic here uses default encoding, which is stupid.
- */
-final class Bytes {
-
- /** Write the two-byte value in 's' into the byte array 'ba', starting at
- * the index 'pos'. */
- public static void setU16(byte[] ba, int pos, short s) {
- ba[pos] = (byte)((s >> 8) & 0xff);
- ba[pos+1] = (byte)((s ) & 0xff);
- }
-
- /** Write the four-byte value in 'i' into the byte array 'ba', starting at
- * the index 'pos'. */
- public static void setU32(byte[] ba, int pos, int i) {
- ba[pos] = (byte)((i >> 24) & 0xff);
- ba[pos+1] = (byte)((i >> 16) & 0xff);
- ba[pos+2] = (byte)((i >> 8) & 0xff);
- ba[pos+3] = (byte)((i ) & 0xff);
- }
-
- /** Return the four-byte value starting at index 'pos' within 'ba' */
- public static int getU32(byte[] ba, int pos) {
- return
- ((ba[pos ]&0xff)<<24) |
- ((ba[pos+1]&0xff)<<16) |
- ((ba[pos+2]&0xff)<< 8) |
- ((ba[pos+3]&0xff));
- }
-
- public static String getU32S(byte[] ba, int pos) {
- return String.valueOf( (getU32(ba,pos))&0xffffffffL );
- }
-
- /** Return the two-byte value starting at index 'pos' within 'ba' */
- public static int getU16(byte[] ba, int pos) {
- return
- ((ba[pos ]&0xff)<<8) |
- ((ba[pos+1]&0xff));
- }
-
- /** Return the string starting at position 'pos' of ba and extending
- * until a zero byte or the end of the string. */
- public static String getNulTerminatedStr(byte[] ba, int pos) {
- int len, maxlen = ba.length-pos;
- for (len=0; len lst, byte[] ba, int pos, byte split) {
- while (pos < ba.length && ba[pos] != 0) {
- int len;
- for (len=0; pos+len < ba.length; ++len) {
- if (ba[pos+len] == 0 || ba[pos+len] == split)
- break;
- }
- if (len>0)
- lst.add(new String(ba, pos, len));
- pos += len;
- if (ba[pos] == split)
- ++pos;
- }
- }
-
- /**
- * Read bytes from 'ba' starting at 'pos', dividing them into strings
- * along the character in 'split' and writing them into 'lst'
- */
- public static List splitStr(List lst, String str) {
- // split string on spaces, include trailing/leading
- String[] tokenArray = str.split(" ", -1);
- if (lst == null) {
- lst = Arrays.asList( tokenArray );
- } else {
- lst.addAll( Arrays.asList( tokenArray ) );
- }
- return lst;
- }
-
- private static final char[] NYBBLES = {
- '0', '1', '2', '3', '4', '5', '6', '7',
- '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
- };
-
- public static final String hex(byte[] ba) {
- StringBuffer buf = new StringBuffer();
- for (int i = 0; i < ba.length; ++i) {
- int b = (ba[i]) & 0xff;
- buf.append(NYBBLES[b >> 4]);
- buf.append(NYBBLES[b&0x0f]);
- }
- return buf.toString();
- }
-
- private Bytes() {};
-}
-
diff --git a/orbotmanager/src/test/java/org/torproject/android/control/ConfigEntry.java b/orbotmanager/src/test/java/org/torproject/android/control/ConfigEntry.java
deleted file mode 100644
index 31eb4b8e..00000000
--- a/orbotmanager/src/test/java/org/torproject/android/control/ConfigEntry.java
+++ /dev/null
@@ -1,20 +0,0 @@
-// Copyright 2005 Nick Mathewson, Roger Dingledine
-// See LICENSE file for copying information
-package org.torproject.android.control;
-
-/** A single key-value pair from Tor's configuration. */
-public class ConfigEntry {
- public ConfigEntry(String k, String v) {
- key = k;
- value = v;
- is_default = false;
- }
- public ConfigEntry(String k) {
- key = k;
- value = "";
- is_default = true;
- }
- public final String key;
- public final String value;
- public final boolean is_default;
-}
diff --git a/orbotmanager/src/test/java/org/torproject/android/control/EventHandler.java b/orbotmanager/src/test/java/org/torproject/android/control/EventHandler.java
deleted file mode 100644
index 5a4e2b5b..00000000
--- a/orbotmanager/src/test/java/org/torproject/android/control/EventHandler.java
+++ /dev/null
@@ -1,75 +0,0 @@
-// Copyright 2005 Nick Mathewson, Roger Dingledine
-// See LICENSE file for copying information
-package org.torproject.android.control;
-
-/**
- * Abstract interface whose methods are invoked when Tor sends us an event.
- *
- * @see TorControlConnection#setEventHandler
- * @see TorControlConnection#setEvents
- */
-public interface EventHandler {
- /**
- * Invoked when a circuit's status has changed.
- * Possible values for status are:
- *
- * - "LAUNCHED" : circuit ID assigned to new circuit
- * - "BUILT" : all hops finished, can now accept streams
- * - "EXTENDED" : one more hop has been completed
- * - "FAILED" : circuit closed (was not built)
- * - "CLOSED" : circuit closed (was built)
- *
- *
- * circID is the alphanumeric identifier of the affected circuit,
- * and path is a comma-separated list of alphanumeric ServerIDs.
- */
- public void circuitStatus(String status, String circID, String path);
- /**
- * Invoked when a stream's status has changed.
- * Possible values for status are:
- *
- * - "NEW" : New request to connect
- * - "NEWRESOLVE" : New request to resolve an address
- * - "SENTCONNECT" : Sent a connect cell along a circuit
- * - "SENTRESOLVE" : Sent a resolve cell along a circuit
- * - "SUCCEEDED" : Received a reply; stream established
- * - "FAILED" : Stream failed and not retriable.
- * - "CLOSED" : Stream closed
- * - "DETACHED" : Detached from circuit; still retriable.
- *
- *
- * streamID is the alphanumeric identifier of the affected stream,
- * and its target is specified as address:port.
- */
- public void streamStatus(String status, String streamID, String target);
- /**
- * Invoked when the status of a connection to an OR has changed.
- * Possible values for status are ["LAUNCHED" | "CONNECTED" | "FAILED" | "CLOSED"].
- * orName is the alphanumeric identifier of the OR affected.
- */
- public void orConnStatus(String status, String orName);
- /**
- * Invoked once per second. read and written are
- * the number of bytes read and written, respectively, in
- * the last second.
- */
- public void bandwidthUsed(long read, long written);
- /**
- * Invoked whenever Tor learns about new ORs. The orList object
- * contains the alphanumeric ServerIDs associated with the new ORs.
- */
- public void newDescriptors(java.util.List orList);
- /**
- * Invoked when Tor logs a message.
- * severity is one of ["DEBUG" | "INFO" | "NOTICE" | "WARN" | "ERR"],
- * and msg is the message string.
- */
- public void message(String severity, String msg);
- /**
- * Invoked when an unspecified message is received.
- * is the message type, and is the message string.
- */
- public void unrecognized(String type, String msg);
-
-}
-
diff --git a/orbotmanager/src/test/java/org/torproject/android/control/PasswordDigest.java b/orbotmanager/src/test/java/org/torproject/android/control/PasswordDigest.java
deleted file mode 100644
index 03d0a98e..00000000
--- a/orbotmanager/src/test/java/org/torproject/android/control/PasswordDigest.java
+++ /dev/null
@@ -1,98 +0,0 @@
-// Copyright 2005 Nick Mathewson, Roger Dingledine
-// See LICENSE file for copying information
-package org.torproject.android.control;
-
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
-import java.security.SecureRandom;
-
-/**
- * A hashed digest of a secret password (used to set control connection
- * security.)
- *
- * For the actual hashing algorithm, see RFC2440's secret-to-key conversion.
- */
-public class PasswordDigest {
-
- private final byte[] secret;
- private final String hashedKey;
-
- /** Return a new password digest with a random secret and salt. */
- public static PasswordDigest generateDigest() {
- byte[] secret = new byte[20];
- SecureRandom rng = new SecureRandom();
- rng.nextBytes(secret);
- return new PasswordDigest(secret);
- }
-
- /** Construct a new password digest with a given secret and random salt */
- public PasswordDigest(byte[] secret) {
- this(secret, null);
- }
-
- /** Construct a new password digest with a given secret and random salt.
- * Note that the 9th byte of the specifier determines the number of hash
- * iterations as in RFC2440.
- */
- public PasswordDigest(byte[] secret, byte[] specifier) {
- this.secret = secret.clone();
- if (specifier == null) {
- specifier = new byte[9];
- SecureRandom rng = new SecureRandom();
- rng.nextBytes(specifier);
- specifier[8] = 96;
- }
- hashedKey = "16:"+encodeBytes(secretToKey(secret, specifier));
- }
-
- /** Return the secret used to generate this password hash.
- */
- public byte[] getSecret() {
- return secret.clone();
- }
-
- /** Return the hashed password in the format used by Tor. */
- public String getHashedPassword() {
- return hashedKey;
- }
-
- /** Parameter used by RFC2440's s2k algorithm. */
- private static final int EXPBIAS = 6;
-
- /** Implement rfc2440 s2k */
- public static byte[] secretToKey(byte[] secret, byte[] specifier) {
- MessageDigest d;
- try {
- d = MessageDigest.getInstance("SHA-1");
- } catch (NoSuchAlgorithmException ex) {
- throw new RuntimeException("Can't run without sha-1.");
- }
- int c = (specifier[8])&0xff;
- int count = (16 + (c&15)) << ((c>>4) + EXPBIAS);
-
- byte[] tmp = new byte[8+secret.length];
- System.arraycopy(specifier, 0, tmp, 0, 8);
- System.arraycopy(secret, 0, tmp, 8, secret.length);
- while (count > 0) {
- if (count >= tmp.length) {
- d.update(tmp);
- count -= tmp.length;
- } else {
- d.update(tmp, 0, count);
- count = 0;
- }
- }
- byte[] key = new byte[20+9];
- System.arraycopy(d.digest(), 0, key, 9, 20);
- System.arraycopy(specifier, 0, key, 0, 9);
- return key;
- }
-
- /** Return a hexadecimal encoding of a byte array. */
- // XXX There must be a better way to do this in Java.
- private static final String encodeBytes(byte[] ba) {
- return Bytes.hex(ba);
- }
-
-}
-
diff --git a/orbotmanager/src/test/java/org/torproject/android/control/README b/orbotmanager/src/test/java/org/torproject/android/control/README
deleted file mode 100644
index b310c7d5..00000000
--- a/orbotmanager/src/test/java/org/torproject/android/control/README
+++ /dev/null
@@ -1,4 +0,0 @@
-We broke the version detection stuff in Tor 0.1.2.16 / 0.2.0.4-alpha.
-Somebody should rip out the v0 control protocol stuff from here, and
-it should start working again. -RD
-
diff --git a/orbotmanager/src/test/java/org/torproject/android/control/TorControlCommands.java b/orbotmanager/src/test/java/org/torproject/android/control/TorControlCommands.java
deleted file mode 100644
index c98a1c48..00000000
--- a/orbotmanager/src/test/java/org/torproject/android/control/TorControlCommands.java
+++ /dev/null
@@ -1,148 +0,0 @@
-// Copyright 2005 Nick Mathewson, Roger Dingledine
-// See LICENSE file for copying information
-package org.torproject.android.control;
-
-/** Interface defining constants used by the Tor controller protocol.
- */
-// XXXX Take documentation for these from control-spec.txt
-public interface TorControlCommands {
-
- public static final short CMD_ERROR = 0x0000;
- public static final short CMD_DONE = 0x0001;
- public static final short CMD_SETCONF = 0x0002;
- public static final short CMD_GETCONF = 0x0003;
- public static final short CMD_CONFVALUE = 0x0004;
- public static final short CMD_SETEVENTS = 0x0005;
- public static final short CMD_EVENT = 0x0006;
- public static final short CMD_AUTH = 0x0007;
- public static final short CMD_SAVECONF = 0x0008;
- public static final short CMD_SIGNAL = 0x0009;
- public static final short CMD_MAPADDRESS = 0x000A;
- public static final short CMD_GETINFO = 0x000B;
- public static final short CMD_INFOVALUE = 0x000C;
- public static final short CMD_EXTENDCIRCUIT = 0x000D;
- public static final short CMD_ATTACHSTREAM = 0x000E;
- public static final short CMD_POSTDESCRIPTOR = 0x000F;
- public static final short CMD_FRAGMENTHEADER = 0x0010;
- public static final short CMD_FRAGMENT = 0x0011;
- public static final short CMD_REDIRECTSTREAM = 0x0012;
- public static final short CMD_CLOSESTREAM = 0x0013;
- public static final short CMD_CLOSECIRCUIT = 0x0014;
-
- public static final String[] CMD_NAMES = {
- "ERROR",
- "DONE",
- "SETCONF",
- "GETCONF",
- "CONFVALUE",
- "SETEVENTS",
- "EVENT",
- "AUTH",
- "SAVECONF",
- "SIGNAL",
- "MAPADDRESS",
- "GETINFO",
- "INFOVALUE",
- "EXTENDCIRCUIT",
- "ATTACHSTREAM",
- "POSTDESCRIPTOR",
- "FRAGMENTHEADER",
- "FRAGMENT",
- "REDIRECTSTREAM",
- "CLOSESTREAM",
- "CLOSECIRCUIT",
- };
-
- public static final short EVENT_CIRCSTATUS = 0x0001;
- public static final short EVENT_STREAMSTATUS = 0x0002;
- public static final short EVENT_ORCONNSTATUS = 0x0003;
- public static final short EVENT_BANDWIDTH = 0x0004;
- public static final short EVENT_NEWDESCRIPTOR = 0x0006;
- public static final short EVENT_MSG_DEBUG = 0x0007;
- public static final short EVENT_MSG_INFO = 0x0008;
- public static final short EVENT_MSG_NOTICE = 0x0009;
- public static final short EVENT_MSG_WARN = 0x000A;
- public static final short EVENT_MSG_ERROR = 0x000B;
-
- public static final String[] EVENT_NAMES = {
- "(0)",
- "CIRC",
- "STREAM",
- "ORCONN",
- "BW",
- "OLDLOG",
- "NEWDESC",
- "DEBUG",
- "INFO",
- "NOTICE",
- "WARN",
- "ERR",
- };
-
- public static final byte CIRC_STATUS_LAUNCHED = 0x01;
- public static final byte CIRC_STATUS_BUILT = 0x02;
- public static final byte CIRC_STATUS_EXTENDED = 0x03;
- public static final byte CIRC_STATUS_FAILED = 0x04;
- public static final byte CIRC_STATUS_CLOSED = 0x05;
-
- public static final String[] CIRC_STATUS_NAMES = {
- "LAUNCHED",
- "BUILT",
- "EXTENDED",
- "FAILED",
- "CLOSED",
- };
-
- public static final byte STREAM_STATUS_SENT_CONNECT = 0x00;
- public static final byte STREAM_STATUS_SENT_RESOLVE = 0x01;
- public static final byte STREAM_STATUS_SUCCEEDED = 0x02;
- public static final byte STREAM_STATUS_FAILED = 0x03;
- public static final byte STREAM_STATUS_CLOSED = 0x04;
- public static final byte STREAM_STATUS_NEW_CONNECT = 0x05;
- public static final byte STREAM_STATUS_NEW_RESOLVE = 0x06;
- public static final byte STREAM_STATUS_DETACHED = 0x07;
-
- public static final String[] STREAM_STATUS_NAMES = {
- "SENT_CONNECT",
- "SENT_RESOLVE",
- "SUCCEEDED",
- "FAILED",
- "CLOSED",
- "NEW_CONNECT",
- "NEW_RESOLVE",
- "DETACHED"
- };
-
- public static final byte OR_CONN_STATUS_LAUNCHED = 0x00;
- public static final byte OR_CONN_STATUS_CONNECTED = 0x01;
- public static final byte OR_CONN_STATUS_FAILED = 0x02;
- public static final byte OR_CONN_STATUS_CLOSED = 0x03;
-
- public static final String[] OR_CONN_STATUS_NAMES = {
- "LAUNCHED","CONNECTED","FAILED","CLOSED"
- };
-
- public static final byte SIGNAL_HUP = 0x01;
- public static final byte SIGNAL_INT = 0x02;
- public static final byte SIGNAL_USR1 = 0x0A;
- public static final byte SIGNAL_USR2 = 0x0C;
- public static final byte SIGNAL_TERM = 0x0F;
-
- public static final String ERROR_MSGS[] = {
- "Unspecified error",
- "Internal error",
- "Unrecognized message type",
- "Syntax error",
- "Unrecognized configuration key",
- "Invalid configuration value",
- "Unrecognized byte code",
- "Unauthorized",
- "Failed authentication attempt",
- "Resource exhausted",
- "No such stream",
- "No such circuit",
- "No such OR",
- };
-
-}
-
diff --git a/orbotmanager/src/test/java/org/torproject/android/control/TorControlConnection.java b/orbotmanager/src/test/java/org/torproject/android/control/TorControlConnection.java
deleted file mode 100644
index 204dbc06..00000000
--- a/orbotmanager/src/test/java/org/torproject/android/control/TorControlConnection.java
+++ /dev/null
@@ -1,730 +0,0 @@
-// Copyright 2005 Nick Mathewson, Roger Dingledine
-// See LICENSE file for copying information
-package org.torproject.android.control;
-
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.OutputStream;
-import java.io.OutputStreamWriter;
-import java.io.PrintStream;
-import java.io.PrintWriter;
-import java.io.Reader;
-import java.io.Writer;
-import java.net.Socket;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.StringTokenizer;
-
-/** A connection to a running Tor process as specified in control-spec.txt. */
-public class TorControlConnection implements TorControlCommands {
-
- private final LinkedList waiters;
- private final BufferedReader input;
- private final Writer output;
-
- private ControlParseThread thread; // Locking: this
-
- private volatile EventHandler handler;
- private volatile PrintWriter debugOutput;
- private volatile IOException parseThreadException;
-
- static class Waiter {
-
- List response; // Locking: this
-
- synchronized List getResponse() throws InterruptedException {
- while (response == null) {
- wait();
- }
- return response;
- }
-
- synchronized void setResponse(List response) {
- this.response = response;
- notifyAll();
- }
- }
-
- static class ReplyLine {
-
- final String status;
- final String msg;
- final String rest;
-
- ReplyLine(String status, String msg, String rest) {
- this.status = status; this.msg = msg; this.rest = rest;
- }
- }
-
- /** Create a new TorControlConnection to communicate with Tor over
- * a given socket. After calling this constructor, it is typical to
- * call launchThread and authenticate. */
- public TorControlConnection(Socket connection) throws IOException {
- this(connection.getInputStream(), connection.getOutputStream());
- }
-
- /** Create a new TorControlConnection to communicate with Tor over
- * an arbitrary pair of data streams.
- */
- public TorControlConnection(InputStream i, OutputStream o) {
- this(new InputStreamReader(i), new OutputStreamWriter(o));
- }
-
- public TorControlConnection(Reader i, Writer o) {
- this.output = o;
- if (i instanceof BufferedReader)
- this.input = (BufferedReader) i;
- else
- this.input = new BufferedReader(i);
- this.waiters = new LinkedList();
- }
-
- protected final void writeEscaped(String s) throws IOException {
- StringTokenizer st = new StringTokenizer(s, "\n");
- while (st.hasMoreTokens()) {
- String line = st.nextToken();
- if (line.startsWith("."))
- line = "."+line;
- if (line.endsWith("\r"))
- line += "\n";
- else
- line += "\r\n";
- if (debugOutput != null)
- debugOutput.print(">> "+line);
- output.write(line);
- }
- output.write(".\r\n");
- if (debugOutput != null)
- debugOutput.print(">> .\n");
- }
-
- protected static final String quote(String s) {
- StringBuffer sb = new StringBuffer("\"");
- for (int i = 0; i < s.length(); ++i) {
- char c = s.charAt(i);
- switch (c)
- {
- case '\r':
- case '\n':
- case '\\':
- case '\"':
- sb.append('\\');
- }
- sb.append(c);
- }
- sb.append('\"');
- return sb.toString();
- }
-
- protected final ArrayList readReply() throws IOException {
- ArrayList reply = new ArrayList();
- char c;
- do {
- String line = input.readLine();
- if (line == null) {
- // if line is null, the end of the stream has been reached, i.e.
- // the connection to Tor has been closed!
- if (reply.isEmpty()) {
- // nothing received so far, can exit cleanly
- return reply;
- }
- // received half of a reply before the connection broke down
- throw new TorControlSyntaxError("Connection to Tor " +
- " broke down while receiving reply!");
- }
- if (debugOutput != null)
- debugOutput.println("<< "+line);
- if (line.length() < 4)
- throw new TorControlSyntaxError("Line (\""+line+"\") too short");
- String status = line.substring(0,3);
- c = line.charAt(3);
- String msg = line.substring(4);
- String rest = null;
- if (c == '+') {
- StringBuffer data = new StringBuffer();
- while (true) {
- line = input.readLine();
- if (debugOutput != null)
- debugOutput.print("<< "+line);
- if (line.equals("."))
- break;
- else if (line.startsWith("."))
- line = line.substring(1);
- data.append(line).append('\n');
- }
- rest = data.toString();
- }
- reply.add(new ReplyLine(status, msg, rest));
- } while (c != ' ');
-
- return reply;
- }
-
- protected synchronized List sendAndWaitForResponse(String s,
- String rest) throws IOException {
- if(parseThreadException != null) throw parseThreadException;
- checkThread();
- Waiter w = new Waiter();
- if (debugOutput != null)
- debugOutput.print(">> "+s);
- synchronized (waiters) {
- output.write(s);
- if (rest != null)
- writeEscaped(rest);
- output.flush();
- waiters.addLast(w);
- }
- List lst;
- try {
- lst = w.getResponse();
- } catch (InterruptedException ex) {
- throw new IOException("Interrupted");
- }
- for (Iterator i = lst.iterator(); i.hasNext(); ) {
- ReplyLine c = i.next();
- if (! c.status.startsWith("2"))
- throw new TorControlError("Error reply: "+c.msg);
- }
- return lst;
- }
-
- /** Helper: decode a CMD_EVENT command and dispatch it to our
- * EventHandler (if any). */
- protected void handleEvent(ArrayList events) {
- if (handler == null)
- return;
-
- for (Iterator i = events.iterator(); i.hasNext(); ) {
- ReplyLine line = i.next();
- int idx = line.msg.indexOf(' ');
- String tp = line.msg.substring(0, idx).toUpperCase();
- String rest = line.msg.substring(idx+1);
- if (tp.equals("CIRC")) {
- List lst = Bytes.splitStr(null, rest);
- handler.circuitStatus(lst.get(1),
- lst.get(0),
- lst.get(1).equals("LAUNCHED")
- || lst.size() < 3 ? ""
- : lst.get(2));
- } else if (tp.equals("STREAM")) {
- List lst = Bytes.splitStr(null, rest);
- handler.streamStatus(lst.get(1),
- lst.get(0),
- lst.get(3));
- // XXXX circID.
- } else if (tp.equals("ORCONN")) {
- List lst = Bytes.splitStr(null, rest);
- handler.orConnStatus(lst.get(1), lst.get(0));
- } else if (tp.equals("BW")) {
- List lst = Bytes.splitStr(null, rest);
- handler.bandwidthUsed(Integer.parseInt(lst.get(0)),
- Integer.parseInt(lst.get(1)));
- } else if (tp.equals("NEWDESC")) {
- List lst = Bytes.splitStr(null, rest);
- handler.newDescriptors(lst);
- } else if (tp.equals("DEBUG") ||
- tp.equals("INFO") ||
- tp.equals("NOTICE") ||
- tp.equals("WARN") ||
- tp.equals("ERR")) {
- handler.message(tp, rest);
- } else {
- handler.unrecognized(tp, rest);
- }
- }
- }
-
-
- /** Sets w as the PrintWriter for debugging output,
- * which writes out all messages passed between Tor and the controller.
- * Outgoing messages are preceded by "\>\>" and incoming messages are preceded
- * by "\<\<"
- */
- public void setDebugging(PrintWriter w) {
- debugOutput = w;
- }
-
- /** Sets s as the PrintStream for debugging output,
- * which writes out all messages passed between Tor and the controller.
- * Outgoing messages are preceded by "\>\>" and incoming messages are preceded
- * by "\<\<"
- */
- public void setDebugging(PrintStream s) {
- debugOutput = new PrintWriter(s, true);
- }
-
- /** Set the EventHandler object that will be notified of any
- * events Tor delivers to this connection. To make Tor send us
- * events, call setEvents(). */
- public void setEventHandler(EventHandler handler) {
- this.handler = handler;
- }
-
- /**
- * Start a thread to react to Tor's responses in the background.
- * This is necessary to handle asynchronous events and synchronous
- * responses that arrive independantly over the same socket.
- */
- public synchronized Thread launchThread(boolean daemon) {
- ControlParseThread th = new ControlParseThread();
- if (daemon)
- th.setDaemon(true);
- th.start();
- this.thread = th;
- return th;
- }
-
- protected class ControlParseThread extends Thread {
-
- @Override
- public void run() {
- try {
- react();
- } catch (IOException ex) {
- parseThreadException = ex;
- }
- }
- }
-
- protected synchronized void checkThread() {
- if (thread == null)
- launchThread(true);
- }
-
- /** helper: implement the main background loop. */
- protected void react() throws IOException {
- while (true) {
- ArrayList lst = readReply();
- if (lst.isEmpty()) {
- // connection has been closed remotely! end the loop!
- return;
- }
- if ((lst.get(0)).status.startsWith("6"))
- handleEvent(lst);
- else {
- synchronized (waiters) {
- if (!waiters.isEmpty())
- {
- Waiter w;
- w = waiters.removeFirst();
- w.setResponse(lst);
- }
- }
-
- }
- }
- }
-
- /** Change the value of the configuration option 'key' to 'val'.
- */
- public void setConf(String key, String value) throws IOException {
- List lst = new ArrayList();
- lst.add(key+" "+value);
- setConf(lst);
- }
-
- /** Change the values of the configuration options stored in kvMap. */
- public void setConf(Map kvMap) throws IOException {
- List lst = new ArrayList();
- for (Iterator> it = kvMap.entrySet().iterator(); it.hasNext(); ) {
- Map.Entry ent = it.next();
- lst.add(ent.getKey()+" "+ent.getValue()+"\n");
- }
- setConf(lst);
- }
-
- /** Changes the values of the configuration options stored in
- * kvList. Each list element in kvList is expected to be
- * String of the format "key value".
- *
- * Tor behaves as though it had just read each of the key-value pairs
- * from its configuration file. Keywords with no corresponding values have
- * their configuration values reset to their defaults. setConf is
- * all-or-nothing: if there is an error in any of the configuration settings,
- * Tor sets none of them.
- *
- * When a configuration option takes multiple values, or when multiple
- * configuration keys form a context-sensitive group (see getConf below), then
- * setting any of the options in a setConf command is taken to reset all of
- * the others. For example, if two ORBindAddress values are configured, and a
- * command arrives containing a single ORBindAddress value, the new
- * command's value replaces the two old values.
- *
- * To remove all settings for a given option entirely (and go back to its
- * default value), include a String in kvList containing the key and no value.
- */
- public void setConf(Collection kvList) throws IOException {
- if (kvList.size() == 0)
- return;
- StringBuffer b = new StringBuffer("SETCONF");
- for (Iterator it = kvList.iterator(); it.hasNext(); ) {
- String kv = it.next();
- int i = kv.indexOf(' ');
- if (i == -1)
- b.append(" ").append(kv);
- b.append(" ").append(kv.substring(0,i)).append("=")
- .append(quote(kv.substring(i+1)));
- }
- b.append("\r\n");
- sendAndWaitForResponse(b.toString(), null);
- }
-
- /** Try to reset the values listed in the collection 'keys' to their
- * default values.
- **/
- public void resetConf(Collection keys) throws IOException {
- if (keys.size() == 0)
- return;
- StringBuffer b = new StringBuffer("RESETCONF");
- for (Iterator it = keys.iterator(); it.hasNext(); ) {
- String key = it.next();
- b.append(" ").append(key);
- }
- b.append("\r\n");
- sendAndWaitForResponse(b.toString(), null);
- }
-
- /** Return the value of the configuration option 'key' */
- public List getConf(String key) throws IOException {
- List lst = new ArrayList();
- lst.add(key);
- return getConf(lst);
- }
-
- /** Requests the values of the configuration variables listed in keys.
- * Results are returned as a list of ConfigEntry objects.
- *
- * If an option appears multiple times in the configuration, all of its
- * key-value pairs are returned in order.
- *
- * Some options are context-sensitive, and depend on other options with
- * different keywords. These cannot be fetched directly. Currently there
- * is only one such option: clients should use the "HiddenServiceOptions"
- * virtual keyword to get all HiddenServiceDir, HiddenServicePort,
- * HiddenServiceNodes, and HiddenServiceExcludeNodes option settings.
- */
- public List getConf(Collection keys) throws IOException {
- StringBuffer sb = new StringBuffer("GETCONF");
- for (Iterator it = keys.iterator(); it.hasNext(); ) {
- String key = it.next();
- sb.append(" ").append(key);
- }
- sb.append("\r\n");
- List lst = sendAndWaitForResponse(sb.toString(), null);
- List result = new ArrayList();
- for (Iterator it = lst.iterator(); it.hasNext(); ) {
- String kv = (it.next()).msg;
- int idx = kv.indexOf('=');
- if (idx >= 0)
- result.add(new ConfigEntry(kv.substring(0, idx),
- kv.substring(idx+1)));
- else
- result.add(new ConfigEntry(kv));
- }
- return result;
- }
-
- /** Request that the server inform the client about interesting events.
- * Each element of events is one of the following Strings:
- * ["CIRC" | "STREAM" | "ORCONN" | "BW" | "DEBUG" |
- * "INFO" | "NOTICE" | "WARN" | "ERR" | "NEWDESC" | "ADDRMAP"] .
- *
- * Any events not listed in the events are turned off; thus, calling
- * setEvents with an empty events argument turns off all event reporting.
- */
- public void setEvents(List events) throws IOException {
- StringBuffer sb = new StringBuffer("SETEVENTS");
- for (Iterator it = events.iterator(); it.hasNext(); ) {
- sb.append(" ").append(it.next());
- }
- sb.append("\r\n");
- sendAndWaitForResponse(sb.toString(), null);
- }
-
- /** Authenticates the controller to the Tor server.
- *
- * By default, the current Tor implementation trusts all local users, and
- * the controller can authenticate itself by calling authenticate(new byte[0]).
- *
- * If the 'CookieAuthentication' option is true, Tor writes a "magic cookie"
- * file named "control_auth_cookie" into its data directory. To authenticate,
- * the controller must send the contents of this file in auth.
- *
- * If the 'HashedControlPassword' option is set, auth must contain the salted
- * hash of a secret password. The salted hash is computed according to the
- * S2K algorithm in RFC 2440 (OpenPGP), and prefixed with the s2k specifier.
- * This is then encoded in hexadecimal, prefixed by the indicator sequence
- * "16:".
- *
- * You can generate the salt of a password by calling
- * 'tor --hash-password '
- * or by using the provided PasswordDigest class.
- * To authenticate under this scheme, the controller sends Tor the original
- * secret that was used to generate the password.
- */
- public void authenticate(byte[] auth) throws IOException {
- String cmd = "AUTHENTICATE " + Bytes.hex(auth) + "\r\n";
- sendAndWaitForResponse(cmd, null);
- }
-
- /** Instructs the server to write out its configuration options into its torrc.
- */
- public void saveConf() throws IOException {
- sendAndWaitForResponse("SAVECONF\r\n", null);
- }
-
- /** Sends a signal from the controller to the Tor server.
- * signal is one of the following Strings:
- *
- * - "RELOAD" or "HUP" : Reload config items, refetch directory
- * - "SHUTDOWN" or "INT" : Controlled shutdown: if server is an OP, exit immediately.
- * If it's an OR, close listeners and exit after 30 seconds
- * - "DUMP" or "USR1" : Dump stats: log information about open connections and circuits
- * - "DEBUG" or "USR2" : Debug: switch all open logs to loglevel debug
- * - "HALT" or "TERM" : Immediate shutdown: clean up and exit now
- *
- */
- public void signal(String signal) throws IOException {
- String cmd = "SIGNAL " + signal + "\r\n";
- sendAndWaitForResponse(cmd, null);
- }
-
- /** Send a signal to the Tor process to shut it down or halt it.
- * Does not wait for a response. */
- public void shutdownTor(String signal) throws IOException {
- String s = "SIGNAL " + signal + "\r\n";
- Waiter w = new Waiter();
- if (debugOutput != null)
- debugOutput.print(">> "+s);
- synchronized (waiters) {
- output.write(s);
- output.flush();
- }
- }
-
- /** Tells the Tor server that future SOCKS requests for connections to a set of original
- * addresses should be replaced with connections to the specified replacement
- * addresses. Each element of kvLines is a String of the form
- * "old-address new-address". This function returns the new address mapping.
- *
- * The client may decline to provide a body for the original address, and
- * instead send a special null address ("0.0.0.0" for IPv4, "::0" for IPv6, or
- * "." for hostname), signifying that the server should choose the original
- * address itself, and return that address in the reply. The server
- * should ensure that it returns an element of address space that is unlikely
- * to be in actual use. If there is already an address mapped to the
- * destination address, the server may reuse that mapping.
- *
- * If the original address is already mapped to a different address, the old
- * mapping is removed. If the original address and the destination address
- * are the same, the server removes any mapping in place for the original
- * address.
- *
- * Mappings set by the controller last until the Tor process exits:
- * they never expire. If the controller wants the mapping to last only
- * a certain time, then it must explicitly un-map the address when that
- * time has elapsed.
- */
- public Map mapAddresses(Collection kvLines) throws IOException {
- StringBuffer sb = new StringBuffer("MAPADDRESS");
- for (Iterator it = kvLines.iterator(); it.hasNext(); ) {
- String kv = it.next();
- int i = kv.indexOf(' ');
- sb.append(" ").append(kv.substring(0,i)).append("=")
- .append(quote(kv.substring(i+1)));
- }
- sb.append("\r\n");
- List lst = sendAndWaitForResponse(sb.toString(), null);
- Map result = new HashMap();
- for (Iterator it = lst.iterator(); it.hasNext(); ) {
- String kv = (it.next()).msg;
- int idx = kv.indexOf('=');
- result.put(kv.substring(0, idx),
- kv.substring(idx+1));
- }
- return result;
- }
-
- public Map mapAddresses(Map addresses) throws IOException {
- List kvList = new ArrayList();
- for (Iterator> it = addresses.entrySet().iterator(); it.hasNext(); ) {
- Map.Entry e = it.next();
- kvList.add(e.getKey()+" "+e.getValue());
- }
- return mapAddresses(kvList);
- }
-
- public String mapAddress(String fromAddr, String toAddr) throws IOException {
- List lst = new ArrayList();
- lst.add(fromAddr+" "+toAddr+"\n");
- Map m = mapAddresses(lst);
- return m.get(fromAddr);
- }
-
- /** Queries the Tor server for keyed values that are not stored in the torrc
- * configuration file. Returns a map of keys to values.
- *
- * Recognized keys include:
- *
- * - "version" : The version of the server's software, including the name
- * of the software. (example: "Tor 0.0.9.4")
- * - "desc/id/" or "desc/name/" : the latest server
- * descriptor for a given OR, NUL-terminated. If no such OR is known, the
- * corresponding value is an empty string.
- * - "network-status" : a space-separated list of all known OR identities.
- * This is in the same format as the router-status line in directories;
- * see tor-spec.txt for details.
- * - "addr-mappings/all"
- * - "addr-mappings/config"
- * - "addr-mappings/cache"
- * - "addr-mappings/control" : a space-separated list of address mappings, each
- * in the form of "from-address=to-address". The 'config' key
- * returns those address mappings set in the configuration; the 'cache'
- * key returns the mappings in the client-side DNS cache; the 'control'
- * key returns the mappings set via the control interface; the 'all'
- * target returns the mappings set through any mechanism.
- * - "circuit-status" : A series of lines as for a circuit status event. Each line is of the form:
- * "CircuitID CircStatus Path"
- * - "stream-status" : A series of lines as for a stream status event. Each is of the form:
- * "StreamID StreamStatus CircID Target"
- * - "orconn-status" : A series of lines as for an OR connection status event. Each is of the
- * form: "ServerID ORStatus"
- *
- */
- public Map getInfo(Collection keys) throws IOException {
- StringBuffer sb = new StringBuffer("GETINFO");
- for (Iterator it = keys.iterator(); it.hasNext(); ) {
- sb.append(" ").append(it.next());
- }
- sb.append("\r\n");
- List lst = sendAndWaitForResponse(sb.toString(), null);
- Map m = new HashMap();
- for (Iterator it = lst.iterator(); it.hasNext(); ) {
- ReplyLine line = it.next();
- int idx = line.msg.indexOf('=');
- if (idx<0)
- break;
- String k = line.msg.substring(0,idx);
- String v;
- if (line.rest != null) {
- v = line.rest;
- } else {
- v = line.msg.substring(idx+1);
- }
- m.put(k, v);
- }
- return m;
- }
-
-
-
- /** Return the value of the information field 'key' */
- public String getInfo(String key) throws IOException {
- List lst = new ArrayList();
- lst.add(key);
- Map m = getInfo(lst);
- return m.get(key);
- }
-
- /** An extendCircuit request takes one of two forms: either the circID is zero, in
- * which case it is a request for the server to build a new circuit according
- * to the specified path, or the circID is nonzero, in which case it is a
- * request for the server to extend an existing circuit with that ID according
- * to the specified path.
- *
- * If successful, returns the Circuit ID of the (maybe newly created) circuit.
- */
- public String extendCircuit(String circID, String path) throws IOException {
- List lst = sendAndWaitForResponse(
- "EXTENDCIRCUIT "+circID+" "+path+"\r\n", null);
- return (lst.get(0)).msg;
- }
-
- /** Informs the Tor server that the stream specified by streamID should be
- * associated with the circuit specified by circID.
- *
- * Each stream may be associated with
- * at most one circuit, and multiple streams may share the same circuit.
- * Streams can only be attached to completed circuits (that is, circuits that
- * have sent a circuit status "BUILT" event or are listed as built in a
- * getInfo circuit-status request).
- *
- * If circID is 0, responsibility for attaching the given stream is
- * returned to Tor.
- *
- * By default, Tor automatically attaches streams to
- * circuits itself, unless the configuration variable
- * "__LeaveStreamsUnattached" is set to "1". Attempting to attach streams
- * via TC when "__LeaveStreamsUnattached" is false may cause a race between
- * Tor and the controller, as both attempt to attach streams to circuits.
- */
- public void attachStream(String streamID, String circID)
- throws IOException {
- sendAndWaitForResponse("ATTACHSTREAM "+streamID+" "+circID+"\r\n", null);
- }
-
- /** Tells Tor about the server descriptor in desc.
- *
- * The descriptor, when parsed, must contain a number of well-specified
- * fields, including fields for its nickname and identity.
- */
- // More documentation here on format of desc?
- // No need for return value? control-spec.txt says reply is merely "250 OK" on success...
- public String postDescriptor(String desc) throws IOException {
- List lst = sendAndWaitForResponse("+POSTDESCRIPTOR\r\n", desc);
- return (lst.get(0)).msg;
- }
-
- /** Tells Tor to change the exit address of the stream identified by streamID
- * to address. No remapping is performed on the new provided address.
- *
- * To be sure that the modified address will be used, this event must be sent
- * after a new stream event is received, and before attaching this stream to
- * a circuit.
- */
- public void redirectStream(String streamID, String address) throws IOException {
- sendAndWaitForResponse("REDIRECTSTREAM "+streamID+" "+address+"\r\n",
- null);
- }
-
- /** Tells Tor to close the stream identified by streamID.
- * reason should be one of the Tor RELAY_END reasons given in tor-spec.txt, as a decimal:
- *
- * - 1 -- REASON_MISC (catch-all for unlisted reasons)
- * - 2 -- REASON_RESOLVEFAILED (couldn't look up hostname)
- * - 3 -- REASON_CONNECTREFUSED (remote host refused connection)
- * - 4 -- REASON_EXITPOLICY (OR refuses to connect to host or port)
- * - 5 -- REASON_DESTROY (Circuit is being destroyed)
- * - 6 -- REASON_DONE (Anonymized TCP connection was closed)
- * - 7 -- REASON_TIMEOUT (Connection timed out, or OR timed out while connecting)
- * - 8 -- (unallocated)
- * - 9 -- REASON_HIBERNATING (OR is temporarily hibernating)
- * - 10 -- REASON_INTERNAL (Internal error at the OR)
- * - 11 -- REASON_RESOURCELIMIT (OR has no resources to fulfill request)
- * - 12 -- REASON_CONNRESET (Connection was unexpectedly reset)
- * - 13 -- REASON_TORPROTOCOL (Sent when closing connection because of Tor protocol violations)
- *
- *
- * Tor may hold the stream open for a while to flush any data that is pending.
- */
- public void closeStream(String streamID, byte reason)
- throws IOException {
- sendAndWaitForResponse("CLOSESTREAM "+streamID+" "+reason+"\r\n",null);
- }
-
- /** Tells Tor to close the circuit identified by circID.
- * If ifUnused is true, do not close the circuit unless it is unused.
- */
- public void closeCircuit(String circID, boolean ifUnused) throws IOException {
- sendAndWaitForResponse("CLOSECIRCUIT "+circID+
- (ifUnused?" IFUNUSED":"")+"\r\n", null);
- }
-}
-
diff --git a/orbotmanager/src/test/java/org/torproject/android/control/TorControlError.java b/orbotmanager/src/test/java/org/torproject/android/control/TorControlError.java
deleted file mode 100644
index d07ee514..00000000
--- a/orbotmanager/src/test/java/org/torproject/android/control/TorControlError.java
+++ /dev/null
@@ -1,39 +0,0 @@
-// Copyright 2005 Nick Mathewson, Roger Dingledine
-// See LICENSE file for copying information
-package org.torproject.android.control;
-
-import java.io.IOException;
-
-/**
- * An exception raised when Tor tells us about an error.
- */
-public class TorControlError extends IOException {
-
- static final long serialVersionUID = 3;
-
- private final int errorType;
-
- public TorControlError(int type, String s) {
- super(s);
- errorType = type;
- }
-
- public TorControlError(String s) {
- this(-1, s);
- }
-
- public int getErrorType() {
- return errorType;
- }
-
- public String getErrorMsg() {
- try {
- if (errorType == -1)
- return null;
- return TorControlCommands.ERROR_MSGS[errorType];
- } catch (ArrayIndexOutOfBoundsException ex) {
- return "Unrecongized error #"+errorType;
- }
- }
-}
-
diff --git a/orbotmanager/src/test/java/org/torproject/android/control/TorControlSyntaxError.java b/orbotmanager/src/test/java/org/torproject/android/control/TorControlSyntaxError.java
deleted file mode 100644
index dba4f44b..00000000
--- a/orbotmanager/src/test/java/org/torproject/android/control/TorControlSyntaxError.java
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright 2005 Nick Mathewson, Roger Dingledine
-// See LICENSE file for copying information
-package org.torproject.android.control;
-
-import java.io.IOException;
-
-/**
- * An exception raised when Tor behaves in an unexpected way.
- */
-public class TorControlSyntaxError extends IOException {
-
- static final long serialVersionUID = 3;
-
- public TorControlSyntaxError(String s) { super(s); }
-}
-
diff --git a/orbotmanager/src/test/java/org/torproject/android/control/examples/.cvsignore b/orbotmanager/src/test/java/org/torproject/android/control/examples/.cvsignore
deleted file mode 100644
index 6b468b62..00000000
--- a/orbotmanager/src/test/java/org/torproject/android/control/examples/.cvsignore
+++ /dev/null
@@ -1 +0,0 @@
-*.class
diff --git a/orbotmanager/src/test/java/org/torproject/android/control/examples/DebuggingEventHandler.java b/orbotmanager/src/test/java/org/torproject/android/control/examples/DebuggingEventHandler.java
deleted file mode 100644
index 48c49a28..00000000
--- a/orbotmanager/src/test/java/org/torproject/android/control/examples/DebuggingEventHandler.java
+++ /dev/null
@@ -1,44 +0,0 @@
-// Copyright 2005 Nick Mathewson, Roger Dingledine
-// See LICENSE file for copying information
-package org.torproject.android.control.examples;
-
-import java.io.PrintWriter;
-import java.util.Iterator;
-import org.torproject.android.control.EventHandler;
-
-public class DebuggingEventHandler implements EventHandler {
-
- private final PrintWriter out;
-
- public DebuggingEventHandler(PrintWriter p) {
- out = p;
- }
-
- public void circuitStatus(String status, String circID, String path) {
- out.println("Circuit "+circID+" is now "+status+" (path="+path+")");
- }
- public void streamStatus(String status, String streamID, String target) {
- out.println("Stream "+streamID+" is now "+status+" (target="+target+")");
- }
- public void orConnStatus(String status, String orName) {
- out.println("OR connection to "+orName+" is now "+status);
- }
- public void bandwidthUsed(long read, long written) {
- out.println("Bandwidth usage: "+read+" bytes read; "+
- written+" bytes written.");
- }
- public void newDescriptors(java.util.List orList) {
- out.println("New descriptors for routers:");
- for (Iterator i = orList.iterator(); i.hasNext(); )
- out.println(" "+i.next());
- }
- public void message(String type, String msg) {
- out.println("["+type+"] "+msg.trim());
- }
-
- public void unrecognized(String type, String msg) {
- out.println("unrecognized event ["+type+"] "+msg.trim());
- }
-
-}
-
diff --git a/orbotmanager/src/test/java/org/torproject/android/control/examples/Main.java b/orbotmanager/src/test/java/org/torproject/android/control/examples/Main.java
deleted file mode 100644
index b0e0a3c0..00000000
--- a/orbotmanager/src/test/java/org/torproject/android/control/examples/Main.java
+++ /dev/null
@@ -1,146 +0,0 @@
-// Copyright 2005 Nick Mathewson, Roger Dingledine
-// See LICENSE file for copying information
-package org.torproject.android.control.examples;
-
-import org.torproject.android.control.*;
-import java.io.EOFException;
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.net.Socket;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Arrays;
-import java.util.Map;
-import java.util.Iterator;
-
-public class Main implements TorControlCommands {
-
- public static void main(String args[]) {
- if (args.length < 1) {
- System.err.println("No command given.");
- return;
- }
- try {
- if (args[0].equals("set-config")) {
- setConfig(args);
- } else if (args[0].equals("get-config")) {
- getConfig(args);
- } else if (args[0].equals("get-info")) {
- getInfo(args);
- } else if (args[0].equals("listen")) {
- listenForEvents(args);
- } else if (args[0].equals("signal")) {
- signal(args);
- } else if (args[0].equals("auth")) {
- authDemo(args);
- } else {
- System.err.println("Unrecognized command: "+args[0]);
- }
- } catch (EOFException ex) {
- System.out.println("Control socket closed by Tor.");
- } catch (TorControlError ex) {
- System.err.println("Error from Tor process: "+
- ex+" ["+ex.getErrorMsg()+"]");
- } catch (IOException ex) {
- System.err.println("IO exception when talking to Tor process: "+
- ex);
- ex.printStackTrace(System.err);
- }
- }
-
- private static TorControlConnection getConnection(String[] args,
- boolean daemon) throws IOException {
- Socket s = new Socket("127.0.0.1", 9100);
- TorControlConnection conn = new TorControlConnection(s);
- conn.launchThread(daemon);
- conn.authenticate(new byte[0]);
- return conn;
- }
-
- private static TorControlConnection getConnection(String[] args)
- throws IOException {
- return getConnection(args, true);
- }
-
- public static void setConfig(String[] args) throws IOException {
- // Usage: "set-config [-save] key value key value key value"
- TorControlConnection conn = getConnection(args);
- ArrayList lst = new ArrayList();
- int i = 1;
- boolean save = false;
- if (args[i].equals("-save")) {
- save = true;
- ++i;
- }
- for (; i < args.length; i +=2) {
- lst.add(args[i]+" "+args[i+1]);
- }
- conn.setConf(lst);
- if (save) {
- conn.saveConf();
- }
- }
-
- public static void getConfig(String[] args) throws IOException {
- // Usage: get-config key key key
- TorControlConnection conn = getConnection(args);
- List lst = conn.getConf(Arrays.asList(args).subList(1,args.length));
- for (Iterator i = lst.iterator(); i.hasNext(); ) {
- ConfigEntry e = i.next();
- System.out.println("KEY: "+e.key);
- System.out.println("VAL: "+e.value);
- }
- }
-
- public static void getInfo(String[] args) throws IOException {
- TorControlConnection conn = getConnection(args);
- Map m = conn.getInfo(Arrays.asList(args).subList(1,args.length));
- for (Iterator> i = m.entrySet().iterator(); i.hasNext(); ) {
- Map.Entry e = i.next();
- System.out.println("KEY: "+e.getKey());
- System.out.println("VAL: "+e.getValue());
- }
- }
-
- public static void listenForEvents(String[] args) throws IOException {
- // Usage: listen [circ|stream|orconn|bw|newdesc|info|notice|warn|error]*
- TorControlConnection conn = getConnection(args, false);
- ArrayList lst = new ArrayList();
- for (int i = 1; i < args.length; ++i) {
- lst.add(args[i]);
- }
- conn.setEventHandler(
- new DebuggingEventHandler(new PrintWriter(System.out, true)));
- conn.setEvents(lst);
- }
-
- public static void signal(String[] args) throws IOException {
- // Usage signal [reload|shutdown|dump|debug|halt]
- TorControlConnection conn = getConnection(args, false);
- // distinguish shutdown signal from other signals
- if ("SHUTDOWN".equalsIgnoreCase(args[1])
- || "HALT".equalsIgnoreCase(args[1])) {
- conn.shutdownTor(args[1].toUpperCase());
- } else {
- conn.signal(args[1].toUpperCase());
- }
- }
-
- public static void authDemo(String[] args) throws IOException {
-
- PasswordDigest pwd = PasswordDigest.generateDigest();
- Socket s = new Socket("127.0.0.1", 9100);
- TorControlConnection conn = new TorControlConnection(s);
- conn.launchThread(true);
- conn.authenticate(new byte[0]);
-
- conn.setConf("HashedControlPassword", pwd.getHashedPassword());
-
- s = new Socket("127.0.0.1", 9100);
- conn = new TorControlConnection(s);
- conn.launchThread(true);
- conn.authenticate(pwd.getSecret());
- }
-
-}
-
diff --git a/orbotmanager/src/test/java/org/torproject/android/proxy/ExampleUnitTest.java b/orbotmanager/src/test/java/org/torproject/android/proxy/ExampleUnitTest.java
deleted file mode 100644
index 25454778..00000000
--- a/orbotmanager/src/test/java/org/torproject/android/proxy/ExampleUnitTest.java
+++ /dev/null
@@ -1,15 +0,0 @@
-package org.torproject.android.proxy;
-
-import org.junit.Test;
-
-import static org.junit.Assert.*;
-
-/**
- * To work on unit tests, switch the Test Artifact in the Build Variants view.
- */
-public class ExampleUnitTest {
- @Test
- public void addition_isCorrect() throws Exception {
- assertEquals(4, 2 + 2);
- }
-}
\ No newline at end of file
diff --git a/orbotmanager/src/test/java/org/torproject/android/service/ExampleUnitTest.java b/orbotmanager/src/test/java/org/torproject/android/service/ExampleUnitTest.java
deleted file mode 100644
index 578fa4b9..00000000
--- a/orbotmanager/src/test/java/org/torproject/android/service/ExampleUnitTest.java
+++ /dev/null
@@ -1,15 +0,0 @@
-package org.torproject.android.service;
-
-import org.junit.Test;
-
-import static org.junit.Assert.*;
-
-/**
- * To work on unit tests, switch the Test Artifact in the Build Variants view.
- */
-public class ExampleUnitTest {
- @Test
- public void addition_isCorrect() throws Exception {
- assertEquals(4, 2 + 2);
- }
-}
\ No newline at end of file