Lightning browser with I2P configuration
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

2234 lines
63 KiB

/*
* Copyright 2014 A.C.R. Development
*/
package acr.browser.lightning;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import acr.browser.lightning.BrowserActivity.SortIgnoreCase;
import android.app.ActionBar;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.res.Configuration;
import android.content.res.Resources.Theme;
import android.content.res.TypedArray;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteException;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.media.MediaPlayer;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Message;
import android.provider.Browser;
import android.support.v4.app.ActionBarDrawerToggle;
import android.support.v4.widget.DrawerLayout;
import android.text.TextUtils;
import android.util.Log;
import android.util.TypedValue;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnKeyListener;
import android.view.View.OnTouchListener;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputMethodManager;
import android.webkit.ValueCallback;
import android.webkit.WebChromeClient.CustomViewCallback;
import android.webkit.CookieManager;
import android.webkit.CookieSyncManager;
import android.webkit.WebIconDatabase;
import android.webkit.WebView;
import android.webkit.WebView.HitTestResult;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.EditText;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.AutoCompleteTextView;
import android.widget.ProgressBar;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.VideoView;
import android.widget.TextView.OnEditorActionListener;
public class IncognitoActivity extends Activity implements BrowserController {
private static DrawerLayout mDrawerLayout;
private static ListView mDrawerList;
private static RelativeLayout mDrawer;
private static LinearLayout mDrawerRight;
private static ListView mDrawerListRight;
private static TextView mNewTab;
private static ActionBarDrawerToggle mDrawerToggle;
private List<LightningView> mWebViews = new ArrayList<LightningView>();
private static List<Integer> mIdList = new ArrayList<Integer>();
private LightningView mCurrentView;
private static int mIdGenerator;
private static LightningViewAdapter mTitleAdapter;
private static List<HistoryItem> mBookmarkList;
private static BookmarkViewAdapter mBookmarkAdapter;
private static AutoCompleteTextView mSearch;
private static ClickHandler mClickHandler;
private static ProgressBar mProgress;
private static boolean mSystemBrowser = false;
private static ValueCallback<Uri> mUploadMessage;
private static View mCustomView;
private static int mOriginalOrientation;
private static int mActionBarSize;
private static ActionBar mActionBar;
private static boolean mFullScreen;
private static FrameLayout mBrowserFrame;
private static FullscreenHolder mFullscreenContainer;
private static CustomViewCallback mCustomViewCallback;
private static final FrameLayout.LayoutParams COVER_SCREEN_PARAMS = new FrameLayout.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT);
private static Bitmap mDefaultVideoPoster;
private static View mVideoProgressView;
private static DatabaseHandler mHistoryHandler;
private static SQLiteDatabase mHistoryDatabase;
private static SharedPreferences mPreferences;
private static SharedPreferences.Editor mEditPrefs;
private static Context mContext;
private static Bitmap mWebpageBitmap;
private static String mSearchText;
private static Activity mActivity;
private static CookieManager mCookieManager;
private static final int API = android.os.Build.VERSION.SDK_INT;
private static Drawable mDeleteIcon;
private static Drawable mRefreshIcon;
private static Drawable mCopyIcon;
private static Drawable mIcon;
private static int mActionBarSizeDp;
private static String mHomepage;
private static boolean mIsNewIntent = false;
private static VideoView mVideoView;
private static SearchAdapter mSearchAdapter;
private static BitmapDrawable mIncognitoIcon;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
initialize();
}
private synchronized void initialize() {
setContentView(R.layout.activity_main);
TypedValue typedValue = new TypedValue();
Theme theme = getTheme();
theme.resolveAttribute(R.attr.numberColor, typedValue, true);
mPreferences = getSharedPreferences(PreferenceConstants.PREFERENCES, 0);
mEditPrefs = mPreferences.edit();
mContext = this;
if (mIdList != null) {
mIdList.clear();
} else {
mIdList = new ArrayList<Integer>();
}
if (mWebViews != null) {
mWebViews.clear();
} else {
mWebViews = new ArrayList<LightningView>();
}
mActivity = this;
mClickHandler = new ClickHandler(this);
mBrowserFrame = (FrameLayout) findViewById(R.id.content_frame);
mProgress = (ProgressBar) findViewById(R.id.activity_bar);
mProgress.setVisibility(View.GONE);
mNewTab = (TextView) findViewById(R.id.new_tab_button);
mDrawer = (RelativeLayout) findViewById(R.id.drawer);
mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
mDrawerList = (ListView) findViewById(R.id.left_drawer);
mDrawerRight = (LinearLayout) findViewById(R.id.right_drawer);
mDrawerListRight = (ListView) findViewById(R.id.right_drawer_list);
Bitmap bm = BitmapFactory.decodeResource(getResources(),
R.drawable.ic_action_incognito);
mIncognitoIcon = new BitmapDrawable(getResources(), bm);
mWebpageBitmap = BitmapFactory.decodeResource(getResources(),
R.drawable.ic_webpage);
mActionBar = getActionBar();
final TypedArray styledAttributes = mContext.getTheme()
.obtainStyledAttributes(
new int[] { android.R.attr.actionBarSize });
mActionBarSize = (int) styledAttributes.getDimension(0, 0);
if (pixelsToDp(mActionBarSize) < 48) {
mActionBarSize = getDp(48);
}
mActionBarSizeDp = pixelsToDp(mActionBarSize);
styledAttributes.recycle();
mHomepage = mPreferences.getString(PreferenceConstants.HOMEPAGE,
Constants.HOMEPAGE);
mTitleAdapter = new LightningViewAdapter(this, R.layout.tab_list_item,
mWebViews);
mDrawerList.setAdapter(mTitleAdapter);
mDrawerList.setOnItemClickListener(new DrawerItemClickListener());
mDrawerList
.setOnItemLongClickListener(new DrawerItemLongClickListener());
mBookmarkList = getBookmarks();
mBookmarkAdapter = new BookmarkViewAdapter(this,
R.layout.bookmark_list_item, mBookmarkList);
mDrawerListRight.setAdapter(mBookmarkAdapter);
mDrawerListRight
.setOnItemClickListener(new BookmarkItemClickListener());
mDrawerListRight
.setOnItemLongClickListener(new BookmarkItemLongClickListener());
if (mHistoryHandler == null) {
mHistoryHandler = new DatabaseHandler(this);
} else if (!mHistoryHandler.isOpen()) {
mHistoryHandler = new DatabaseHandler(this);
}
mHistoryDatabase = mHistoryHandler.getReadableDatabase();
// set display options of the ActionBar
mActionBar.setDisplayShowTitleEnabled(false);
mActionBar.setDisplayShowCustomEnabled(true);
mActionBar.setDisplayShowHomeEnabled(true);
mActionBar.setDisplayHomeAsUpEnabled(true);
mActionBar.setCustomView(R.layout.search);
RelativeLayout back = (RelativeLayout) findViewById(R.id.action_back);
RelativeLayout forward = (RelativeLayout) findViewById(R.id.action_forward);
if (back != null) {
back.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if (mCurrentView != null) {
if (mCurrentView.canGoBack()) {
mCurrentView.goBack();
} else {
deleteTab(mDrawerList.getCheckedItemPosition());
}
}
}
});
}
if (forward != null) {
forward.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if (mCurrentView != null) {
if (mCurrentView.canGoForward()) {
mCurrentView.goForward();
}
}
}
});
}
// create the search EditText in the ActionBar
mSearch = (AutoCompleteTextView) mActionBar.getCustomView()
.findViewById(R.id.search);
mDeleteIcon = getResources().getDrawable(R.drawable.ic_action_delete);
mDeleteIcon.setBounds(0, 0, Utils.convertToDensityPixels(mContext, 24),
Utils.convertToDensityPixels(mContext, 24));
mRefreshIcon = getResources().getDrawable(R.drawable.ic_action_refresh);
mRefreshIcon.setBounds(0, 0,
Utils.convertToDensityPixels(mContext, 24),
Utils.convertToDensityPixels(mContext, 24));
mCopyIcon = getResources().getDrawable(R.drawable.ic_action_copy);
mCopyIcon.setBounds(0, 0, Utils.convertToDensityPixels(mContext, 24),
Utils.convertToDensityPixels(mContext, 24));
mIcon = mRefreshIcon;
mSearch.setCompoundDrawables(null, null, mRefreshIcon, null);
mSearch.setOnKeyListener(new OnKeyListener() {
@Override
public boolean onKey(View arg0, int arg1, KeyEvent arg2) {
switch (arg1) {
case KeyEvent.KEYCODE_ENTER:
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(mSearch.getWindowToken(), 0);
searchTheWeb(mSearch.getText().toString());
if (mCurrentView != null) {
mCurrentView.requestFocus();
}
return true;
default:
break;
}
return false;
}
});
mSearch.setOnFocusChangeListener(new View.OnFocusChangeListener() {
@Override
public void onFocusChange(View v, boolean hasFocus) {
if (!hasFocus && mCurrentView != null) {
if (mCurrentView != null) {
if (mCurrentView.getProgress() < 100) {
setIsLoading();
} else {
setIsFinishedLoading();
}
}
updateUrl(mCurrentView.getUrl());
} else if (hasFocus) {
mIcon = mCopyIcon;
mSearch.setCompoundDrawables(null, null, mCopyIcon, null);
}
}
});
mSearch.setOnEditorActionListener(new OnEditorActionListener() {
@Override
public boolean onEditorAction(TextView arg0, int actionId,
KeyEvent arg2) {
// hide the keyboard and search the web when the enter key
// button is pressed
if (actionId == EditorInfo.IME_ACTION_GO
|| actionId == EditorInfo.IME_ACTION_DONE
|| actionId == EditorInfo.IME_ACTION_NEXT
|| actionId == EditorInfo.IME_ACTION_SEND
|| actionId == EditorInfo.IME_ACTION_SEARCH
|| (arg2.getAction() == KeyEvent.KEYCODE_ENTER)) {
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(mSearch.getWindowToken(), 0);
searchTheWeb(mSearch.getText().toString());
if (mCurrentView != null) {
mCurrentView.requestFocus();
}
return true;
}
return false;
}
});
mSearch.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
if (mSearch.getCompoundDrawables()[2] != null) {
boolean tappedX = event.getX() > (mSearch.getWidth()
- mSearch.getPaddingRight() - mIcon
.getIntrinsicWidth());
if (tappedX) {
if (event.getAction() == MotionEvent.ACTION_UP) {
if (mSearch.hasFocus()) {
ClipboardManager clipboard = (ClipboardManager) getSystemService(CLIPBOARD_SERVICE);
ClipData clip = ClipData.newPlainText("label",
mSearch.getText().toString());
clipboard.setPrimaryClip(clip);
Utils.showToast(
mContext,
mContext.getResources().getString(
R.string.message_text_copied));
} else {
refreshOrStop();
}
}
return true;
}
}
return false;
}
});
mSystemBrowser = getSystemBrowser();
Thread initialize = new Thread(new Runnable() {
@Override
public void run() {
initializeSearchSuggestions(mSearch);
}
});
initialize.run();
// ActionBarDrawerToggle ties together the the proper interactions
// between the sliding drawer and the action bar app icon
mDrawerToggle = new ActionBarDrawerToggle(this, /* host Activity */
mDrawerLayout, /* DrawerLayout object */
R.drawable.ic_drawer, /* nav drawer image to replace 'Up' caret */
R.string.drawer_open, /* "open drawer" description for accessibility */
R.string.drawer_close /* "close drawer" description for accessibility */
) {
public void onDrawerClosed(View view) {
super.onDrawerClosed(view);
if (view.equals(mDrawer)) {
mDrawerLayout.setDrawerLockMode(
DrawerLayout.LOCK_MODE_UNLOCKED, mDrawerRight);
} else if (view.equals(mDrawerRight)) {
mDrawerLayout.setDrawerLockMode(
DrawerLayout.LOCK_MODE_UNLOCKED, mDrawer);
}
}
public void onDrawerOpened(View drawerView) {
super.onDrawerOpened(drawerView);
if (drawerView.equals(mDrawer)) {
mDrawerLayout.closeDrawer(mDrawerRight);
mDrawerLayout.setDrawerLockMode(
DrawerLayout.LOCK_MODE_LOCKED_CLOSED, mDrawerRight);
} else if (drawerView.equals(mDrawerRight)) {
mDrawerLayout.closeDrawer(mDrawer);
mDrawerLayout.setDrawerLockMode(
DrawerLayout.LOCK_MODE_LOCKED_CLOSED, mDrawer);
}
}
};
mNewTab.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
newTab(null, true);
}
});
mDrawerLayout.setDrawerListener(mDrawerToggle);
initializePreferences();
initializeTabs();
if (API < 19) {
WebIconDatabase.getInstance().open(
getDir("icons", MODE_PRIVATE).getPath());
}
}
public synchronized void initializeTabs() {
mIdGenerator = 0;
String url = null;
newTab(url, true);
}
public void initializePreferences() {
if (mPreferences == null) {
mPreferences = getSharedPreferences(
PreferenceConstants.PREFERENCES, 0);
}
mFullScreen = mPreferences.getBoolean(PreferenceConstants.FULL_SCREEN,
false);
if (mPreferences.getBoolean(PreferenceConstants.HIDE_STATUS_BAR, false)) {
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
} else {
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
}
switch (mPreferences.getInt(PreferenceConstants.SEARCH, 1)) {
case 0:
mSearchText = mPreferences.getString(
PreferenceConstants.SEARCH_URL, Constants.GOOGLE_SEARCH);
if (!mSearchText.startsWith(Constants.HTTP)
&& !mSearchText.startsWith(Constants.HTTPS)) {
mSearchText = Constants.GOOGLE_SEARCH;
}
break;
case 1:
mSearchText = Constants.GOOGLE_SEARCH;
break;
case 2:
mSearchText = Constants.ANDROID_SEARCH;
break;
case 3:
mSearchText = Constants.BING_SEARCH;
break;
case 4:
mSearchText = Constants.YAHOO_SEARCH;
break;
case 5:
mSearchText = Constants.STARTPAGE_SEARCH;
break;
case 6:
mSearchText = Constants.STARTPAGE_MOBILE_SEARCH;
break;
case 7:
mSearchText = Constants.DUCK_SEARCH;
break;
case 8:
mSearchText = Constants.DUCK_LITE_SEARCH;
break;
case 9:
mSearchText = Constants.BAIDU_SEARCH;
break;
case 10:
mSearchText = Constants.YANDEX_SEARCH;
break;
}
mCookieManager = CookieManager.getInstance();
CookieSyncManager.createInstance(this);
mCookieManager.setAcceptCookie(mPreferences.getBoolean(
PreferenceConstants.INCOGNITO_COOKIES, true));
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_ENTER) {
if (mSearch.hasFocus()) {
searchTheWeb(mSearch.getText().toString());
}
}
return super.onKeyDown(keyCode, event);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.incognito, menu);
return super.onCreateOptionsMenu(menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// The action bar home/up action should open or close the drawer.
// ActionBarDrawerToggle will take care of this.
if (mDrawerToggle.onOptionsItemSelected(item)) {
return true;
}
// Handle action buttons
switch (item.getItemId()) {
case android.R.id.home:
if (mDrawerLayout.isDrawerOpen(mDrawerRight)) {
mDrawerLayout.closeDrawer(mDrawerRight);
}
mDrawerToggle.syncState();
return true;
case R.id.action_back:
if (mCurrentView != null) {
if (mCurrentView.canGoBack())
mCurrentView.goBack();
}
return true;
case R.id.action_forward:
if (mCurrentView != null) {
if (mCurrentView.canGoForward())
mCurrentView.goForward();
}
return true;
case R.id.action_new_tab:
newTab(null, true);
return true;
case R.id.action_incognito:
startActivity(new Intent(Constants.INCOGNITO_INTENT));
return true;
case R.id.action_share:
if (!mCurrentView.getUrl().startsWith(Constants.FILE)) {
Intent shareIntent = new Intent(
android.content.Intent.ACTION_SEND);
shareIntent.setType("text/plain");
shareIntent.putExtra(android.content.Intent.EXTRA_SUBJECT,
mCurrentView.getTitle());
String shareMessage = mCurrentView.getUrl();
shareIntent.putExtra(android.content.Intent.EXTRA_TEXT,
shareMessage);
startActivity(Intent.createChooser(shareIntent, getResources()
.getString(R.string.dialog_title_share)));
}
return true;
case R.id.action_bookmarks:
openBookmarks();
return true;
case R.id.action_copy:
if (mCurrentView != null) {
if (!mCurrentView.getUrl().startsWith(Constants.FILE)) {
ClipboardManager clipboard = (ClipboardManager) getSystemService(CLIPBOARD_SERVICE);
ClipData clip = ClipData.newPlainText("label", mCurrentView
.getUrl().toString());
clipboard.setPrimaryClip(clip);
Utils.showToast(mContext, mContext.getResources()
.getString(R.string.message_link_copied));
}
}
return true;
case R.id.action_settings:
startActivity(new Intent(Constants.SETTINGS_INTENT));
return true;
case R.id.action_history:
openHistory();
return true;
case R.id.action_add_bookmark:
if (!mCurrentView.getUrl().startsWith(Constants.FILE)) {
addBookmark(this, mCurrentView.getTitle(),
mCurrentView.getUrl());
}
return true;
case R.id.action_find:
findInPage();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
/**
* refreshes the underlying list of the Bookmark adapter since the bookmark
* adapter doesn't always change when notifyDataChanged gets called.
*/
private void notifyBookmarkDataSetChanged() {
mBookmarkAdapter.clear();
mBookmarkAdapter.addAll(mBookmarkList);
mBookmarkAdapter.notifyDataSetChanged();
}
/**
* method that shows a dialog asking what string the user wishes to search
* for. It highlights the text entered.
*/
private void findInPage() {
final AlertDialog.Builder finder = new AlertDialog.Builder(mActivity);
finder.setTitle(getResources().getString(R.string.action_find));
final EditText getHome = new EditText(this);
getHome.setHint(getResources().getString(R.string.search_hint));
finder.setView(getHome);
finder.setPositiveButton(
getResources().getString(R.string.search_hint),
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
String text = getHome.getText().toString();
if (mCurrentView != null) {
mCurrentView.find(text);
}
}
});
finder.show();
}
/** The click listener for ListView in the navigation drawer */
private class DrawerItemClickListener implements
ListView.OnItemClickListener {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position,
long id) {
mIsNewIntent = false;
selectItem(position);
}
}
/** long click listener for Navigation Drawer */
private class DrawerItemLongClickListener implements
ListView.OnItemLongClickListener {
@Override
public boolean onItemLongClick(AdapterView<?> arg0, View arg1,
int position, long arg3) {
deleteTab(position);
return false;
}
}
private class BookmarkItemClickListener implements
ListView.OnItemClickListener {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position,
long id) {
if (mCurrentView != null) {
mCurrentView.loadUrl(mBookmarkList.get(position).getUrl());
}
mDrawerLayout.closeDrawer(mDrawerRight);
}
}
private class BookmarkItemLongClickListener implements
ListView.OnItemLongClickListener {
@Override
public boolean onItemLongClick(AdapterView<?> arg0, View arg1,
final int position, long arg3) {
AlertDialog.Builder builder = new AlertDialog.Builder(mActivity);
builder.setTitle(mContext.getResources().getString(
R.string.action_bookmarks));
builder.setMessage(
getResources().getString(R.string.dialog_bookmark))
.setCancelable(true)
.setPositiveButton(
getResources().getString(R.string.action_new_tab),
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog,
int id) {
newTab(mBookmarkList.get(position).getUrl(),
false);
mDrawerLayout.closeDrawers();
}
})
.setNegativeButton(
getResources().getString(R.string.action_delete),
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog,
int which) {
deleteBookmark(mBookmarkList.get(position)
.getUrl());
}
})
.setNeutralButton(
getResources().getString(R.string.action_edit),
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog,
int which) {
editBookmark(position);
}
});
AlertDialog alert = builder.create();
alert.show();
return true;
}
}
/**
* Takes in the id of which bookmark was selected and shows a dialog that
* allows the user to rename and change the url of the bookmark
*
* @param id
* which id in the list was chosen
*/
public synchronized void editBookmark(final int id) {
final AlertDialog.Builder homePicker = new AlertDialog.Builder(
mActivity);
homePicker.setTitle(getResources().getString(
R.string.title_edit_bookmark));
final EditText getTitle = new EditText(mContext);
getTitle.setHint(getResources().getString(R.string.hint_title));
getTitle.setText(mBookmarkList.get(id).getTitle());
getTitle.setSingleLine();
final EditText getUrl = new EditText(mContext);
getUrl.setHint(getResources().getString(R.string.hint_url));
getUrl.setText(mBookmarkList.get(id).getUrl());
getUrl.setSingleLine();
LinearLayout layout = new LinearLayout(mContext);
layout.setOrientation(LinearLayout.VERTICAL);
layout.addView(getTitle);
layout.addView(getUrl);
homePicker.setView(layout);
homePicker.setPositiveButton(
getResources().getString(R.string.action_ok),
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
mBookmarkList.get(id).setTitle(
getTitle.getText().toString());
mBookmarkList.get(id).setUrl(
getUrl.getText().toString());
notifyBookmarkDataSetChanged();
File book = new File(getFilesDir(), "bookmarks");
File bookUrl = new File(getFilesDir(), "bookurl");
try {
BufferedWriter bookWriter = new BufferedWriter(
new FileWriter(book));
BufferedWriter urlWriter = new BufferedWriter(
new FileWriter(bookUrl));
Iterator<HistoryItem> iter = mBookmarkList
.iterator();
HistoryItem item;
while (iter.hasNext()) {
item = iter.next();
bookWriter.write(item.getTitle());
urlWriter.write(item.getUrl());
bookWriter.newLine();
urlWriter.newLine();
}
bookWriter.close();
urlWriter.close();
} catch (FileNotFoundException e) {
} catch (IOException e) {
}
Collections.sort(mBookmarkList, new SortIgnoreCase());
notifyBookmarkDataSetChanged();
if (mCurrentView != null) {
if (mCurrentView.getUrl()
.startsWith(Constants.FILE)
&& mCurrentView.getUrl().endsWith(
"bookmarks.html")) {
openBookmarkPage(mCurrentView.getWebView());
}
}
}
});
homePicker.show();
}
/**
* displays the WebView contained in the LightningView Also handles the
* removal of previous views
*
* @param view
* the LightningView to show
*/
private synchronized void showTab(LightningView view) {
if (view == null) {
return;
}
if (mCurrentView != null) {
mCurrentView.onPause();
}
mCurrentView = view;
if (view.getWebView() != null) {
updateUrl(view.getUrl());
updateProgress(view.getProgress());
} else {
updateUrl("");
updateProgress(0);
}
mBrowserFrame.removeAllViews();
mCurrentView.onResume();
mBrowserFrame.addView(view.getWebView());
}
/**
* creates a new tab with the passed in URL if it isn't null
*/
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
if (mCurrentView == null) {
initialize();
}
String url = null;
if (intent != null) {
url = intent.getDataString();
}
int num = 0;
if (intent != null && intent.getExtras() != null)
num = intent.getExtras().getInt(getPackageName() + ".Origin");
if (num == 1) {
mCurrentView.loadUrl(url);
} else if (url != null) {
url = null;
newTab(url, true);
mIsNewIntent = true;
}
}
private void selectItem(int position) {
// update selected item and title, then close the drawer
mDrawerList.setItemChecked(position, true);
showTab(mWebViews.get(position));
mDrawerLayout.closeDrawer(mDrawer);
}
/**
* When using the ActionBarDrawerToggle, you must call it during
* onPostCreate() and onConfigurationChanged()...
*/
@Override
protected void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
// Sync the toggle state after onRestoreInstanceState has occurred.
mDrawerToggle.syncState();
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
// Pass any configuration change to the drawer toggls
mDrawerToggle.onConfigurationChanged(newConfig);
}
private synchronized void newTab(String url, boolean show) {
mIsNewIntent = false;
LightningView startingTab = new LightningView(mActivity, url, mCookieManager);
if (mIdGenerator == 0) {
startingTab.resumeTimers();
}
mIdList.add(mIdGenerator);
mIdGenerator++;
mWebViews.add(startingTab);
Drawable icon = writeOnDrawable(mWebViews.size());
mActionBar.setIcon(icon);
mTitleAdapter.notifyDataSetChanged();
if (show) {
mDrawerList.setItemChecked(mWebViews.size() - 1, true);
showTab(startingTab);
}
}
private synchronized void deleteTab(int position) {
if (position >= mWebViews.size()) {
return;
}
int current = mDrawerList.getCheckedItemPosition();
LightningView reference = mWebViews.get(position);
if (reference == null) {
return;
}
boolean isShown = reference.isShown();
if (current > position) {
mIdList.remove(position);
mWebViews.remove(position);
mDrawerList.setItemChecked(current - 1, true);
reference.onDestroy();
} else if (mWebViews.size() > position + 1) {
mIdList.remove(position);
showTab(mWebViews.get(position + 1));
mWebViews.remove(position);
mDrawerList.setItemChecked(position, true);
reference.onDestroy();
} else if (mWebViews.size() > 1) {
mIdList.remove(position);
showTab(mWebViews.get(position - 1));
mWebViews.remove(position);
mDrawerList.setItemChecked(position - 1, true);
reference.onDestroy();
} else {
if (mCurrentView.getUrl().startsWith(Constants.FILE)
|| mCurrentView.getUrl().equals(mHomepage)) {
finish();
} else {
mIdList.remove(position);
mWebViews.remove(position);
if (mPreferences.getBoolean(
PreferenceConstants.CLEAR_CACHE_EXIT, false)
&& mCurrentView != null) {
mCurrentView.clearCache(true);
Log.i("Lightning", "Cache Cleared");
}
if (reference != null) {
reference.pauseTimers();
reference.onDestroy();
}
mCurrentView = null;
mTitleAdapter.notifyDataSetChanged();
finish();
}
}
mTitleAdapter.notifyDataSetChanged();
Drawable icon = writeOnDrawable(mWebViews.size());
mActionBar.setIcon(icon);
if (mIsNewIntent && isShown) {
mIsNewIntent = false;
finish();
}
Log.i("Lightning", "deleted tab");
}
@Override
public boolean onKeyLongPress(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
if (mPreferences.getBoolean(PreferenceConstants.CLEAR_CACHE_EXIT,
false) && mCurrentView != null) {
mCurrentView.clearCache(true);
Log.i("Lightning", "Cache Cleared");
}
mCurrentView = null;
for (int n = 0; n < mWebViews.size(); n++) {
if (mWebViews.get(n) != null)
mWebViews.get(n).onDestroy();
}
mWebViews.clear();
mTitleAdapter.notifyDataSetChanged();
finish();
}
return true;
}
@Override
public void onBackPressed() {
if (!mActionBar.isShowing()) {
mActionBar.show();
}
if (mDrawerLayout.isDrawerOpen(mDrawer)) {
mDrawerLayout.closeDrawer(mDrawer);
} else if (mDrawerLayout.isDrawerOpen(mDrawerRight)) {
mDrawerLayout.closeDrawer(mDrawerRight);
} else {
if (mCurrentView != null) {
Log.i("Lightning", "onBackPressed");
if (mCurrentView.canGoBack()) {
if (!mCurrentView.isShown()) {
onHideCustomView();
} else {
mCurrentView.goBack();
}
} else {
deleteTab(mDrawerList.getCheckedItemPosition());
}
} else {
Log.e("Lightning Browser",
"So madness. Much confusion. Why happen.");
super.onBackPressed();
}
}
}
@Override
protected void onPause() {
super.onPause();
Log.i("Lightning", "onPause");
if (mCurrentView != null) {
mCurrentView.pauseTimers();
mCurrentView.onPause();
}
if (mHistoryDatabase != null) {
if (mHistoryDatabase.isOpen())
mHistoryDatabase.close();
}
if (mHistoryHandler != null) {
if (mHistoryHandler.isOpen())
mHistoryHandler.close();
}
}
@Override
protected void onDestroy() {
Log.i("Lightning", "onDestroy");
if (mHistoryDatabase != null) {
if (mHistoryDatabase.isOpen())
mHistoryDatabase.close();
}
if (mHistoryHandler != null) {
if (mHistoryHandler.isOpen())
mHistoryHandler.close();
}
super.onDestroy();
}
@Override
protected void onResume() {
super.onResume();
Log.i("Lightning", "onResume");
if (SettingsController.getClearHistory()) {
}
if (mSearchAdapter != null) {
mSearchAdapter.refreshPreferences();
mSearchAdapter.refreshBookmarks();
}
if (mActionBar != null) {
if (!mActionBar.isShowing()) {
mActionBar.show();
}
}
if (mCurrentView != null) {
mCurrentView.resumeTimers();
mCurrentView.onResume();
if (mHistoryHandler == null) {
mHistoryHandler = new DatabaseHandler(this);
} else if (!mHistoryHandler.isOpen()) {
mHistoryHandler = new DatabaseHandler(this);
}
mHistoryDatabase = mHistoryHandler.getReadableDatabase();
mBookmarkList = getBookmarks();
notifyBookmarkDataSetChanged();
} else {
initialize();
}
initializePreferences();
if (mWebViews != null) {
for (int n = 0; n < mWebViews.size(); n++) {
if (mWebViews.get(n) != null) {
mWebViews.get(n).initializePreferences(this);
} else {
mWebViews.remove(n);
}
}
} else {
initialize();
}
}
/**
* searches the web for the query fixing any and all problems with the input
* checks if it is a search, url, etc.
*/
void searchTheWeb(String query) {
if (query.equals("")) {
return;
}
String SEARCH = mSearchText;
query = query.trim();
mCurrentView.stopLoading();
if (query.startsWith("www.")) {
query = Constants.HTTP + query;
} else if (query.startsWith("ftp.")) {
query = "ftp://" + query;
}
boolean containsPeriod = query.contains(".");
boolean isIPAddress = (TextUtils.isDigitsOnly(query.replace(".", ""))
&& (query.replace(".", "").length() >= 4) && query
.contains("."));
boolean aboutScheme = query.contains("about:");
boolean validURL = (query.startsWith("ftp://")
|| query.startsWith(Constants.HTTP)
|| query.startsWith(Constants.FILE) || query
.startsWith(Constants.HTTPS)) || isIPAddress;
boolean isSearch = ((query.contains(" ") || !containsPeriod) && !aboutScheme);
if (isIPAddress
&& (!query.startsWith(Constants.HTTP) || !query
.startsWith(Constants.HTTPS))) {
query = Constants.HTTP + query;
}
if (isSearch) {
try {
query = URLEncoder.encode(query, "UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
mCurrentView.loadUrl(SEARCH + query);
} else if (!validURL) {
mCurrentView.loadUrl(Constants.HTTP + query);
} else {
mCurrentView.loadUrl(query);
}
}
public void deleteBookmark(String url) {
File book = new File(getFilesDir(), "bookmarks");
File bookUrl = new File(getFilesDir(), "bookurl");
try {
BufferedWriter bookWriter = new BufferedWriter(new FileWriter(book));
BufferedWriter urlWriter = new BufferedWriter(new FileWriter(
bookUrl));
Iterator<HistoryItem> iter = mBookmarkList.iterator();
HistoryItem item;
int num = 0;
int deleteIndex = -1;
while (iter.hasNext()) {
item = iter.next();
if (!item.getUrl().equalsIgnoreCase(url)) {
bookWriter.write(item.getTitle());
urlWriter.write(item.getUrl());
bookWriter.newLine();
urlWriter.newLine();
} else {
deleteIndex = num;
}
num++;
}
if (deleteIndex != -1) {
mBookmarkList.remove(deleteIndex);
}
bookWriter.close();
urlWriter.close();
} catch (FileNotFoundException e) {
} catch (IOException e) {
}
notifyBookmarkDataSetChanged();
mSearchAdapter.refreshBookmarks();
openBookmarks();
}
/**
* converts the int num into density pixels
*
* @param num
* @return density pixels
*/
private int getDp(int num) {
float scale = getResources().getDisplayMetrics().density;
return (int) (num * scale + 0.5f);
}
private int pixelsToDp(int num) {
float scale = getResources().getDisplayMetrics().density;
return (int) ((num - 0.5f) / scale);
}
/**
* writes the number of open tabs on the icon.
*/
public BitmapDrawable writeOnDrawable(int number) {
return mIncognitoIcon;
}
public class LightningViewAdapter extends ArrayAdapter<LightningView> {
Context context;
int layoutResourceId;
List<LightningView> data = null;
public LightningViewAdapter(Context context, int layoutResourceId,
List<LightningView> data) {
super(context, layoutResourceId, data);
this.layoutResourceId = layoutResourceId;
this.context = context;
this.data = data;
}
@Override
public View getView(final int position, View convertView,
ViewGroup parent) {
View row = convertView;
LightningViewHolder holder = null;
if (row == null) {
LayoutInflater inflater = ((Activity) context)
.getLayoutInflater();
row = inflater.inflate(layoutResourceId, parent, false);
holder = new LightningViewHolder();
holder.txtTitle = (TextView) row.findViewById(R.id.text1);
holder.favicon = (ImageView) row.findViewById(R.id.favicon1);
holder.exit = (ImageView) row.findViewById(R.id.delete1);
holder.exit.setTag(position);
row.setTag(holder);
} else {
holder = (LightningViewHolder) row.getTag();
}
holder.exit.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
deleteTab(position);
}
});
LightningView web = data.get(position);
holder.txtTitle.setText(web.getTitle());
Bitmap favicon = web.getFavicon();
holder.favicon.setImageBitmap(favicon);
return row;
}
class LightningViewHolder {
TextView txtTitle;
ImageView favicon;
ImageView exit;
}
}
public class BookmarkViewAdapter extends ArrayAdapter<HistoryItem> {
Context context;
int layoutResourceId;
List<HistoryItem> data = null;
public BookmarkViewAdapter(Context context, int layoutResourceId,
List<HistoryItem> data) {
super(context, layoutResourceId, data);
this.layoutResourceId = layoutResourceId;
this.context = context;
this.data = data;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View row = convertView;
BookmarkViewHolder holder = null;
if (row == null) {
LayoutInflater inflater = ((Activity) context)
.getLayoutInflater();
row = inflater.inflate(layoutResourceId, parent, false);
holder = new BookmarkViewHolder();
holder.txtTitle = (TextView) row.findViewById(R.id.text1);
holder.favicon = (ImageView) row.findViewById(R.id.favicon1);
row.setTag(holder);
} else {
holder = (BookmarkViewHolder) row.getTag();
}
HistoryItem web = data.get(position);
holder.txtTitle.setText(web.getTitle());
holder.favicon.setImageBitmap(mWebpageBitmap);
if (web.getBitmap() == null) {
getImage(holder.favicon, web);
} else {
holder.favicon.setImageBitmap(web.getBitmap());
}
return row;
}
class BookmarkViewHolder {
TextView txtTitle;
ImageView favicon;
}
}
public void getImage(ImageView image, HistoryItem web) {
try {
new DownloadImageTask(image, web).execute(Constants.HTTP
+ getDomainName(web.getUrl()) + "/favicon.ico");
} catch (URISyntaxException e) {
new DownloadImageTask(image, web)
.execute("https://www.google.com/s2/favicons?domain_url="
+ web.getUrl());
e.printStackTrace();
}
}
private class DownloadImageTask extends AsyncTask<String, Void, Bitmap> {
ImageView bmImage;
HistoryItem mWeb;
public DownloadImageTask(ImageView bmImage, HistoryItem web) {
this.bmImage = bmImage;
this.mWeb = web;
}
protected Bitmap doInBackground(String... urls) {
String urldisplay = urls[0];
Bitmap mIcon = null;
// unique path for each url that is bookmarked.
String hash = String.valueOf(urldisplay.hashCode());
File image = new File(mContext.getCacheDir(), hash + ".png");
// checks to see if the image exists
if (!image.exists()) {
try {
// if not, download it...
InputStream in = new java.net.URL(urldisplay).openStream();
if (in != null) {
mIcon = BitmapFactory.decodeStream(in);
}
// ...and cache it
if (mIcon != null) {
FileOutputStream fos = new FileOutputStream(image);
mIcon.compress(Bitmap.CompressFormat.PNG, 85, fos);
fos.flush();
fos.close();
}
} catch (Exception e) {
}
} else {
// if it exists, retrieve it from the cache
mIcon = BitmapFactory.decodeFile(image.getPath());
}
if (mIcon == null) {
try {
// if not, download it...
InputStream in = new java.net.URL(
"https://www.google.com/s2/favicons?domain_url="
+ urldisplay).openStream();
if (in != null) {
mIcon = BitmapFactory.decodeStream(in);
}
// ...and cache it
if (mIcon != null) {
FileOutputStream fos = new FileOutputStream(image);
mIcon.compress(Bitmap.CompressFormat.PNG, 85, fos);
fos.flush();
fos.close();
}
} catch (Exception e) {
}
}
if (mIcon == null) {
return mWebpageBitmap;
} else {
return mIcon;
}
}
protected void onPostExecute(Bitmap result) {
bmImage.setImageBitmap(result);
mWeb.setBitmap(result);
notifyBookmarkDataSetChanged();
}
}
public static String getDomainName(String url) throws URISyntaxException {
URI uri = new URI(url);
String domain = uri.getHost();
if (domain == null) {
return url;
}
return domain.startsWith("www.") ? domain.substring(4) : domain;
}
@Override
public void updateUrl(String url) {
if (url == null)
return;
url = url.replaceFirst(Constants.HTTP, "");
if (url.startsWith(Constants.FILE)) {
url = "";
}
mSearch.setText(url);
}
@Override
public void updateProgress(int n) {
if (!mProgress.isShown())
mProgress.setVisibility(View.VISIBLE);
mProgress.setProgress(n);
if (n == 100) {
mProgress.setVisibility(View.INVISIBLE);
setIsFinishedLoading();
} else {
setIsLoading();
}
}
@Override
public void updateHistory(final String title, final String url) {
}
/**
* 1, 2, 3, testing... is there a system browser that has some nice
* bookmarks for us?
*/
public boolean isSystemBrowserAvailable() {
return mSystemBrowser;
}
/**
* 1, 2, 3, testing... is there a system browser that has some nice
* bookmarks for us? helper method for isSystemBrowserAvailable
*/
public boolean getSystemBrowser() {
Cursor c = null;
String[] columns = new String[] { "url", "title" };
boolean browserFlag = false;
try {
Uri bookmarks = Browser.BOOKMARKS_URI;
c = getContentResolver()
.query(bookmarks, columns, null, null, null);
} catch (SQLiteException ignored) {
} catch (IllegalStateException ignored) {
} catch (NullPointerException ignored) {
}
if (c != null) {
Log.i("Browser", "System Browser Available");
browserFlag = true;
} else {
Log.e("Browser", "System Browser Unavailable");
browserFlag = false;
}
if (c != null) {
c.close();
c = null;
}
mEditPrefs.putBoolean("SystemBrowser", browserFlag);
mEditPrefs.commit();
return browserFlag;
}
/**
* method to generate search suggestions for the AutoCompleteTextView from
* previously searched URLs
*/
private void initializeSearchSuggestions(final AutoCompleteTextView getUrl) {
getUrl.setThreshold(1);
getUrl.setDropDownWidth(-1);
getUrl.setDropDownAnchor(R.id.progressWrapper);
getUrl.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
long arg3) {
try {
String url;
url = ((TextView) arg1.findViewById(R.id.url)).getText()
.toString();
if (url.startsWith(mContext.getString(R.string.suggestion))) {
url = ((TextView) arg1.findViewById(R.id.title))
.getText().toString();
} else {
getUrl.setText(url);
}
searchTheWeb(url);
url = null;
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(getUrl.getWindowToken(), 0);
if (mCurrentView != null) {
mCurrentView.requestFocus();
}
} catch (NullPointerException e) {
Log.e("Browser Error: ",
"NullPointerException on item click");
}
}
});
getUrl.setSelectAllOnFocus(true);
mSearchAdapter = new SearchAdapter(mContext, true);
getUrl.setAdapter(mSearchAdapter);
}
/**
* returns a list of bookmarks in the style (Title, Url) that is useful. the
* boolean addStarChar just adds an ASCII star character to each title if
* you want, primarily for use in search suggestions where the star
* indicates that it is a bookmarked url. All other uses can just supply
* false to this method.
*/
private List<HistoryItem> getBookmarks() {
List<HistoryItem> bookmarks = new ArrayList<HistoryItem>();
File bookUrl = new File(getApplicationContext().getFilesDir(),
"bookurl");
File book = new File(getApplicationContext().getFilesDir(), "bookmarks");
try {
BufferedReader readUrl = new BufferedReader(new FileReader(bookUrl));
BufferedReader readBook = new BufferedReader(new FileReader(book));
String u, t;
while ((u = readUrl.readLine()) != null
&& (t = readBook.readLine()) != null) {
HistoryItem map = new HistoryItem(u, t);
bookmarks.add(map);
}
readBook.close();
readUrl.close();
} catch (FileNotFoundException ignored) {
} catch (IOException ignored) {
}
Collections.sort(bookmarks, new SortIgnoreCase());
return bookmarks;
}
/**
* returns a list of HistoryItems
*
* @return
*/
private List<HistoryItem> getLatestHistory() {
DatabaseHandler historyHandler = new DatabaseHandler(mContext);
return historyHandler.getLastHundredItems();
}
/**
* function that opens the HTML history page in the browser
*/
private void openHistory() {
Thread history = new Thread(new Runnable() {
@Override
public void run() {
String historyHtml = HistoryPageVariables.Heading;
List<HistoryItem> historyList = getLatestHistory();
Iterator<HistoryItem> it = historyList.iterator();
HistoryItem helper;
while (it.hasNext()) {
helper = it.next();
historyHtml += HistoryPageVariables.Part1 + helper.getUrl()
+ HistoryPageVariables.Part2 + helper.getTitle()
+ HistoryPageVariables.Part3 + helper.getUrl()
+ HistoryPageVariables.Part4;
}
historyHtml += HistoryPageVariables.End;
File historyWebPage = new File(getFilesDir(), "history.html");
try {
FileWriter hWriter = new FileWriter(historyWebPage, false);
hWriter.write(historyHtml);
hWriter.close();
} catch (IOException e) {
e.printStackTrace();
}
mCurrentView.loadUrl(Constants.FILE + historyWebPage);
mSearch.setText("");
}
});
history.run();
}
/**
* helper function that opens the bookmark drawer
*/
private void openBookmarks() {
if (mDrawerLayout.isDrawerOpen(mDrawer)) {
mDrawerLayout.closeDrawers();
}
mDrawerToggle.syncState();
mDrawerLayout.openDrawer(mDrawerRight);
}
@Override
/**
* open the HTML bookmarks page, parameter view is the WebView that should show the page
*/
public void openBookmarkPage(WebView view) {
String bookmarkHtml = BookmarkPageVariables.Heading;
Iterator<HistoryItem> iter = mBookmarkList.iterator();
HistoryItem helper;
while (iter.hasNext()) {
helper = iter.next();
bookmarkHtml += (BookmarkPageVariables.Part1 + helper.getUrl()
+ BookmarkPageVariables.Part2 + helper.getUrl()
+ BookmarkPageVariables.Part3 + helper.getTitle() + BookmarkPageVariables.Part4);
}
bookmarkHtml += BookmarkPageVariables.End;
File bookmarkWebPage = new File(mContext.getCacheDir(),
"bookmarks.html");
try {
FileWriter bookWriter = new FileWriter(bookmarkWebPage, false);
bookWriter.write(bookmarkHtml);
bookWriter.close();
} catch (IOException e) {
e.printStackTrace();
}
view.loadUrl(Constants.FILE + bookmarkWebPage);
}
/**
* adds a bookmark with a title and url. Simple.
*/
public void addBookmark(Context context, String title, String url) {
File book = new File(context.getFilesDir(), "bookmarks");
File bookUrl = new File(context.getFilesDir(), "bookurl");
HistoryItem bookmark = new HistoryItem(url, title);
try {
BufferedReader readUrlRead = new BufferedReader(new FileReader(
bookUrl));
String u;
while ((u = readUrlRead.readLine()) != null) {
if (u.contentEquals(url)) {
readUrlRead.close();
return;
}
}
readUrlRead.close();
} catch (FileNotFoundException ignored) {
} catch (IOException ignored) {
} catch (NullPointerException ignored) {
}
try {
BufferedWriter bookWriter = new BufferedWriter(new FileWriter(book,
true));
BufferedWriter urlWriter = new BufferedWriter(new FileWriter(
bookUrl, true));
bookWriter.write(title);
urlWriter.write(url);
bookWriter.newLine();
urlWriter.newLine();
bookWriter.close();
urlWriter.close();
mBookmarkList.add(bookmark);
Collections.sort(mBookmarkList, new SortIgnoreCase());
notifyBookmarkDataSetChanged();
} catch (FileNotFoundException ignored) {
} catch (IOException ignored) {
} catch (NullPointerException ignored) {
}
mSearchAdapter.refreshBookmarks();
}
@Override
public void update() {
mTitleAdapter.notifyDataSetChanged();
}
@Override
/**
* opens a file chooser
* param ValueCallback is the message from the WebView indicating a file chooser
* should be opened
*/
public void openFileChooser(ValueCallback<Uri> uploadMsg) {
mUploadMessage = uploadMsg;
Intent i = new Intent(Intent.ACTION_GET_CONTENT);
i.addCategory(Intent.CATEGORY_OPENABLE);
i.setType("*/*");
startActivityForResult(Intent.createChooser(i, "File Chooser"), 1);
}
@Override
/**
* used to allow uploading into the browser, doesn't get called in KitKat :(
*/
protected void onActivityResult(int requestCode, int resultCode,
Intent intent) {
if (requestCode == 1) {
if (null == mUploadMessage)
return;
Uri result = intent == null || resultCode != RESULT_OK ? null
: intent.getData();
mUploadMessage.onReceiveValue(result);
mUploadMessage = null;
}
}
@Override
/**
* handles long presses for the browser, tries to get the
* url of the item that was clicked and sends it (it can be null)
* to the click handler that does cool stuff with it
*/
public void onLongPress() {
if (mClickHandler == null) {
mClickHandler = new ClickHandler(mContext);
}
Message click = mClickHandler.obtainMessage();
if (click != null) {
click.setTarget(mClickHandler);
}
mCurrentView.getWebView().requestFocusNodeHref(click);
}
@Override
public void onShowCustomView(View view, int requestedOrientation,
CustomViewCallback callback) {
if (view == null) {
return;
}
if (mCustomView != null && callback != null) {
callback.onCustomViewHidden();
return;
}
view.setKeepScreenOn(true);
mOriginalOrientation = getRequestedOrientation();
FrameLayout decor = (FrameLayout) getWindow().getDecorView();
mFullscreenContainer = new FullscreenHolder(this);
mCustomView = view;
mFullscreenContainer.addView(mCustomView, COVER_SCREEN_PARAMS);
decor.addView(mFullscreenContainer, COVER_SCREEN_PARAMS);
setFullscreen(true);
mCurrentView.setVisibility(View.GONE);
if (view instanceof FrameLayout) {
if (((FrameLayout) view).getFocusedChild() instanceof VideoView) {
mVideoView = (VideoView) ((FrameLayout) view).getFocusedChild();
mVideoView.setOnErrorListener(new VideoCompletionListener());
mVideoView
.setOnCompletionListener(new VideoCompletionListener());
}
}
mCustomViewCallback = callback;
}
@Override
public void onHideCustomView() {
if (mCustomView == null || mCustomViewCallback == null
|| mCurrentView == null)
return;
Log.i("Lightning", "onHideCustomView");
mCurrentView.setVisibility(View.VISIBLE);
mCustomView.setKeepScreenOn(false);
setFullscreen(mPreferences.getBoolean(
PreferenceConstants.HIDE_STATUS_BAR, false));
FrameLayout decor = (FrameLayout) getWindow().getDecorView();
if (decor != null) {
decor.removeView(mFullscreenContainer);
}
if (API < 19) {
try {
mCustomViewCallback.onCustomViewHidden();
} catch (Throwable ignored) {
}
}
mFullscreenContainer = null;
mCustomView = null;
if (mVideoView != null) {
mVideoView.setOnErrorListener(null);
mVideoView.setOnCompletionListener(null);
mVideoView = null;
}
setRequestedOrientation(mOriginalOrientation);
}
private class VideoCompletionListener implements
MediaPlayer.OnCompletionListener, MediaPlayer.OnErrorListener {
@Override
public boolean onError(MediaPlayer mp, int what, int extra) {
return false;
}
@Override
public void onCompletion(MediaPlayer mp) {
onHideCustomView();
}
}
/**
* turns on fullscreen mode in the app
*
* @param enabled
* whether to enable fullscreen or not
*/
public void setFullscreen(boolean enabled) {
Window win = getWindow();
WindowManager.LayoutParams winParams = win.getAttributes();
final int bits = WindowManager.LayoutParams.FLAG_FULLSCREEN;
if (enabled) {
winParams.flags |= bits;
} else {
winParams.flags &= ~bits;
if (mCustomView != null) {
mCustomView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_VISIBLE);
} else {
mBrowserFrame
.setSystemUiVisibility(View.SYSTEM_UI_FLAG_VISIBLE);
}
}
win.setAttributes(winParams);
}
/**
* a class extending FramLayout used to display fullscreen videos
*/
static class FullscreenHolder extends FrameLayout {
public FullscreenHolder(Context ctx) {
super(ctx);
setBackgroundColor(ctx.getResources().getColor(
android.R.color.black));
}
@Override
public boolean onTouchEvent(MotionEvent evt) {
return true;
}
}
@Override
/**
* a stupid method that returns the bitmap image to display in place of
* a loading video
*/
public Bitmap getDefaultVideoPoster() {
if (mDefaultVideoPoster == null) {
mDefaultVideoPoster = BitmapFactory.decodeResource(getResources(),
android.R.drawable.ic_media_play);
}
return mDefaultVideoPoster;
}
@Override
/**
* dumb method that returns the loading progress for a video
*/
public View getVideoLoadingProgressView() {
if (mVideoProgressView == null) {
LayoutInflater inflater = LayoutInflater.from(this);
mVideoProgressView = inflater.inflate(
R.layout.video_loading_progress, null);
}
return mVideoProgressView;
}
@Override
/**
* handles javascript requests to create a new window in the browser
*/
public void onCreateWindow(boolean isUserGesture, Message resultMsg) {
if (resultMsg == null) {
return;
}
newTab("", true);
WebView.WebViewTransport transport = (WebView.WebViewTransport) resultMsg.obj;
transport.setWebView(mCurrentView.getWebView());
resultMsg.sendToTarget();
}
@Override
/**
* returns the Activity instance for this activity,
* very helpful when creating things in other classes... I think
*/
public Activity getActivity() {
return mActivity;
}
/**
* it hides the action bar, seriously what else were you expecting
*/
@Override
public void hideActionBar() {
if (mActionBar.isShowing() && mFullScreen) {
mActionBar.hide();
}
}
@Override
/**
* obviously it shows the action bar if it's hidden
*/
public void showActionBar() {
if (!mActionBar.isShowing() && mFullScreen) {
mActionBar.show();
}
}
@Override
/**
* handles a long click on the page, parameter String url
* is the url that should have been obtained from the WebView touch node
* thingy, if it is null, this method tries to deal with it and find a workaround
*/
public void longClickPage(final String url) {
HitTestResult result = null;
if (mCurrentView.getWebView() != null) {
result = mCurrentView.getWebView().getHitTestResult();
}
if (url != null) {
if (url != null) {
if (result != null) {
if (result.getType() == HitTestResult.SRC_IMAGE_ANCHOR_TYPE
|| result.getType() == HitTestResult.IMAGE_TYPE) {
DialogInterface.OnClickListener dialogClickListener = new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog,
int which) {
switch (which) {
case DialogInterface.BUTTON_POSITIVE: {
newTab(url, false);
break;
}
case DialogInterface.BUTTON_NEGATIVE: {
mCurrentView.loadUrl(url);
break;
}
case DialogInterface.BUTTON_NEUTRAL: {
if (API > 8) {
Utils.downloadFile(mActivity, url,
mCurrentView.getUserAgent(),
"attachment", false);
}
break;
}
}
}
};
AlertDialog.Builder builder = new AlertDialog.Builder(
mActivity); // dialog
builder.setTitle(url.replace(Constants.HTTP, ""))
.setMessage(
getResources().getString(
R.string.dialog_image))
.setPositiveButton(
getResources().getString(
R.string.action_new_tab),
dialogClickListener)
.setNegativeButton(
getResources().getString(
R.string.action_open),
dialogClickListener)
.setNeutralButton(
getResources().getString(
R.string.action_download),
dialogClickListener).show();
} else {
DialogInterface.OnClickListener dialogClickListener = new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog,
int which) {
switch (which) {
case DialogInterface.BUTTON_POSITIVE: {
newTab(url, false);
break;
}
case DialogInterface.BUTTON_NEGATIVE: {
mCurrentView.loadUrl(url);
break;
}
case DialogInterface.BUTTON_NEUTRAL: {
ClipboardManager clipboard = (ClipboardManager) getSystemService(CLIPBOARD_SERVICE);
ClipData clip = ClipData.newPlainText(
"label", url);
clipboard.setPrimaryClip(clip);
break;
}
}
}
};
AlertDialog.Builder builder = new AlertDialog.Builder(
mActivity); // dialog
builder.setTitle(url)
.setMessage(
getResources().getString(
R.string.dialog_link))
.setPositiveButton(
getResources().getString(
R.string.action_new_tab),
dialogClickListener)
.setNegativeButton(
getResources().getString(
R.string.action_open),
dialogClickListener)
.setNeutralButton(
getResources().getString(
R.string.action_copy),
dialogClickListener).show();
}
} else {
DialogInterface.OnClickListener dialogClickListener = new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
switch (which) {
case DialogInterface.BUTTON_POSITIVE: {
newTab(url, false);
break;
}
case DialogInterface.BUTTON_NEGATIVE: {
mCurrentView.loadUrl(url);
break;
}
case DialogInterface.BUTTON_NEUTRAL: {
ClipboardManager clipboard = (ClipboardManager) getSystemService(CLIPBOARD_SERVICE);
ClipData clip = ClipData.newPlainText("label",
url);
clipboard.setPrimaryClip(clip);
break;
}
}
}
};
AlertDialog.Builder builder = new AlertDialog.Builder(
mActivity); // dialog
builder.setTitle(url)
.setMessage(
getResources().getString(
R.string.dialog_link))
.setPositiveButton(
getResources().getString(
R.string.action_new_tab),
dialogClickListener)
.setNegativeButton(
getResources().getString(
R.string.action_open),
dialogClickListener)
.setNeutralButton(
getResources().getString(
R.string.action_copy),
dialogClickListener).show();
}
}
} else if (result != null) {
if (result.getExtra() != null) {
final String newUrl = result.getExtra();
if (result.getType() == HitTestResult.SRC_IMAGE_ANCHOR_TYPE
|| result.getType() == HitTestResult.IMAGE_TYPE) {
DialogInterface.OnClickListener dialogClickListener = new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
switch (which) {
case DialogInterface.BUTTON_POSITIVE: {
newTab(newUrl, false);
break;
}
case DialogInterface.BUTTON_NEGATIVE: {
mCurrentView.loadUrl(newUrl);
break;
}
case DialogInterface.BUTTON_NEUTRAL: {
if (API > 8) {
Utils.downloadFile(mActivity, newUrl,
mCurrentView.getUserAgent(),
"attachment", false);
}
break;
}
}
}
};
AlertDialog.Builder builder = new AlertDialog.Builder(
mActivity); // dialog
builder.setTitle(newUrl.replace(Constants.HTTP, ""))
.setMessage(
getResources().getString(
R.string.dialog_image))
.setPositiveButton(
getResources().getString(
R.string.action_new_tab),
dialogClickListener)
.setNegativeButton(
getResources().getString(
R.string.action_open),
dialogClickListener)
.setNeutralButton(
getResources().getString(
R.string.action_download),
dialogClickListener).show();
} else {
DialogInterface.OnClickListener dialogClickListener = new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
switch (which) {
case DialogInterface.BUTTON_POSITIVE: {
newTab(newUrl, false);
break;
}
case DialogInterface.BUTTON_NEGATIVE: {
mCurrentView.loadUrl(newUrl);
break;
}
case DialogInterface.BUTTON_NEUTRAL: {
ClipboardManager clipboard = (ClipboardManager) getSystemService(CLIPBOARD_SERVICE);
ClipData clip = ClipData.newPlainText("label",
newUrl);
clipboard.setPrimaryClip(clip);
break;
}
}
}
};
AlertDialog.Builder builder = new AlertDialog.Builder(
mActivity); // dialog
builder.setTitle(newUrl)
.setMessage(
getResources().getString(
R.string.dialog_link))
.setPositiveButton(
getResources().getString(
R.string.action_new_tab),
dialogClickListener)
.setNegativeButton(
getResources().getString(
R.string.action_open),
dialogClickListener)
.setNeutralButton(
getResources().getString(
R.string.action_copy),
dialogClickListener).show();
}
}
}
}
/**
* This method lets the search bar know that the page is currently loading
* and that it should display the stop icon to indicate to the user that
* pressing it stops the page from loading
*/
public void setIsLoading() {
if (!mSearch.hasFocus()) {
mIcon = mDeleteIcon;
mSearch.setCompoundDrawables(null, null, mDeleteIcon, null);
}
}
/**
* This tells the search bar that the page is finished loading and it should
* display the refresh icon
*/
public void setIsFinishedLoading() {
if (!mSearch.hasFocus()) {
mIcon = mRefreshIcon;
mSearch.setCompoundDrawables(null, null, mRefreshIcon, null);
}
}
/**
* handle presses on the refresh icon in the search bar, if the page is
* loading, stop the page, if it is done loading refresh the page.
*
* See setIsFinishedLoading and setIsLoading for displaying the correct icon
*/
public void refreshOrStop() {
if (mCurrentView != null) {
if (mCurrentView.getProgress() < 100) {
mCurrentView.stopLoading();
} else {
mCurrentView.reload();
}
}
}
@Override
public boolean isActionBarShowing() {
if (mActionBar != null) {
return mActionBar.isShowing();
} else {
return false;
}
}
public class SortIgnoreCase implements Comparator<HistoryItem> {
public int compare(HistoryItem o1, HistoryItem o2) {
return o1.getTitle().toLowerCase(Locale.getDefault())
.compareTo(o2.getTitle().toLowerCase(Locale.getDefault()));
}
}
}