/**
* Shadow - Anonymous web browser for Android devices
* Copyright (C) 2009 Connell Gauld
*
* Thanks to University of Cambridge,
* Alastair Beresford and Andrew Rice
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
*
* 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, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
package uk.ac.cam.cl.dtg.android.tor.Shadow;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InterruptedIOException;
import java.io.UnsupportedEncodingException;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.UnknownHostException;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.http.client.ClientProtocolException;
import uk.ac.cam.cl.dtg.android.tor.TorProxyLib.ITorProxyControl;
import uk.ac.cam.cl.dtg.android.tor.TorProxyLib.TorProxyLib;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.SearchManager;
import android.content.ActivityNotFoundException;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.content.SharedPreferences;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.LayerDrawable;
import android.graphics.drawable.PaintDrawable;
import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import android.preference.PreferenceManager;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.Window;
import android.view.View.OnClickListener;
import android.webkit.PluginData;
import android.webkit.UrlInterceptHandler;
import android.webkit.UrlInterceptRegistry;
import android.webkit.WebChromeClient;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.webkit.CacheManager.CacheResult;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.TextView;
/**
* The main browser activity
* @author Connell Gauld
*
*/
public class Shadow extends Activity implements UrlInterceptHandler,
OnClickListener {
// TorProxy service
private ITorProxyControl mControlService = null;
private final IntentFilter torStatusFilter = new IntentFilter(
TorProxyLib.STATUS_CHANGE_INTENT);
private AnonProxy mAnonProxy = null;
// UI elements
private ShadowWebView mWebView = null;
private LinearLayout mNoTorLayout = null;
private LinearLayout mWebLayout = null;
private Button mStartTor = null;
private LinearLayout mCookieIcon = null;
private TextView mTorStatus = null;
// Misc
private Drawable mGenericFavicon = null;
private boolean mInLoad = false;
private Menu mMenu = null;
private boolean mLastIsTorActive = true;
private CookieManager mCookieManager = null;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Set up title bar of window
this.requestWindowFeature(Window.FEATURE_LEFT_ICON);
this.requestWindowFeature(Window.FEATURE_RIGHT_ICON);
this.requestWindowFeature(Window.FEATURE_PROGRESS);
this.requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
// Allow search to start by just typing
setDefaultKeyMode(DEFAULT_KEYS_SEARCH_LOCAL);
setContentView(R.layout.main);
// Register to capture all URLs in the WebView
UrlInterceptRegistry.registerHandler(this);
mCookieManager = CookieManager.getInstance(this);
mAnonProxy = new AnonProxy();
// Grab UI elements
mWebView = (ShadowWebView) findViewById(R.id.WebView);
mNoTorLayout = (LinearLayout) findViewById(R.id.NoTorLayout);
mWebLayout = (LinearLayout) findViewById(R.id.WebLayout);
mStartTor = (Button) findViewById(R.id.StartTor);
mCookieIcon = (LinearLayout) findViewById(R.id.CookieIcon);
mTorStatus = (TextView) findViewById(R.id.torStatus);
// Set up UI elements
mStartTor.setOnClickListener(this);
mWebView.setWebViewClient(mWebViewClient);
mWebView.setWebChromeClient(mWebViewChrome);
mWebView.getSettings().setBuiltInZoomControls(true);
mWebView.getSettings().setLoadsImagesAutomatically(true);
mWebView.setBlockedCookiesView(mCookieIcon);
mCookieIcon.setOnClickListener(this);
// Misc
mGenericFavicon = getResources().getDrawable(
R.drawable.app_web_browser_sm);
// TODO - properly handle initial Intents
SharedPreferences prefs = PreferenceManager
.getDefaultSharedPreferences(this);
String starturl = prefs.getString(getString(R.string.pref_homepage),
getString(R.string.default_homepage));
mCookieManager.setBehaviour(prefs.getString("pref_cookiebehaviour",
"whitelist"));
Intent i = getIntent();
if (i != null) {
if (Intent.ACTION_VIEW.equals(i.getAction())) {
onNewIntent(i);
return;
}
}
loadUrl(starturl);
}
// Service connection to TorProxy service
private ServiceConnection mSvcConn = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
mControlService = ITorProxyControl.Stub.asInterface(service);
updateTorStatus();
}
@Override
public void onServiceDisconnected(ComponentName name) {
mControlService = null;
updateTorStatus();
}
};
/*
* Set the title bar icon to the supplied bitmap. Yoinked from the Android
* browser
*/
private void setFavicon(Bitmap icon) {
Drawable[] array = new Drawable[2];
PaintDrawable p = new PaintDrawable(Color.WHITE);
p.setCornerRadius(3f);
array[0] = p;
if (icon == null) {
array[1] = mGenericFavicon;
} else {
array[1] = new BitmapDrawable(icon);
}
LayerDrawable d = new LayerDrawable(array);
d.setLayerInset(1, 2, 2, 2, 2);
getWindow().setFeatureDrawable(Window.FEATURE_LEFT_ICON, d);
}
/**
* Yoinked from android source
*
* @param url
* @return
*/
private static String buildTitleUrl(String url) {
String titleUrl = null;
if (url != null) {
try {
// parse the url string
URL urlObj = new URL(url);
if (urlObj != null) {
titleUrl = "";
String protocol = urlObj.getProtocol();
String host = urlObj.getHost();
if (host != null && 0 < host.length()) {
titleUrl = host;
if (protocol != null) {
// if a secure site, add an "https://" prefix!
if (protocol.equalsIgnoreCase("https")) {
titleUrl = protocol + "://" + host;
}
}
}
}
} catch (MalformedURLException e) {
}
}
return titleUrl;
}
static final Pattern ACCEPTED_URI_SCHEMA = Pattern.compile("(?i)"
+ // switch on case insensitive matching
"("
+ // begin group for schema
"(?:http|https|file):\\/\\/"
+ "|(?:data|about|content|javascript):" + ")" + "(.*)");
private String smartUrlFilter(String url) {
String inUrl = url.trim();
boolean hasSpace = inUrl.indexOf(' ') != -1;
Matcher matcher = ACCEPTED_URI_SCHEMA.matcher(inUrl);
if (matcher.matches()) {
if (hasSpace) {
inUrl = inUrl.replace(" ", "%20");
}
// force scheme to lowercase
String scheme = matcher.group(1);
String lcScheme = scheme.toLowerCase();
if (!lcScheme.equals(scheme)) {
return lcScheme + matche
yxkfw
- 粉丝: 82
- 资源: 2万+
最新资源
- 基于OPENMV的视觉智能小车(车可自己动,实现方块,颜色识别)
- C# usb hid 设备控制
- MYSQL window安装包,版本8.0
- 三菱PLC药片自动装瓶机控制系统设计自动药片装瓶机电气控制
- 图形用户界面(GUI)应用程序
- 企业商户自动发卡运营版带WAP手机端【多种主题+亲测可用】
- Unity程序开发:创建一个2D平台游戏
- 矩形三维随机裂隙网络 使用COMSOL with Matlab接口编程 可以直接导入COMSOL中,无需CAD,无需提取数据,方便快捷可以直接计算 裂隙由matlab编程生成,能够生成两组不同产
- python+celery+AWVS 实现的漏洞扫描器
- 1.3M宽干式拉丝机(双道砂带)sw16可编辑全套技术资料100%好用.zip
- C# USB HID 读卡器 (CPU卡和IC卡的读和写)上位机源码
- EWSA中文版使用教程.doc
- 罗技鼠标接收器与罗技鼠标相连的软件
- 履带车底盘sw16全套技术资料100%好用.zip
- h2database 2.2.224 版本 Jar包
- 基于Springboot的梦宇飞行培训管理系统
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈