package com.duckduckgo.mobile.android.util;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.net.Uri;
import android.os.Build;
import android.webkit.WebView;
import android.widget.Toast;
import com.duckduckgo.mobile.android.R;
import com.duckduckgo.mobile.android.bus.BusProvider;
import com.duckduckgo.mobile.android.events.OrbotConnectedEvent;
import com.duckduckgo.mobile.android.network.DDGNetworkConstants;
import info.guardianproject.netcipher.proxy.OrbotHelper;
import info.guardianproject.netcipher.web.WebkitProxy;
/**
* This class implements methods for Tor integration, such as setting and resetting proxy.
*/
public class TorIntegration {
public static final int JELLY_BEAN_MR2 = 18;
private final Activity context;
private Dialog dialogOrbotInstall = null;
private Dialog dialogOrbotStart = null;
private String orbotStatus = OrbotHelper.STATUS_OFF;
public BroadcastReceiver orbotReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
orbotStatus = intent.getStringExtra(OrbotHelper.EXTRA_STATUS);
if(isTorSettingEnabled() && isOrbotRunning()) {
Toast.makeText(context, R.string.orbot_connected, Toast.LENGTH_SHORT).show();
BusProvider.getInstance().post(new OrbotConnectedEvent());
}
}
};
public TorIntegration(Activity context){
this.context = context;
}
public boolean prepareTorSettings(){
return prepareTorSettings(isTorSettingEnabled());
}
public boolean prepareTorSettings(boolean enableTor){
if(!isTorSupported()){
return false;
}
//DDGNetworkConstants.initializeMainClient(context.getApplication(), enableTor);
if(enableTor){
DDGNetworkConstants.initializeMainClient(context.getApplication(), enableTor);
enableOrbotProxy();
requestOrbotInstallAndStart();
}
else{
orbotStatus = OrbotHelper.STATUS_OFF;
resetProxy();
}
return true;
}
private void resetProxy() {
try {
WebkitProxy.resetProxy("com.duckduckgo.mobile.android.DDGApplication", DDGNetworkConstants.getWebView().getContext().getApplicationContext());
} catch (Exception e) {
e.printStackTrace();
}
}
public void resetProxy(WebView webView) {
try {
WebkitProxy.resetProxy("com.duckduckgo.mobile.android.DDGApplication", webView.getContext().getApplicationContext());
} catch (Exception e) {
e.printStackTrace();
}
}
private void enableOrbotProxy() {
try {
WebkitProxy.setProxy("com.duckduckgo.mobile.android.DDGApplication", DDGNetworkConstants.getWebView().getContext().getApplicationContext(), DDGNetworkConstants.getWebView(), DDGNetworkConstants.PROXY_HOST, DDGNetworkConstants.PROXY_HTTP_PORT);
} catch (Exception e) {
// what should we do here? Discuss!
e.printStackTrace();
}
}
public void enableOrbotProxy(WebView webView) {
try {
WebkitProxy.setProxy("com.duckduckgo.mobile.android.DDGApplication", webView.getContext().getApplicationContext(), webView, DDGNetworkConstants.PROXY_HOST, DDGNetworkConstants.PROXY_HTTP_PORT);
} catch (Exception e) {
// what should we do here? Discuss!
e.printStackTrace();
}
}
private void requestOrbotInstallAndStart() {
if (!OrbotHelper.isOrbotInstalled(context)){
promptToInstall();
}
else if (!isOrbotRunning()){
requestOrbotStart();
}
}
/**
* if showing this will dismiss and release all the dialogs generated by TorIntegration
*/
public void dismissDialogs(){
dismissOrbotStartDialog();
dismissOrbotPromptDialog();
}
/**
* This method will dismiss prompt dialog if visible.
*/
public void dismissOrbotPromptDialog(){
if(dialogOrbotInstall != null && dialogOrbotInstall.isShowing()){
dialogOrbotInstall.dismiss();
dialogOrbotInstall = null;
}
}
/**
* This method is same as OrbotHelper.promptToInstall except dismisses the previous dialogs and stores the reference of new one.
*/
public void promptToInstall() {
// show dialog - install from market, f-droid or direct APK
dialogOrbotInstall = showDownloadDialog(context.getString(R.string.orbot_install_title),
context.getString(R.string.orbot_install_message),
context.getString(R.string.Yes), context.getString(R.string.No));
}
/**
* This method is taken from OrbotHelper it uses same resource strings but returns the dialog instead.
* @return AlertDialog instance which can be used later to dismiss when activity is destroying
*/
private AlertDialog showDownloadDialog(CharSequence stringTitle, CharSequence stringMessage, CharSequence stringButtonYes,
CharSequence stringButtonNo) {
AlertDialog.Builder downloadDialog = new AlertDialog.Builder(context);
downloadDialog.setTitle(stringTitle);
downloadDialog.setMessage(stringMessage);
downloadDialog.setPositiveButton(stringButtonYes, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
OrbotHelper.get(context).installOrbot(context);
}
});
downloadDialog.setNegativeButton(stringButtonNo, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
}
});
return downloadDialog.show();
}
/**
* This method will dismiss prompt dialog if visible.
*/
public void dismissOrbotStartDialog(){
if(dialogOrbotStart != null && dialogOrbotStart.isShowing()){
dialogOrbotStart.dismiss();
dialogOrbotStart = null;
}
}
public void requestOrbotStart() {
boolean dialogIsAlreadyShown = dialogOrbotStart != null;
dismissOrbotStartDialog();
AlertDialog.Builder downloadDialog = new AlertDialog.Builder(context);
downloadDialog.setTitle(R.string.orbot_start_title);
downloadDialog
.setMessage(dialogIsAlreadyShown ? R.string.orbot_start_message_manually : R.string.orbot_start_message);
downloadDialog.setPositiveButton(R.string.Yes, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
startOrbot();
}
});
downloadDialog.setNegativeButton(R.string.No, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
dialogOrbotStart = null;
}
});
dialogOrbotStart = downloadDialog.show();
}
private void startOrbot() {
OrbotHelper.requestStartTor(context);
/*
boolean result = OrbotHelper.get(context).init();
if(!result) {
promptToInstall();
}*/
}
private boolean isOrbotRunning() {
return OrbotHelper.isOrbotRunning(context) || orbotStatus.equals(OrbotHelper.STATUS_ON);
}
public boolean isTorSettingEnabled() {
return PreferencesManager.getEnableTor();
}
public boolean isOrbotRunningAccordingToSettings() {
return !isTorSettingEnabled() || isTorEnabledAndOrbotRunning();
}
private boolean isTorEnabledAndOrbotRunning(){
return isTorSettingEnabled() &&
OrbotHelper.isOrbotInstalled(context) &&
isOrbotRunning();
}
public boolean isTorSupported() {
return true; //Build.VERSION.SDK_INT <= JELLY_BEAN_MR2;
}
}