From ea078dddc514553cd148e972e88346e5526c186f Mon Sep 17 00:00:00 2001 From: Anthony Restaino Date: Fri, 25 Jul 2014 17:48:42 -0400 Subject: [PATCH] Smoothed progress bar --- .../browser/lightning/BrowserActivity.java | 4658 ++++++++--------- 1 file changed, 2255 insertions(+), 2403 deletions(-) diff --git a/src/acr/browser/lightning/BrowserActivity.java b/src/acr/browser/lightning/BrowserActivity.java index 0a2c6c6..acdf2ae 100644 --- a/src/acr/browser/lightning/BrowserActivity.java +++ b/src/acr/browser/lightning/BrowserActivity.java @@ -4,6 +4,7 @@ package acr.browser.lightning; +import android.animation.ObjectAnimator; import android.annotation.SuppressLint; import android.app.ActionBar; import android.app.Activity; @@ -41,6 +42,7 @@ import android.view.*; import android.view.View.OnClickListener; import android.view.View.OnKeyListener; import android.view.View.OnTouchListener; +import android.view.animation.DecelerateInterpolator; import android.view.inputmethod.EditorInfo; import android.view.inputmethod.InputMethodManager; import android.webkit.*; @@ -60,2578 +62,2428 @@ import java.util.*; public class BrowserActivity extends Activity implements BrowserController { - private DrawerLayout mDrawerLayout; + private DrawerLayout mDrawerLayout; - private ListView mDrawerList; + private ListView mDrawerList; - private RelativeLayout mDrawer; + private RelativeLayout mDrawer; - private LinearLayout mDrawerRight; + private LinearLayout mDrawerRight; - private ListView mDrawerListRight; + private ListView mDrawerListRight; - private RelativeLayout mNewTab; + private RelativeLayout mNewTab; - private ActionBarDrawerToggle mDrawerToggle; + private ActionBarDrawerToggle mDrawerToggle; - private List mWebViews = new ArrayList(); + private List mWebViews = new ArrayList(); - private List mIdList = new ArrayList(); + private List mIdList = new ArrayList(); - private LightningView mCurrentView; + private LightningView mCurrentView; - private int mIdGenerator; + private int mIdGenerator; - private LightningViewAdapter mTitleAdapter; + private LightningViewAdapter mTitleAdapter; - private List mBookmarkList; + private List mBookmarkList; - private BookmarkViewAdapter mBookmarkAdapter; + private BookmarkViewAdapter mBookmarkAdapter; - private AutoCompleteTextView mSearch; + private AutoCompleteTextView mSearch; - private ClickHandler mClickHandler; + private ClickHandler mClickHandler; - private ProgressBar mProgress; + private ProgressBar mProgress; - private boolean mSystemBrowser = false; + private boolean mSystemBrowser = false; - private ValueCallback mUploadMessage; + private ValueCallback mUploadMessage; - private View mCustomView; + private View mCustomView; - private int mOriginalOrientation; + private int mOriginalOrientation; - private int mActionBarSize; + private int mActionBarSize; - private ActionBar mActionBar; + private ActionBar mActionBar; - private boolean mFullScreen; + private boolean mFullScreen; - private FrameLayout mBrowserFrame; + private FrameLayout mBrowserFrame; - private FullscreenHolder mFullscreenContainer; + private FullscreenHolder mFullscreenContainer; - private CustomViewCallback mCustomViewCallback; + private CustomViewCallback mCustomViewCallback; - private final FrameLayout.LayoutParams COVER_SCREEN_PARAMS = new FrameLayout.LayoutParams( - ViewGroup.LayoutParams.MATCH_PARENT, - ViewGroup.LayoutParams.MATCH_PARENT); + private final FrameLayout.LayoutParams COVER_SCREEN_PARAMS = new FrameLayout.LayoutParams( + ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT); - private Bitmap mDefaultVideoPoster; + private Bitmap mDefaultVideoPoster; - private View mVideoProgressView; + private View mVideoProgressView; - private DatabaseHandler mHistoryHandler; + private DatabaseHandler mHistoryHandler; - private SQLiteDatabase mHistoryDatabase; + private SQLiteDatabase mHistoryDatabase; - private SharedPreferences mPreferences; + private SharedPreferences mPreferences; - private SharedPreferences.Editor mEditPrefs; + private SharedPreferences.Editor mEditPrefs; - private Context mContext; + private Context mContext; - private Bitmap mWebpageBitmap; + private Bitmap mWebpageBitmap; - private String mSearchText; + private String mSearchText; - private Activity mActivity; + private Activity mActivity; - private CookieManager mCookieManager; + private CookieManager mCookieManager; - private final int API = android.os.Build.VERSION.SDK_INT; + private final int API = android.os.Build.VERSION.SDK_INT; - private Drawable mDeleteIcon; + private Drawable mDeleteIcon; - private Drawable mRefreshIcon; + private Drawable mRefreshIcon; - private Drawable mCopyIcon; + private Drawable mCopyIcon; - private Drawable mIcon; + private Drawable mIcon; - private int mActionBarSizeDp; + private int mActionBarSizeDp; - private int mNumberIconColor; + private int mNumberIconColor; - private String mHomepage; + private String mHomepage; - private boolean mIsNewIntent = false; + private boolean mIsNewIntent = false; - private VideoView mVideoView; + private VideoView mVideoView; - private static SearchAdapter mSearchAdapter; + private static SearchAdapter mSearchAdapter; - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - initialize(); - } - - @SuppressWarnings("deprecation") - private synchronized void initialize() { - setContentView(R.layout.activity_main); - TypedValue typedValue = new TypedValue(); - Theme theme = getTheme(); - theme.resolveAttribute(R.attr.numberColor, typedValue, true); - mNumberIconColor = typedValue.data; - mPreferences = getSharedPreferences(PreferenceConstants.PREFERENCES, 0); - mEditPrefs = mPreferences.edit(); - mContext = this; - if (mIdList != null) { - mIdList.clear(); - } else { - mIdList = new ArrayList(); - } - if (mWebViews != null) { - mWebViews.clear(); - } else { - mWebViews = new ArrayList(); - } - - 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 = (RelativeLayout) 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); - mDrawerList.setDivider(null); - mDrawerList.setDividerHeight(0); - mDrawerRight = (LinearLayout) findViewById(R.id.right_drawer); - mDrawerListRight = (ListView) findViewById(R.id.right_drawer_list); - mDrawerListRight.setDivider(null); - mDrawerListRight.setDividerHeight(0); - setNavigationDrawerWidth(); - 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); - mDrawerLayout.setDrawerShadow(R.drawable.drawer_right_shadow, - GravityCompat.END); - mDrawerLayout.setDrawerShadow(R.drawable.drawer_shadow, - GravityCompat.START); - initializePreferences(); - initializeTabs(); - - if (API < 19) { - WebIconDatabase.getInstance().open( - getDir("icons", MODE_PRIVATE).getPath()); - } - - checkForTor(); - - } - - /* - * If Orbot/Tor is installed, prompt the user if they want to enable - * proxying for this session - */ - public boolean checkForTor() { - boolean useProxy = mPreferences.getBoolean( - PreferenceConstants.USE_PROXY, false); - - OrbotHelper oh = new OrbotHelper(this); - if (oh.isOrbotInstalled() - && !mPreferences.getBoolean( - PreferenceConstants.INITIAL_CHECK_FOR_TOR, false)) { - mEditPrefs.putBoolean(PreferenceConstants.INITIAL_CHECK_FOR_TOR, - true); - mEditPrefs.apply(); - DialogInterface.OnClickListener dialogClickListener = new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - switch (which) { - case DialogInterface.BUTTON_POSITIVE: - mPreferences - .edit() - .putBoolean(PreferenceConstants.USE_PROXY, true) - .apply(); - - initializeTor(); - break; - case DialogInterface.BUTTON_NEGATIVE: - mPreferences - .edit() - .putBoolean(PreferenceConstants.USE_PROXY, - false).apply(); - break; - } - } - }; - - AlertDialog.Builder builder = new AlertDialog.Builder(this); - builder.setMessage(R.string.use_tor_prompt) - .setPositiveButton(R.string.yes, dialogClickListener) - .setNegativeButton(R.string.no, dialogClickListener).show(); - - return true; - } else if (oh.isOrbotInstalled() & useProxy == true) { - initializeTor(); - return true; - } else { - mEditPrefs.putBoolean(PreferenceConstants.USE_PROXY, false); - mEditPrefs.apply(); - return false; - } - } - - /* - * Initialize WebKit Proxying for Tor - */ - public void initializeTor() { - - OrbotHelper oh = new OrbotHelper(this); - if (!oh.isOrbotRunning()) { - oh.requestOrbotStart(this); - } - - WebkitProxy wkp = new WebkitProxy(); - try { - String host = mPreferences.getString( - PreferenceConstants.USE_PROXY_HOST, "localhost"); - int port = mPreferences.getInt(PreferenceConstants.USE_PROXY_PORT, - 8118); - wkp.setProxy("acr.browser.lightning.BrowserApp", - getApplicationContext(), host, port); - } catch (Exception e) { - Log.d(Constants.TAG, "error enabling web proxying", e); - } - - } - - public void setNavigationDrawerWidth() { - int width = getResources().getDisplayMetrics().widthPixels * 3 / 4; - int maxWidth = Utils.convertToDensityPixels(mContext, 300); - if (width > maxWidth) { - DrawerLayout.LayoutParams params = (android.support.v4.widget.DrawerLayout.LayoutParams) mDrawer - .getLayoutParams(); - params.width = maxWidth; - mDrawer.setLayoutParams(params); - DrawerLayout.LayoutParams paramsRight = (android.support.v4.widget.DrawerLayout.LayoutParams) mDrawerRight - .getLayoutParams(); - paramsRight.width = maxWidth; - mDrawerRight.setLayoutParams(paramsRight); - } else { - DrawerLayout.LayoutParams params = (android.support.v4.widget.DrawerLayout.LayoutParams) mDrawer - .getLayoutParams(); - params.width = width; - mDrawer.setLayoutParams(params); - DrawerLayout.LayoutParams paramsRight = (android.support.v4.widget.DrawerLayout.LayoutParams) mDrawerRight - .getLayoutParams(); - paramsRight.width = width; - mDrawerRight.setLayoutParams(paramsRight); - } - } - - /* - * Override this class - */ - public synchronized void initializeTabs() { - - } - - public void restoreOrNewTab() { - mIdGenerator = 0; - - String url = null; - if (getIntent() != null) { - url = getIntent().getDataString(); - if (url != null) { - if (url.startsWith(Constants.FILE)) { - Utils.showToast( - this, - getResources().getString( - R.string.message_blocked_local)); - url = null; - } - } - } - if (mPreferences - .getBoolean(PreferenceConstants.RESTORE_LOST_TABS, true)) { - String mem = mPreferences.getString(PreferenceConstants.URL_MEMORY, - ""); - mEditPrefs.putString(PreferenceConstants.URL_MEMORY, ""); - String[] array = Utils.getArray(mem); - int count = 0; - for (int n = 0; n < array.length; n++) { - if (array[n].length() > 0) { - newTab(array[n], true); - count++; - } - } - if (url != null) { - newTab(url, true); - } else if (count == 0) { - newTab(null, true); - } - } else { - 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; - } - - updateCookiePreference(); - if (mPreferences.getBoolean(PreferenceConstants.USE_PROXY, false)) { - initializeTor(); - } else { - try { - WebkitProxy.resetProxy("acr.browser.lightning.BrowserApp", - getApplicationContext()); - } catch (Exception e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - } - } - - /* - * Override this if class overrides BrowserActivity - */ - public void updateCookiePreference() { - - } - - @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) { - 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)) { - if (mDrawerLayout.isDrawerOpen(mDrawerRight)) { - mDrawerLayout.closeDrawer(mDrawerRight); - mDrawerLayout.openDrawer(mDrawer); - } else if (mDrawerLayout.isDrawerOpen(mDrawer)) { - mDrawerLayout.closeDrawer(mDrawer); - } - mDrawerToggle.syncState(); - 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(this, IncognitoActivity.class)); - 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(this, SettingsActivity.class)); - 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()); - } - // keep any jank from happening when the drawer is closed after the - // URL starts to load - final Handler handler = new Handler(); - handler.postDelayed(new Runnable() { - @Override - public void run() { - mDrawerLayout.closeDrawer(mDrawerRight); - } - }, 150); - } - } - - 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 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.setForegroundTab(false); - mCurrentView.onPause(); - } - mCurrentView = view; - mCurrentView.setForegroundTab(true); - 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); - } - - public void handleNewIntent(Intent 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) { - if (url.startsWith(Constants.FILE)) { - Utils.showToast(this, - getResources() - .getString(R.string.message_blocked_local)); - url = null; - } - newTab(url, true); - mIsNewIntent = true; - } - } - - @Override - public void closeEmptyTab() { - if (mCurrentView != null - && mCurrentView.getWebView().copyBackForwardList().getSize() == 0) { - closeCurrentTab(); - } - } - - private void closeCurrentTab() { - //don't delete the tab because the browser will close and mess stuff up - } - - private void selectItem(final int position) { - // update selected item and title, then close the drawer - - mDrawerList.setItemChecked(position, true); - showTab(mWebViews.get(position)); - - // Use a delayed handler to make the transition smooth - // otherwise it will get caught up with the showTab code - // and cause a janky motion - final Handler handler = new Handler(); - handler.postDelayed(new Runnable() { - @Override - public void run() { - mDrawerLayout.closeDrawer(mDrawer); - } - }, 150); - - } - - /** - * 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); - } - - protected 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)) { - closeActivity(); - } else { - mIdList.remove(position); - mWebViews.remove(position); - if (mPreferences.getBoolean( - PreferenceConstants.CLEAR_CACHE_EXIT, false) - && mCurrentView != null && !isIncognito()) { - mCurrentView.clearCache(true); - Log.i(Constants.TAG, "Cache Cleared"); - - } - if (mPreferences.getBoolean( - PreferenceConstants.CLEAR_HISTORY_EXIT, false) - && !isIncognito()) { - clearHistory(); - Log.i(Constants.TAG, "History Cleared"); - - } - if (mPreferences.getBoolean( - PreferenceConstants.CLEAR_COOKIES_EXIT, false) - && !isIncognito()) { - clearCookies(); - Log.i(Constants.TAG, "Cookies 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; - closeActivity(); - } - - Log.i(Constants.TAG, "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 && !isIncognito()) { - mCurrentView.clearCache(true); - Log.i(Constants.TAG, "Cache Cleared"); - - } - if (mPreferences.getBoolean(PreferenceConstants.CLEAR_HISTORY_EXIT, - false) && !isIncognito()) { - clearHistory(); - Log.i(Constants.TAG, "History Cleared"); - - } - if (mPreferences.getBoolean(PreferenceConstants.CLEAR_COOKIES_EXIT, - false) && !isIncognito()) { - clearCookies(); - Log.i(Constants.TAG, "Cookies 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; - } - - @SuppressWarnings("deprecation") - public void clearHistory() { - this.deleteDatabase(DatabaseHandler.DATABASE_NAME); - WebViewDatabase m = WebViewDatabase.getInstance(this); - m.clearFormData(); - m.clearHttpAuthUsernamePassword(); - if (API < 18) { - m.clearUsernamePassword(); - WebIconDatabase.getInstance().removeAllIcons(); - } - if (mSystemBrowser) { - try { - Browser.clearHistory(getContentResolver()); - } catch (NullPointerException ignored) { - } - } - SettingsController.setClearHistory(true); - Utils.trimCache(this); - } - - public void clearCookies() { - CookieManager c = CookieManager.getInstance(); - CookieSyncManager.createInstance(this); - c.removeAllCookie(); - } - - @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(Constants.TAG, "onBackPressed"); - if (mCurrentView.canGoBack()) { - if (!mCurrentView.isShown()) { - onHideCustomView(); - } else { - mCurrentView.goBack(); - } - } else { - deleteTab(mDrawerList.getCheckedItemPosition()); - } - } else { - Log.e(Constants.TAG, - "So madness. Much confusion. Why happen."); - super.onBackPressed(); - } - } - } - - @Override - protected void onPause() { - super.onPause(); - Log.i(Constants.TAG, "onPause"); - if (mCurrentView != null) { - mCurrentView.pauseTimers(); - mCurrentView.onPause(); - } - if (mHistoryDatabase != null) { - if (mHistoryDatabase.isOpen()) { - mHistoryDatabase.close(); - } - } - if (mHistoryHandler != null) { - if (mHistoryHandler.isOpen()) { - mHistoryHandler.close(); - } - } - - } - - public void saveOpenTabs() { - if (mPreferences - .getBoolean(PreferenceConstants.RESTORE_LOST_TABS, true)) { - String s = ""; - for (int n = 0; n < mWebViews.size(); n++) { - if (mWebViews.get(n).getUrl() != null) { - s = s + mWebViews.get(n).getUrl() + "|$|SEPARATOR|$|"; - } - } - mEditPrefs.putString(PreferenceConstants.URL_MEMORY, s); - mEditPrefs.commit(); - } - } - - @Override - protected void onDestroy() { - Log.i(Constants.TAG, "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(Constants.TAG, "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 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 - * - * @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) { - - Bitmap bm = Bitmap.createBitmap(mActionBarSize, mActionBarSize, - Config.ARGB_8888); - String text = number + ""; - Paint paint = new Paint(); - paint.setTextAlign(Paint.Align.CENTER); - paint.setAntiAlias(true); - paint.setStyle(Style.FILL); - paint.setColor(mNumberIconColor); - if (number > 99) { - number = 99; - } - // pixels, 36 dp - if (mActionBarSizeDp < 50) { - if (number > 9) { - paint.setTextSize(mActionBarSize * 3 / 4); // originally - // 40 - // pixels, - // 24 dp - } else { - paint.setTextSize(mActionBarSize * 9 / 10); // originally 50 - // pixels, 30 dp - } - } else { - paint.setTextSize(mActionBarSize * 3 / 4); - } - Canvas canvas = new Canvas(bm); - // originally only vertical padding of 5 pixels - - int xPos = (canvas.getWidth() / 2); - int yPos = (int) ((canvas.getHeight() / 2) - ((paint.descent() + paint - .ascent()) / 2)); - - canvas.drawText(text, xPos, yPos, paint); - - return new BitmapDrawable(getResources(), bm); - } - - public class LightningViewAdapter extends ArrayAdapter { - - Context context; - - int layoutResourceId; - - List data = null; - - public LightningViewAdapter(Context context, int layoutResourceId, - List 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()); - if (web.isForegroundTab()) { - holder.txtTitle.setTextAppearance(context, R.style.boldText); - } else { - holder.txtTitle.setTextAppearance(context, R.style.normalText); - } - - Bitmap favicon = web.getFavicon(); - holder.favicon.setImageBitmap(favicon); - return row; - } + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + initialize(); + } - class LightningViewHolder { - - TextView txtTitle; - - ImageView favicon; - - ImageView exit; - } + @SuppressWarnings("deprecation") + private synchronized void initialize() { + setContentView(R.layout.activity_main); + TypedValue typedValue = new TypedValue(); + Theme theme = getTheme(); + theme.resolveAttribute(R.attr.numberColor, typedValue, true); + mNumberIconColor = typedValue.data; + mPreferences = getSharedPreferences(PreferenceConstants.PREFERENCES, 0); + mEditPrefs = mPreferences.edit(); + mContext = this; + if (mIdList != null) { + mIdList.clear(); + } else { + mIdList = new ArrayList(); + } + if (mWebViews != null) { + mWebViews.clear(); + } else { + mWebViews = new ArrayList(); } - public class BookmarkViewAdapter extends ArrayAdapter { + 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 = (RelativeLayout) 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); + mDrawerList.setDivider(null); + mDrawerList.setDividerHeight(0); + mDrawerRight = (LinearLayout) findViewById(R.id.right_drawer); + mDrawerListRight = (ListView) findViewById(R.id.right_drawer_list); + mDrawerListRight.setDivider(null); + mDrawerListRight.setDividerHeight(0); + setNavigationDrawerWidth(); + 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(); - Context context; + mHomepage = mPreferences.getString(PreferenceConstants.HOMEPAGE, Constants.HOMEPAGE); - int layoutResourceId; + mTitleAdapter = new LightningViewAdapter(this, R.layout.tab_list_item, mWebViews); + mDrawerList.setAdapter(mTitleAdapter); + mDrawerList.setOnItemClickListener(new DrawerItemClickListener()); + mDrawerList.setOnItemLongClickListener(new DrawerItemLongClickListener()); - List data = null; + mBookmarkList = getBookmarks(); + mBookmarkAdapter = new BookmarkViewAdapter(this, R.layout.bookmark_list_item, mBookmarkList); + mDrawerListRight.setAdapter(mBookmarkAdapter); + mDrawerListRight.setOnItemClickListener(new BookmarkItemClickListener()); + mDrawerListRight.setOnItemLongClickListener(new BookmarkItemLongClickListener()); - public BookmarkViewAdapter(Context context, int layoutResourceId, - List data) { - super(context, layoutResourceId, data); - this.layoutResourceId = layoutResourceId; - this.context = context; - this.data = data; - } + 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 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); + public void onClick(View v) { + if (mCurrentView != null) { + if (mCurrentView.canGoBack()) { + mCurrentView.goBack(); } else { - holder = (BookmarkViewHolder) row.getTag(); + deleteTab(mDrawerList.getCheckedItemPosition()); } - - 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; - } + }); } + if (forward != null) { + forward.setOnClickListener(new OnClickListener() { - 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(); + @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; } - } - - private class DownloadImageTask extends AsyncTask { - - ImageView bmImage; - - HistoryItem mWeb; + return false; + } - public DownloadImageTask(ImageView bmImage, HistoryItem web) { - this.bmImage = bmImage; - this.mWeb = web; - } + }); + mSearch.setOnFocusChangeListener(new View.OnFocusChangeListener() { - 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) { - } + @Override + public void onFocusChange(View v, boolean hasFocus) { + if (!hasFocus && mCurrentView != null) { + if (mCurrentView != null) { + if (mCurrentView.getProgress() < 100) { + setIsLoading(); } else { - // if it exists, retrieve it from the cache - mIcon = BitmapFactory.decodeFile(image.getPath()); + setIsFinishedLoading(); } - 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; + } + 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() { + + @SuppressLint("ClickableViewAccessibility") + @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; + } } - - protected void onPostExecute(Bitmap result) { - bmImage.setImageBitmap(result); - mWeb.setBitmap(result); - notifyBookmarkDataSetChanged(); + 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); + mDrawerLayout.setDrawerShadow(R.drawable.drawer_right_shadow, GravityCompat.END); + mDrawerLayout.setDrawerShadow(R.drawable.drawer_shadow, GravityCompat.START); + initializePreferences(); + initializeTabs(); + + if (API < 19) { + WebIconDatabase.getInstance().open(getDir("icons", MODE_PRIVATE).getPath()); + } + + checkForTor(); + + } + + /* + * If Orbot/Tor is installed, prompt the user if they want to enable + * proxying for this session + */ + public boolean checkForTor() { + boolean useProxy = mPreferences.getBoolean(PreferenceConstants.USE_PROXY, false); + + OrbotHelper oh = new OrbotHelper(this); + if (oh.isOrbotInstalled() + && !mPreferences.getBoolean(PreferenceConstants.INITIAL_CHECK_FOR_TOR, false)) { + mEditPrefs.putBoolean(PreferenceConstants.INITIAL_CHECK_FOR_TOR, true); + mEditPrefs.apply(); + DialogInterface.OnClickListener dialogClickListener = new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + switch (which) { + case DialogInterface.BUTTON_POSITIVE: + mPreferences.edit().putBoolean(PreferenceConstants.USE_PROXY, true) + .apply(); + + initializeTor(); + break; + case DialogInterface.BUTTON_NEGATIVE: + mPreferences.edit().putBoolean(PreferenceConstants.USE_PROXY, false) + .apply(); + break; + } + } + }; + + AlertDialog.Builder builder = new AlertDialog.Builder(this); + builder.setMessage(R.string.use_tor_prompt) + .setPositiveButton(R.string.yes, dialogClickListener) + .setNegativeButton(R.string.no, dialogClickListener).show(); + + return true; + } else if (oh.isOrbotInstalled() & useProxy == true) { + initializeTor(); + return true; + } else { + mEditPrefs.putBoolean(PreferenceConstants.USE_PROXY, false); + mEditPrefs.apply(); + return false; + } + } + + /* + * Initialize WebKit Proxying for Tor + */ + public void initializeTor() { + + OrbotHelper oh = new OrbotHelper(this); + if (!oh.isOrbotRunning()) { + oh.requestOrbotStart(this); + } + + try { + String host = mPreferences.getString(PreferenceConstants.USE_PROXY_HOST, "localhost"); + int port = mPreferences.getInt(PreferenceConstants.USE_PROXY_PORT, 8118); + WebkitProxy.setProxy("acr.browser.lightning.BrowserApp", getApplicationContext(), host, + port); + } catch (Exception e) { + Log.d(Constants.TAG, "error enabling web proxying", e); + } + + } + + public void setNavigationDrawerWidth() { + int width = getResources().getDisplayMetrics().widthPixels * 3 / 4; + int maxWidth = Utils.convertToDensityPixels(mContext, 300); + if (width > maxWidth) { + DrawerLayout.LayoutParams params = (android.support.v4.widget.DrawerLayout.LayoutParams) mDrawer + .getLayoutParams(); + params.width = maxWidth; + mDrawer.setLayoutParams(params); + DrawerLayout.LayoutParams paramsRight = (android.support.v4.widget.DrawerLayout.LayoutParams) mDrawerRight + .getLayoutParams(); + paramsRight.width = maxWidth; + mDrawerRight.setLayoutParams(paramsRight); + } else { + DrawerLayout.LayoutParams params = (android.support.v4.widget.DrawerLayout.LayoutParams) mDrawer + .getLayoutParams(); + params.width = width; + mDrawer.setLayoutParams(params); + DrawerLayout.LayoutParams paramsRight = (android.support.v4.widget.DrawerLayout.LayoutParams) mDrawerRight + .getLayoutParams(); + paramsRight.width = width; + mDrawerRight.setLayoutParams(paramsRight); + } + } + + /* + * Override this class + */ + public synchronized void initializeTabs() { + + } + + public void restoreOrNewTab() { + mIdGenerator = 0; + + String url = null; + if (getIntent() != null) { + url = getIntent().getDataString(); + if (url != null) { + if (url.startsWith(Constants.FILE)) { + Utils.showToast(this, getResources().getString(R.string.message_blocked_local)); + url = null; + } + } + } + if (mPreferences.getBoolean(PreferenceConstants.RESTORE_LOST_TABS, true)) { + String mem = mPreferences.getString(PreferenceConstants.URL_MEMORY, ""); + mEditPrefs.putString(PreferenceConstants.URL_MEMORY, ""); + String[] array = Utils.getArray(mem); + int count = 0; + for (int n = 0; n < array.length; n++) { + if (array[n].length() > 0) { + newTab(array[n], true); + count++; + } + } + if (url != null) { + newTab(url, true); + } else if (count == 0) { + newTab(null, true); + } + } else { + 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; + } + + updateCookiePreference(); + if (mPreferences.getBoolean(PreferenceConstants.USE_PROXY, false)) { + initializeTor(); + } else { + try { + WebkitProxy.resetProxy("acr.browser.lightning.BrowserApp", getApplicationContext()); + } catch (Exception e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + } + + /* + * Override this if class overrides BrowserActivity + */ + public void updateCookiePreference() { + + } + + @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) { + 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)) { + if (mDrawerLayout.isDrawerOpen(mDrawerRight)) { + mDrawerLayout.closeDrawer(mDrawerRight); + mDrawerLayout.openDrawer(mDrawer); + } else if (mDrawerLayout.isDrawerOpen(mDrawer)) { + mDrawerLayout.closeDrawer(mDrawer); + } + mDrawerToggle.syncState(); + return true; + } + // Handle action buttons + switch (item.getItemId()) { + case android.R.id.home: + if (mDrawerLayout.isDrawerOpen(mDrawerRight)) { + mDrawerLayout.closeDrawer(mDrawerRight); } - } - - static String getDomainName(String url) throws URISyntaxException { - URI uri = new URI(url); - String domain = uri.getHost(); - if (domain == null) { - return url; + mDrawerToggle.syncState(); + return true; + case R.id.action_back: + if (mCurrentView != null) { + if (mCurrentView.canGoBack()) { + mCurrentView.goBack(); + } } - return domain.startsWith("www.") ? domain.substring(4) : domain; - } - - @Override - public void updateUrl(String url) { - if (url == null) { - return; + return true; + case R.id.action_forward: + if (mCurrentView != null) { + if (mCurrentView.canGoForward()) { + mCurrentView.goForward(); + } } - url = url.replaceFirst(Constants.HTTP, ""); - if (url.startsWith(Constants.FILE)) { - url = ""; + return true; + case R.id.action_new_tab: + newTab(null, true); + return true; + case R.id.action_incognito: + startActivity(new Intent(this, IncognitoActivity.class)); + 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(this, SettingsActivity.class)); + 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(); + } - mSearch.setText(url); - } + /** + * The click listener for ListView in the navigation drawer + */ + private class DrawerItemClickListener implements ListView.OnItemClickListener { @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(); - } + public void onItemClick(AdapterView parent, View view, int position, long id) { + mIsNewIntent = false; + selectItem(position); } + } - @Override - public void updateHistory(final String title, final String url) { + /** + * 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; } + } - public void addItemToHistory(final String title, final String url) { - Runnable update = new Runnable() { - @Override - public void run() { - if (isSystemBrowserAvailable()) { - try { - Browser.updateVisitedHistory(getContentResolver(), url, - true); - } catch (NullPointerException ignored) { - } - } - try { - StringBuilder sb = new StringBuilder("url" + " = "); - DatabaseUtils.appendEscapedSQLString(sb, url); - - if (mHistoryHandler == null) { - mHistoryHandler = new DatabaseHandler(mContext); - mHistoryDatabase = mHistoryHandler - .getReadableDatabase(); - } else if (!mHistoryHandler.isOpen()) { - mHistoryHandler = new DatabaseHandler(mContext); - mHistoryDatabase = mHistoryHandler - .getReadableDatabase(); - } else if (mHistoryDatabase == null) { - mHistoryDatabase = mHistoryHandler - .getReadableDatabase(); - } else if (!mHistoryDatabase.isOpen()) { - mHistoryDatabase = mHistoryHandler - .getReadableDatabase(); - } - Cursor cursor = mHistoryDatabase.query( - DatabaseHandler.TABLE_HISTORY, new String[]{"id", - "url", "title"}, sb.toString(), null, - null, null, null); - if (!cursor.moveToFirst()) { - mHistoryHandler.addHistoryItem(new HistoryItem(url, - title)); - } else { - mHistoryHandler.delete(url); - mHistoryHandler.addHistoryItem(new HistoryItem(url, - title)); - } - cursor.close(); - cursor = null; - } catch (IllegalStateException e) { - Log.e(Constants.TAG, - "IllegalStateException in updateHistory"); - } catch (NullPointerException e) { - Log.e(Constants.TAG, - "NullPointerException in updateHistory"); - } catch (SQLiteException e) { - Log.e(Constants.TAG, "SQLiteException in updateHistory"); - } - } - }; - if (url != null) { - if (!url.startsWith(Constants.FILE)) { - new Thread(update).start(); + 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()); + } + // keep any jank from happening when the drawer is closed after the + // URL starts to load + final Handler handler = new Handler(); + handler.postDelayed(new Runnable() { + @Override + public void run() { + mDrawerLayout.closeDrawer(mDrawerRight); } + }, 150); } + } - /** - * 1, 2, 3, testing... is there a system browser that has some nice bookmarks for us? - */ - public boolean isSystemBrowserAvailable() { - return mSystemBrowser; - } + private class BookmarkItemLongClickListener implements ListView.OnItemLongClickListener { - /** - * 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 { + @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() { - Uri bookmarks = Browser.BOOKMARKS_URI; - c = getContentResolver() - .query(bookmarks, columns, null, null, null); - } catch (SQLiteException ignored) { - } catch (IllegalStateException ignored) { - } catch (NullPointerException ignored) { - } + @Override + public void onClick(DialogInterface dialog, int which) { + deleteBookmark(mBookmarkList.get(position).getUrl()); + } + }) + .setNeutralButton(getResources().getString(R.string.action_edit), + new DialogInterface.OnClickListener() { - 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; - } + @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 iter = mBookmarkList.iterator(); + HistoryItem item; + while (iter.hasNext()) { + item = iter.next(); - /** - * method to generate search suggestions for the AutoCompleteTextView from previously searched URLs - */ - private void initializeSearchSuggestions(final AutoCompleteTextView getUrl) { + bookWriter.write(item.getTitle()); + urlWriter.write(item.getUrl()); + bookWriter.newLine(); + urlWriter.newLine(); - 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"); - } + 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.setForegroundTab(false); + mCurrentView.onPause(); + } + mCurrentView = view; + mCurrentView.setForegroundTab(true); + 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); + } + + public void handleNewIntent(Intent 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) { + if (url.startsWith(Constants.FILE)) { + Utils.showToast(this, getResources().getString(R.string.message_blocked_local)); + url = null; + } + newTab(url, true); + mIsNewIntent = true; + } + } + + @Override + public void closeEmptyTab() { + if (mCurrentView != null && mCurrentView.getWebView().copyBackForwardList().getSize() == 0) { + closeCurrentTab(); + } + } + + private void closeCurrentTab() { + // don't delete the tab because the browser will close and mess stuff up + } + + private void selectItem(final int position) { + // update selected item and title, then close the drawer + + mDrawerList.setItemChecked(position, true); + showTab(mWebViews.get(position)); + + // Use a delayed handler to make the transition smooth + // otherwise it will get caught up with the showTab code + // and cause a janky motion + final Handler handler = new Handler(); + handler.postDelayed(new Runnable() { + @Override + public void run() { + mDrawerLayout.closeDrawer(mDrawer); + } + }, 150); + + } + + /** + * 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); + } + + protected 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)) { + closeActivity(); + } else { + mIdList.remove(position); + mWebViews.remove(position); + if (mPreferences.getBoolean(PreferenceConstants.CLEAR_CACHE_EXIT, false) + && mCurrentView != null && !isIncognito()) { + mCurrentView.clearCache(true); + Log.i(Constants.TAG, "Cache Cleared"); + + } + if (mPreferences.getBoolean(PreferenceConstants.CLEAR_HISTORY_EXIT, false) + && !isIncognito()) { + clearHistory(); + Log.i(Constants.TAG, "History Cleared"); + + } + if (mPreferences.getBoolean(PreferenceConstants.CLEAR_COOKIES_EXIT, false) + && !isIncognito()) { + clearCookies(); + Log.i(Constants.TAG, "Cookies Cleared"); + + } + if (reference != null) { + reference.pauseTimers(); + reference.onDestroy(); + } + mCurrentView = null; + mTitleAdapter.notifyDataSetChanged(); + finish(); - getUrl.setSelectAllOnFocus(true); - mSearchAdapter = new SearchAdapter(mContext, isIncognito()); - getUrl.setAdapter(mSearchAdapter); + } + } + mTitleAdapter.notifyDataSetChanged(); + Drawable icon = writeOnDrawable(mWebViews.size()); + mActionBar.setIcon(icon); + + if (mIsNewIntent && isShown) { + mIsNewIntent = false; + closeActivity(); + } + + Log.i(Constants.TAG, "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 && !isIncognito()) { + mCurrentView.clearCache(true); + Log.i(Constants.TAG, "Cache Cleared"); + + } + if (mPreferences.getBoolean(PreferenceConstants.CLEAR_HISTORY_EXIT, false) + && !isIncognito()) { + clearHistory(); + Log.i(Constants.TAG, "History Cleared"); + + } + if (mPreferences.getBoolean(PreferenceConstants.CLEAR_COOKIES_EXIT, false) + && !isIncognito()) { + clearCookies(); + Log.i(Constants.TAG, "Cookies 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; + } + + @SuppressWarnings("deprecation") + public void clearHistory() { + this.deleteDatabase(DatabaseHandler.DATABASE_NAME); + WebViewDatabase m = WebViewDatabase.getInstance(this); + m.clearFormData(); + m.clearHttpAuthUsernamePassword(); + if (API < 18) { + m.clearUsernamePassword(); + WebIconDatabase.getInstance().removeAllIcons(); + } + if (mSystemBrowser) { + try { + Browser.clearHistory(getContentResolver()); + } catch (NullPointerException ignored) { + } + } + SettingsController.setClearHistory(true); + Utils.trimCache(this); + } + + public void clearCookies() { + CookieManager c = CookieManager.getInstance(); + CookieSyncManager.createInstance(this); + c.removeAllCookie(); + } + + @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(Constants.TAG, "onBackPressed"); + if (mCurrentView.canGoBack()) { + if (!mCurrentView.isShown()) { + onHideCustomView(); + } else { + mCurrentView.goBack(); + } + } else { + deleteTab(mDrawerList.getCheckedItemPosition()); + } + } else { + Log.e(Constants.TAG, "So madness. Much confusion. Why happen."); + super.onBackPressed(); + } + } + } + + @Override + protected void onPause() { + super.onPause(); + Log.i(Constants.TAG, "onPause"); + if (mCurrentView != null) { + mCurrentView.pauseTimers(); + mCurrentView.onPause(); + } + if (mHistoryDatabase != null) { + if (mHistoryDatabase.isOpen()) { + mHistoryDatabase.close(); + } + } + if (mHistoryHandler != null) { + if (mHistoryHandler.isOpen()) { + mHistoryHandler.close(); + } + } + + } + + public void saveOpenTabs() { + if (mPreferences.getBoolean(PreferenceConstants.RESTORE_LOST_TABS, true)) { + String s = ""; + for (int n = 0; n < mWebViews.size(); n++) { + if (mWebViews.get(n).getUrl() != null) { + s = s + mWebViews.get(n).getUrl() + "|$|SEPARATOR|$|"; + } + } + mEditPrefs.putString(PreferenceConstants.URL_MEMORY, s); + mEditPrefs.commit(); + } + } + + @Override + protected void onDestroy() { + Log.i(Constants.TAG, "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(Constants.TAG, "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 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 + * + * @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) { + + Bitmap bm = Bitmap.createBitmap(mActionBarSize, mActionBarSize, Config.ARGB_8888); + String text = number + ""; + Paint paint = new Paint(); + paint.setTextAlign(Paint.Align.CENTER); + paint.setAntiAlias(true); + paint.setStyle(Style.FILL); + paint.setColor(mNumberIconColor); + if (number > 99) { + number = 99; + } + // pixels, 36 dp + if (mActionBarSizeDp < 50) { + if (number > 9) { + paint.setTextSize(mActionBarSize * 3 / 4); // originally + // 40 + // pixels, + // 24 dp + } else { + paint.setTextSize(mActionBarSize * 9 / 10); // originally 50 + // pixels, 30 dp + } + } else { + paint.setTextSize(mActionBarSize * 3 / 4); + } + Canvas canvas = new Canvas(bm); + // originally only vertical padding of 5 pixels + + int xPos = (canvas.getWidth() / 2); + int yPos = (int) ((canvas.getHeight() / 2) - ((paint.descent() + paint.ascent()) / 2)); + + canvas.drawText(text, xPos, yPos, paint); + + return new BitmapDrawable(getResources(), bm); + } + + public class LightningViewAdapter extends ArrayAdapter { + + Context context; + + int layoutResourceId; + + List data = null; + + public LightningViewAdapter(Context context, int layoutResourceId, List data) { + super(context, layoutResourceId, data); + this.layoutResourceId = layoutResourceId; + this.context = context; + this.data = data; } - public boolean isIncognito() { - return false; - } + @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() { - // Damn it, I regret not using SQLite in the first place for this - private List getBookmarks() { - List bookmarks = new ArrayList(); - 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) { + @Override + public void onClick(View view) { + deleteTab(position); } - Collections.sort(bookmarks, new SortIgnoreCase()); - return bookmarks; - } - /** - * returns a list of HistoryItems - */ - private List 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() { + LightningView web = data.get(position); + holder.txtTitle.setText(web.getTitle()); + if (web.isForegroundTab()) { + holder.txtTitle.setTextAppearance(context, R.style.boldText); + } else { + holder.txtTitle.setTextAppearance(context, R.style.normalText); + } - @Override - public void run() { - String historyHtml = HistoryPageVariables.Heading; - List historyList = getLatestHistory(); - Iterator 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; - } + Bitmap favicon = web.getFavicon(); + holder.favicon.setImageBitmap(favicon); + return row; + } - 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(""); - } + class LightningViewHolder { - }); - history.run(); - } + TextView txtTitle; - /** - * helper function that opens the bookmark drawer - */ - private void openBookmarks() { - if (mDrawerLayout.isDrawerOpen(mDrawer)) { - mDrawerLayout.closeDrawers(); - } - mDrawerToggle.syncState(); - mDrawerLayout.openDrawer(mDrawerRight); - } + ImageView favicon; - public void closeDrawers() { - mDrawerLayout.closeDrawers(); + ImageView exit; } + } - @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 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(); - } + public class BookmarkViewAdapter extends ArrayAdapter { - view.loadUrl(Constants.FILE + bookmarkWebPage); - } + Context context; - /** - * 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); + int layoutResourceId; - try { - BufferedReader readUrlRead = new BufferedReader(new FileReader( - bookUrl)); - String u; - while ((u = readUrlRead.readLine()) != null) { - if (u.contentEquals(url)) { - readUrlRead.close(); - return; - } - } - readUrlRead.close(); + List data = null; - } 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(); + public BookmarkViewAdapter(Context context, int layoutResourceId, List data) { + super(context, layoutResourceId, data); + this.layoutResourceId = layoutResourceId; + this.context = context; + this.data = data; } @Override - public void update() { - mTitleAdapter.notifyDataSetChanged(); - } + public View getView(int position, View convertView, ViewGroup parent) { + View row = convertView; + BookmarkViewHolder holder = null; - @Override - /** - * opens a file chooser - * param ValueCallback is the message from the WebView indicating a file chooser - * should be opened - */ - public void openFileChooser(ValueCallback 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); - } + if (row == null) { + LayoutInflater inflater = ((Activity) context).getLayoutInflater(); + row = inflater.inflate(layoutResourceId, parent, false); - @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; + 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; } - @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); + class BookmarkViewHolder { + + TextView txtTitle; + + ImageView favicon; } + } - @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; + 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(); } + } - @Override - public void onHideCustomView() { - if (mCustomView == null || mCustomViewCallback == null - || mCurrentView == null) { - return; - } - Log.i(Constants.TAG, "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); - } + private class DownloadImageTask extends AsyncTask { - if (API < 19) { - try { - mCustomViewCallback.onCustomViewHidden(); - } catch (Throwable ignored) { + ImageView bmImage; - } - } - mFullscreenContainer = null; - mCustomView = null; - if (mVideoView != null) { - mVideoView.setOnErrorListener(null); - mVideoView.setOnCompletionListener(null); - mVideoView = null; - } - setRequestedOrientation(mOriginalOrientation); + HistoryItem mWeb; + + public DownloadImageTask(ImageView bmImage, HistoryItem web) { + this.bmImage = bmImage; + this.mWeb = web; } - private class VideoCompletionListener implements - MediaPlayer.OnCompletionListener, MediaPlayer.OnErrorListener { + 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(); + } - @Override - public boolean onError(MediaPlayer mp, int what, int extra) { - return false; + } 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(); + } - @Override - public void onCompletion(MediaPlayer mp) { - onHideCustomView(); + } catch (Exception e) { } - + } + if (mIcon == null) { + return mWebpageBitmap; + } else { + return mIcon; + } } - /** - * 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); + protected void onPostExecute(Bitmap result) { + bmImage.setImageBitmap(result); + mWeb.setBitmap(result); + notifyBookmarkDataSetChanged(); } + } - /** - * a class extending FramLayout used to display fullscreen videos - */ - static class FullscreenHolder extends FrameLayout { + 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; + } - public FullscreenHolder(Context ctx) { - super(ctx); - setBackgroundColor(ctx.getResources().getColor( - android.R.color.black)); - } + @Override + public void updateUrl(String url) { + if (url == null) { + return; + } + url = url.replaceFirst(Constants.HTTP, ""); + if (url.startsWith(Constants.FILE)) { + url = ""; + } - @Override - public boolean onTouchEvent(MotionEvent evt) { - return true; - } + mSearch.setText(url); + } + @Override + public void updateProgress(int n) { + if (!mProgress.isShown()) { + mProgress.setVisibility(View.VISIBLE); } - - @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; + ObjectAnimator animator = ObjectAnimator.ofInt(mProgress, "progress", n); + animator.setDuration(200); + animator.setInterpolator(new DecelerateInterpolator()); + animator.start(); + if (n == 100) { + mProgress.setVisibility(View.INVISIBLE); + setIsFinishedLoading(); + } else { + setIsLoading(); } + } - @SuppressLint("InflateParams") - @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); + @Override + public void updateHistory(final String title, final String url) { + + } + + public void addItemToHistory(final String title, final String url) { + Runnable update = new Runnable() { + @Override + public void run() { + if (isSystemBrowserAvailable()) { + try { + Browser.updateVisitedHistory(getContentResolver(), url, true); + } catch (NullPointerException ignored) { + } } - return mVideoProgressView; - } + try { + StringBuilder sb = new StringBuilder("url" + " = "); + DatabaseUtils.appendEscapedSQLString(sb, url); - @Override - /** - * handles javascript requests to create a new window in the browser - */ - public void onCreateWindow(boolean isUserGesture, Message resultMsg) { - if (resultMsg == null) { - return; + if (mHistoryHandler == null) { + mHistoryHandler = new DatabaseHandler(mContext); + mHistoryDatabase = mHistoryHandler.getReadableDatabase(); + } else if (!mHistoryHandler.isOpen()) { + mHistoryHandler = new DatabaseHandler(mContext); + mHistoryDatabase = mHistoryHandler.getReadableDatabase(); + } else if (mHistoryDatabase == null) { + mHistoryDatabase = mHistoryHandler.getReadableDatabase(); + } else if (!mHistoryDatabase.isOpen()) { + mHistoryDatabase = mHistoryHandler.getReadableDatabase(); + } + Cursor cursor = mHistoryDatabase.query(DatabaseHandler.TABLE_HISTORY, + new String[] { "id", "url", "title" }, sb.toString(), null, null, null, + null); + if (!cursor.moveToFirst()) { + mHistoryHandler.addHistoryItem(new HistoryItem(url, title)); + } else { + mHistoryHandler.delete(url); + mHistoryHandler.addHistoryItem(new HistoryItem(url, title)); + } + cursor.close(); + cursor = null; + } catch (IllegalStateException e) { + Log.e(Constants.TAG, "IllegalStateException in updateHistory"); + } catch (NullPointerException e) { + Log.e(Constants.TAG, "NullPointerException in updateHistory"); + } catch (SQLiteException e) { + Log.e(Constants.TAG, "SQLiteException in updateHistory"); + } + } + }; + if (url != null) { + if (!url.startsWith(Constants.FILE)) { + new Thread(update).start(); + + } + } + } + + /** + * 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, isIncognito()); + getUrl.setAdapter(mSearchAdapter); + } + + public boolean isIncognito() { + return false; + } + + // Damn it, I regret not using SQLite in the first place for this + private List getBookmarks() { + List bookmarks = new ArrayList(); + 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 + */ + private List 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 historyList = getLatestHistory(); + Iterator 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; } - 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; - } + 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); + } + + public void closeDrawers() { + mDrawerLayout.closeDrawers(); + } + + @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 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 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(Constants.TAG, "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 { - /** - * it hides the action bar, seriously what else were you expecting - */ @Override - public void hideActionBar() { - if (mActionBar.isShowing() && mFullScreen) { - mActionBar.hide(); - } + public boolean onError(MediaPlayer mp, int what, int extra) { + return false; } @Override - /** - * obviously it shows the action bar if it's hidden - */ - public void showActionBar() { - if (!mActionBar.isShowing() && mFullScreen) { - mActionBar.show(); - } - } - + 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)); + } + + @SuppressLint("ClickableViewAccessibility") @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 (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(); + 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; + } + + @SuppressLint("InflateParams") + @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 (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; + } } - } 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(); - } + }; + + 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; - /** - * 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); - } - } + case DialogInterface.BUTTON_NEUTRAL: + ClipboardManager clipboard = (ClipboardManager) getSystemService(CLIPBOARD_SERVICE); + ClipData clip = ClipData.newPlainText("label", url); + clipboard.setPrimaryClip(clip); - /** - * 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); - } - } + break; + } + } + }; - /** - * 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(); + 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(); - @Override - public boolean isActionBarShowing() { - if (mActionBar != null) { - return mActionBar.isShowing(); } else { - return false; - } + 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 this, use finish() for Incognito, moveTaskToBack for Main - public void closeActivity() { - finish(); + @Override + public boolean isActionBarShowing() { + if (mActionBar != null) { + return mActionBar.isShowing(); + } else { + return false; } + } - public class SortIgnoreCase implements Comparator { + // Override this, use finish() for Incognito, moveTaskToBack for Main + public void closeActivity() { + finish(); + } - public int compare(HistoryItem o1, HistoryItem o2) { - return o1.getTitle().toLowerCase(Locale.getDefault()) - .compareTo(o2.getTitle().toLowerCase(Locale.getDefault())); - } + public class SortIgnoreCase implements Comparator { + public int compare(HistoryItem o1, HistoryItem o2) { + return o1.getTitle().toLowerCase(Locale.getDefault()) + .compareTo(o2.getTitle().toLowerCase(Locale.getDefault())); } + + } }