diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 9b9b0a9..7e0481e 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -47,6 +47,18 @@ + + + + + + + + + + + + diff --git a/app/src/main/java/acr/browser/lightning/activity/BrowserActivity.java b/app/src/main/java/acr/browser/lightning/activity/BrowserActivity.java index 2ffe1ee..78d888c 100644 --- a/app/src/main/java/acr/browser/lightning/activity/BrowserActivity.java +++ b/app/src/main/java/acr/browser/lightning/activity/BrowserActivity.java @@ -187,7 +187,7 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements LightningDialogBuilder bookmarksDialogBuilder; @Inject - TabsManager tabsManager; + TabsManager mTabsManager; // Preference manager was moved on ThemeableBrowserActivity @@ -346,7 +346,7 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements WebIconDatabase.getInstance().open(getDir("icons", MODE_PRIVATE).getPath()); } - tabsManager.restoreTabsAndHandleIntent(this, getIntent(), isIncognito()); + mTabsManager.restoreTabsAndHandleIntent(this, getIntent(), isIncognito()); // At this point we always have at least a tab in the tab manager showTab(0); @@ -363,7 +363,7 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); imm.hideSoftInputFromWindow(mSearch.getWindowToken(), 0); searchTheWeb(mSearch.getText().toString()); - final LightningView currentView = tabsManager.getCurrentTab(); + final LightningView currentView = mTabsManager.getCurrentTab(); if (currentView != null) { currentView.requestFocus(); } @@ -386,7 +386,7 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); imm.hideSoftInputFromWindow(mSearch.getWindowToken(), 0); searchTheWeb(mSearch.getText().toString()); - final LightningView currentView = tabsManager.getCurrentTab(); + final LightningView currentView = mTabsManager.getCurrentTab(); if (currentView != null) { currentView.requestFocus(); } @@ -397,13 +397,13 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements @Override public void onFocusChange(View v, final boolean hasFocus) { - final LightningView currentView = tabsManager.getCurrentTab(); + final LightningView currentView = mTabsManager.getCurrentTab(); if (!hasFocus && currentView != null) { setIsLoading(currentView.getProgress() < 100); updateUrl(currentView.getUrl(), true); } else if (hasFocus && currentView != null) { String url = currentView.getUrl(); - if (url.startsWith(Constants.FILE)) { + if (UrlUtils.isSpecialUrl(url)) { mSearch.setText(""); } else { mSearch.setText(url); @@ -553,8 +553,8 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements } private void initializePreferences() { - final LightningView currentView = tabsManager.getCurrentTab(); - final WebView currentWebView = tabsManager.getCurrentWebView(); + final LightningView currentView = mTabsManager.getCurrentTab(); + final WebView currentWebView = mTabsManager.getCurrentWebView(); mFullScreen = mPreferences.getFullScreenEnabled(); boolean colorMode = mPreferences.getColorModeEnabled(); colorMode &= !mDarkTheme; @@ -665,7 +665,7 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements @Override public boolean onOptionsItemSelected(MenuItem item) { - final LightningView currentView = tabsManager.getCurrentTab(); + final LightningView currentView = mTabsManager.getCurrentTab(); // Handle action buttons switch (item.getItemId()) { case android.R.id.home: @@ -691,7 +691,7 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements overridePendingTransition(R.anim.slide_up_in, R.anim.fade_out_scale); return true; case R.id.action_share: - if (currentView != null && !currentView.getUrl().startsWith(Constants.FILE)) { + if (currentView != null && !UrlUtils.isSpecialUrl(currentView.getUrl())) { Intent shareIntent = new Intent(Intent.ACTION_SEND); shareIntent.setType("text/plain"); shareIntent.putExtra(Intent.EXTRA_SUBJECT, currentView.getTitle()); @@ -703,7 +703,7 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements openBookmarks(); return true; case R.id.action_copy: - if (currentView != null && !currentView.getUrl().startsWith(Constants.FILE)) { + if (currentView != null && !UrlUtils.isSpecialUrl(currentView.getUrl())) { ClipboardManager clipboard = (ClipboardManager) getSystemService(CLIPBOARD_SERVICE); ClipData clip = ClipData.newPlainText("label", currentView.getUrl()); clipboard.setPrimaryClip(clip); @@ -717,7 +717,7 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements openHistory(); return true; case R.id.action_add_bookmark: - if (currentView != null && !currentView.getUrl().startsWith(Constants.FILE)) { + if (currentView != null && !UrlUtils.isSpecialUrl(currentView.getUrl())) { mEventBus.post(new BrowserEvents.AddBookmark(currentView.getTitle(), currentView.getUrl())); } @@ -761,7 +761,7 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements } private void showSearchInterfaceBar(String text) { - final LightningView currentView = tabsManager.getCurrentTab(); + final LightningView currentView = mTabsManager.getCurrentTab(); if (currentView != null) { currentView.find(text); } @@ -815,9 +815,9 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements * @param position the poition of the tab to display */ private synchronized void showTab(final int position) { - final LightningView currentView = tabsManager.getCurrentTab(); + final LightningView currentView = mTabsManager.getCurrentTab(); final WebView currentWebView = currentView != null ? currentView.getWebView() : null; - final LightningView newView = tabsManager.switchToTab(position); + final LightningView newView = mTabsManager.switchToTab(position); final WebView newWebView = newView != null ? newView.getWebView() : null; if (newView == null || newWebView == null) { return; @@ -825,7 +825,7 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements // Set the background color so the color mode color doesn't show through mBrowserFrame.setBackgroundColor(mBackgroundColor); - if (newView == currentView && !currentView.isShown()) { + if (newView == currentView && currentView.isShown()) { return; } mIsNewIntent = false; @@ -845,6 +845,7 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements updateProgress(0); } + removeViewFromParent(newWebView); mBrowserFrame.addView(newWebView, MATCH_PARENT); newView.requestFocus(); newView.onResume(); @@ -891,32 +892,53 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements } - void handleNewIntent(Intent intent) { + private static void removeViewFromParent(View view) { + ViewGroup parent = ((ViewGroup) view.getParent()); + if (parent != null) { + parent.removeView(view); + } + } - String url = null; + void handleNewIntent(Intent intent) { + final String url; if (intent != null) { url = intent.getDataString(); + } else { + url = null; } int num = 0; - String source = null; + final String source; if (intent != null && intent.getExtras() != null) { num = intent.getExtras().getInt(getPackageName() + ".Origin"); source = intent.getExtras().getString("SOURCE"); + } else { + source = null; } if (num == 1) { loadUrlInCurrentView(url); } else if (url != null) { if (url.startsWith(Constants.FILE)) { - Utils.showSnackbar(this, R.string.message_blocked_local); - url = null; + AlertDialog.Builder builder = new AlertDialog.Builder(this); + builder.setCancelable(true) + .setTitle(R.string.title_warning) + .setMessage(R.string.message_blocked_local) + .setNegativeButton(android.R.string.cancel, null) + .setPositiveButton(R.string.action_open, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + newTab(url, true); + } + }) + .show(); + } else { + newTab(url, true); } - newTab(url, true); mIsNewIntent = (source == null); } } private void loadUrlInCurrentView(final String url) { - final LightningView currentTab = tabsManager.getCurrentTab(); + final LightningView currentTab = mTabsManager.getCurrentTab(); if (currentTab == null) { // This is a problem, probably an assert will be better than a return return; @@ -928,7 +950,7 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements @Override public void closeEmptyTab() { - final WebView currentWebView = tabsManager.getCurrentWebView(); + final WebView currentWebView = mTabsManager.getCurrentWebView(); if (currentWebView != null && currentWebView.copyBackForwardList().getSize() == 0) { closeCurrentTab(); } @@ -942,25 +964,25 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements public void onTrimMemory(int level) { if (level > TRIM_MEMORY_MODERATE && Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) { Log.d(Constants.TAG, "Low Memory, Free Memory"); - tabsManager.freeMemory(); + mTabsManager.freeMemory(); } } private synchronized boolean newTab(String url, boolean show) { // Limit number of tabs for limited version of app - if (!Constants.FULL_VERSION && tabsManager.size() >= 10) { + if (!Constants.FULL_VERSION && mTabsManager.size() >= 10) { Utils.showSnackbar(this, R.string.max_tabs); return false; } mIsNewIntent = false; - LightningView startingTab = tabsManager.newTab(this, url, isIncognito()); + LightningView startingTab = mTabsManager.newTab(this, url, isIncognito()); if (mIdGenerator == 0) { startingTab.resumeTimers(); } mIdGenerator++; if (show) { - showTab(tabsManager.size() - 1); + showTab(mTabsManager.size() - 1); } // TODO Check is this is callable directly from LightningView mEventBus.post(new BrowserEvents.TabsChanged()); @@ -969,7 +991,7 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements // new Handler().postDelayed(new Runnable() { // @Override // public void run() { - // mDrawerListLeft.smoothScrollToPosition(tabsManager.size() - 1); + // mDrawerListLeft.smoothScrollToPosition(mTabsManager.size() - 1); // } // }, 300); @@ -977,16 +999,16 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements } private synchronized void deleteTab(int position) { - final LightningView tabToDelete = tabsManager.getTabAtPosition(position); - final LightningView currentTab = tabsManager.getCurrentTab(); + final LightningView tabToDelete = mTabsManager.getTabAtPosition(position); + final LightningView currentTab = mTabsManager.getCurrentTab(); if (tabToDelete == null) { return; } - int current = tabsManager.positionOf(currentTab); + int current = mTabsManager.positionOf(currentTab); - if (!tabToDelete.getUrl().startsWith(Constants.FILE) && !isIncognito()) { + if (!UrlUtils.isSpecialUrl(tabToDelete.getUrl()) && !isIncognito()) { mPreferences.setSavedUrl(tabToDelete.getUrl()); } final boolean isShown = tabToDelete.isShown(); @@ -995,30 +1017,30 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements mBrowserFrame.setBackgroundColor(mBackgroundColor); } if (current > position) { - tabsManager.deleteTab(position); + mTabsManager.deleteTab(position); mEventBus.post(new BrowserEvents.TabsChanged()); - } else if (tabsManager.size() > position + 1) { + } else if (mTabsManager.size() > position + 1) { if (current == position) { showTab(position + 1); - tabsManager.deleteTab(position); + mTabsManager.deleteTab(position); mEventBus.post(new BrowserEvents.TabsChanged()); } else { - tabsManager.deleteTab(position); + mTabsManager.deleteTab(position); } - } else if (tabsManager.size() > 1) { + } else if (mTabsManager.size() > 1) { if (current == position) { showTab(position - 1); - tabsManager.deleteTab(position); + mTabsManager.deleteTab(position); mEventBus.post(new BrowserEvents.TabsChanged()); } else { - tabsManager.deleteTab(position); + mTabsManager.deleteTab(position); } } else { - if (currentTab != null && (currentTab.getUrl().startsWith(Constants.FILE) + if (currentTab != null && (UrlUtils.isSpecialUrl(currentTab.getUrl()) || currentTab.getUrl().equals(mHomepage))) { closeActivity(); } else { - tabsManager.deleteTab(position); + mTabsManager.deleteTab(position); performExitCleanUp(); tabToDelete.pauseTimers(); mEventBus.post(new BrowserEvents.TabsChanged()); @@ -1036,7 +1058,7 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements } private void performExitCleanUp() { - final LightningView currentTab = tabsManager.getCurrentTab(); + final LightningView currentTab = mTabsManager.getCurrentTab(); if (mPreferences.getClearCacheExit() && currentTab != null && !isIncognito()) { WebUtils.clearCache(currentTab.getWebView()); Log.d(Constants.TAG, "Cache Cleared"); @@ -1059,9 +1081,9 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements @Override public boolean onKeyLongPress(int keyCode, KeyEvent event) { - final LightningView currentTab = tabsManager.getCurrentTab(); + final LightningView currentTab = mTabsManager.getCurrentTab(); if (keyCode == KeyEvent.KEYCODE_BACK) { - showCloseDialog(tabsManager.positionOf(currentTab)); + showCloseDialog(mTabsManager.positionOf(currentTab)); } return true; } @@ -1069,14 +1091,14 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements private void closeBrowser() { mBrowserFrame.setBackgroundColor(mBackgroundColor); performExitCleanUp(); - tabsManager.shutdown(); + mTabsManager.shutdown(); mEventBus.post(new BrowserEvents.TabsChanged()); finish(); } @Override public synchronized void onBackPressed() { - final LightningView currentTab = tabsManager.getCurrentTab(); + final LightningView currentTab = mTabsManager.getCurrentTab(); if (mDrawerLayout.isDrawerOpen(mDrawerLeft)) { mDrawerLayout.closeDrawer(mDrawerLeft); } else if (mDrawerLayout.isDrawerOpen(mDrawerRight)) { @@ -1096,7 +1118,7 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements if (mCustomView != null || mCustomViewCallback != null) { onHideCustomView(); } else { - deleteTab(tabsManager.positionOf(currentTab)); + deleteTab(mTabsManager.positionOf(currentTab)); } } } else { @@ -1109,7 +1131,7 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements @Override protected void onPause() { super.onPause(); - final LightningView currentTab = tabsManager.getCurrentTab(); + final LightningView currentTab = mTabsManager.getCurrentTab(); Log.d(Constants.TAG, "onPause"); if (currentTab != null) { currentTab.pauseTimers(); @@ -1129,7 +1151,7 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements void saveOpenTabs() { if (mPreferences.getRestoreLostTabsEnabled()) { - final String s = tabsManager.tabsString(); + final String s = mTabsManager.tabsString(); mPreferences.setMemoryUrl(s); } } @@ -1159,7 +1181,7 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements @Override protected void onResume() { super.onResume(); - final LightningView currentTab = tabsManager.getCurrentTab(); + final LightningView currentTab = mTabsManager.getCurrentTab(); Log.d(Constants.TAG, "onResume"); if (mSearchAdapter != null) { mSearchAdapter.refreshPreferences(); @@ -1170,7 +1192,7 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements currentTab.onResume(); } initializePreferences(); - tabsManager.resume(this); + mTabsManager.resume(this); supportInvalidateOptionsMenu(); @@ -1186,7 +1208,7 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements * checks if it is a search, url, etc. */ private void searchTheWeb(@NonNull String query) { - final LightningView currentTab = tabsManager.getCurrentTab(); + final LightningView currentTab = mTabsManager.getCurrentTab(); if (query.isEmpty()) { return; } @@ -1271,9 +1293,9 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements if (url == null || mSearch == null || mSearch.hasFocus()) { return; } - final LightningView currentTab = tabsManager.getCurrentTab(); + final LightningView currentTab = mTabsManager.getCurrentTab(); mEventBus.post(new BrowserEvents.CurrentPageUrl(url)); - if (shortUrl && !url.startsWith(Constants.FILE)) { + if (shortUrl && !UrlUtils.isSpecialUrl(url)) { switch (mPreferences.getUrlBoxContentChoice()) { case 0: // Default, show only the domain url = url.replaceFirst(Constants.HTTP, ""); @@ -1292,7 +1314,7 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements break; } } else { - if (url.startsWith(Constants.FILE)) { + if (UrlUtils.isSpecialUrl(url)) { url = ""; } mSearch.setText(url); @@ -1320,7 +1342,7 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements } } }; - if (!url.startsWith(Constants.FILE)) { + if (!UrlUtils.isSpecialUrl(url)) { new Thread(update).start(); } } @@ -1355,7 +1377,7 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements searchTheWeb(url); InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); imm.hideSoftInputFromWindow(getUrl.getWindowToken(), 0); - final LightningView currentTab = tabsManager.getCurrentTab(); + final LightningView currentTab = mTabsManager.getCurrentTab(); if (currentTab != null) { currentTab.requestFocus(); } @@ -1522,7 +1544,7 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements @Override public synchronized void onShowCustomView(final View view, CustomViewCallback callback, int requestedOrientation) { - final LightningView currentTab = tabsManager.getCurrentTab(); + final LightningView currentTab = mTabsManager.getCurrentTab(); if (view == null || mCustomView != null) { if (callback != null) { try { @@ -1569,7 +1591,7 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements @Override public void onHideCustomView() { - final LightningView currentTab = tabsManager.getCurrentTab(); + final LightningView currentTab = mTabsManager.getCurrentTab(); if (mCustomView == null || mCustomViewCallback == null || currentTab == null) { if (mCustomViewCallback != null) { try { @@ -1687,7 +1709,7 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements return; } if (newTab("", true)) { - LightningView newTab = tabsManager.getTabAtPosition(tabsManager.size() - 1); + LightningView newTab = mTabsManager.getTabAtPosition(mTabsManager.size() - 1); if (newTab != null) { final WebView webView = newTab.getWebView(); if (webView != null) { @@ -1709,7 +1731,7 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements */ @Override public void onCloseWindow(LightningView view) { - deleteTab(tabsManager.positionOf(view)); + deleteTab(mTabsManager.positionOf(view)); } /** @@ -1719,7 +1741,7 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements */ @Override public void hideActionBar() { - final WebView currentWebView = tabsManager.getCurrentWebView(); + final WebView currentWebView = mTabsManager.getCurrentWebView(); if (mFullScreen) { if (mBrowserFrame.findViewById(R.id.toolbar_layout) == null) { mUiLayout.removeView(mToolbarLayout); @@ -1759,7 +1781,7 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements @Override public void showActionBar() { if (mFullScreen) { - final WebView view = tabsManager.getCurrentWebView(); + final WebView view = mTabsManager.getCurrentWebView(); if (mToolbarLayout == null) return; @@ -1780,7 +1802,7 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements view.setTranslationY(height); } } - final LightningView currentTab = tabsManager.getCurrentTab(); + final LightningView currentTab = mTabsManager.getCurrentTab(); if (currentTab == null) return; @@ -1823,7 +1845,7 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements * See setIsFinishedLoading and setIsLoading for displaying the correct icon */ private void refreshOrStop() { - final LightningView currentTab = tabsManager.getCurrentTab(); + final LightningView currentTab = mTabsManager.getCurrentTab(); if (currentTab != null) { if (currentTab.getProgress() < 100) { currentTab.stopLoading(); @@ -1842,7 +1864,7 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements */ @Override public void onClick(View v) { - final LightningView currentTab = tabsManager.getCurrentTab(); + final LightningView currentTab = mTabsManager.getCurrentTab(); if (currentTab == null) { return; } @@ -1927,7 +1949,7 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements super.onReceive(context, intent); boolean isConnected = isConnected(context); Log.d(Constants.TAG, "Network Connected: " + String.valueOf(isConnected)); - tabsManager.notifyConnectionStatus(isConnected); + mTabsManager.notifyConnectionStatus(isConnected); } }; @@ -1992,7 +2014,7 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements */ @Subscribe public void bookmarkCurrentPage(final BookmarkEvents.WantToBookmarkCurrentPage event) { - final LightningView currentTab = tabsManager.getCurrentTab(); + final LightningView currentTab = mTabsManager.getCurrentTab(); if (currentTab != null) { mEventBus.post(new BrowserEvents.AddBookmark(currentTab.getTitle(), currentTab.getUrl())); } @@ -2016,9 +2038,9 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements */ @Subscribe public void bookmarkChanged(final BookmarkEvents.BookmarkChanged event) { - final LightningView currentTab = tabsManager.getCurrentTab(); + final LightningView currentTab = mTabsManager.getCurrentTab(); if (currentTab != null && currentTab.getUrl().startsWith(Constants.FILE) - && currentTab.getUrl().endsWith(Constants.BOOKMARKS_FILENAME)) { + && currentTab.getUrl().endsWith(BookmarkPage.FILENAME)) { currentTab.loadBookmarkpage(); } if (currentTab != null) { @@ -2033,9 +2055,9 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements */ @Subscribe public void bookmarkDeleted(final BookmarkEvents.Deleted event) { - final LightningView currentTab = tabsManager.getCurrentTab(); + final LightningView currentTab = mTabsManager.getCurrentTab(); if (currentTab != null && currentTab.getUrl().startsWith(Constants.FILE) - && currentTab.getUrl().endsWith(Constants.BOOKMARKS_FILENAME)) { + && currentTab.getUrl().endsWith(BookmarkPage.FILENAME)) { currentTab.loadBookmarkpage(); } if (currentTab != null) { @@ -2103,12 +2125,12 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements */ @Subscribe public void goBack(final NavigationEvents.GoBack event) { - final LightningView currentTab = tabsManager.getCurrentTab(); + final LightningView currentTab = mTabsManager.getCurrentTab(); if (currentTab != null) { if (currentTab.canGoBack()) { currentTab.goBack(); } else { - deleteTab(tabsManager.positionOf(currentTab)); + deleteTab(mTabsManager.positionOf(currentTab)); } } } @@ -2120,7 +2142,7 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements */ @Subscribe public void goForward(final NavigationEvents.GoForward event) { - final LightningView currentTab = tabsManager.getCurrentTab(); + final LightningView currentTab = mTabsManager.getCurrentTab(); if (currentTab != null) { if (currentTab.canGoForward()) { currentTab.goForward(); @@ -2130,7 +2152,7 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements @Subscribe public void goHome(final NavigationEvents.GoHome event) { - final LightningView currentTab = tabsManager.getCurrentTab(); + final LightningView currentTab = mTabsManager.getCurrentTab(); if (currentTab != null) { currentTab.loadHomepage(); closeDrawers(); diff --git a/app/src/main/java/acr/browser/lightning/activity/TabsManager.java b/app/src/main/java/acr/browser/lightning/activity/TabsManager.java index 6b4910b..b4be5a3 100644 --- a/app/src/main/java/acr/browser/lightning/activity/TabsManager.java +++ b/app/src/main/java/acr/browser/lightning/activity/TabsManager.java @@ -2,8 +2,10 @@ package acr.browser.lightning.activity; import android.app.Activity; import android.content.Context; +import android.content.DialogInterface; import android.content.Intent; import android.support.annotation.Nullable; +import android.support.v7.app.AlertDialog; import android.util.Log; import android.webkit.WebView; @@ -13,6 +15,8 @@ import java.util.List; import javax.inject.Inject; import javax.inject.Singleton; +import acr.browser.lightning.R; +import acr.browser.lightning.constant.Constants; import acr.browser.lightning.preference.PreferenceManager; import acr.browser.lightning.utils.Utils; import acr.browser.lightning.view.LightningView; @@ -34,16 +38,15 @@ public class TabsManager { @Inject public TabsManager() {} - public void restoreTabsAndHandleIntent(Activity activity, Intent intent, boolean incognito) { + public synchronized void restoreTabsAndHandleIntent(final Activity activity, + final Intent intent, + final boolean incognito) { String url = null; if (intent != null) { url = intent.getDataString(); } mWebViewList.clear(); mCurrentTab = null; - if (url != null) { - newTab(activity, url, incognito); - } if (!incognito && mPreferenceManager.getRestoreLostTabsEnabled()) { final String mem = mPreferenceManager.getMemoryUrl(); mPreferenceManager.setMemoryUrl(""); @@ -54,10 +57,28 @@ public class TabsManager { } } } + if (url != null) { + if (url.startsWith(Constants.FILE)) { + final String urlToLoad = url; + AlertDialog.Builder builder = new AlertDialog.Builder(activity); + builder.setCancelable(true) + .setTitle(R.string.title_warning) + .setMessage(R.string.message_blocked_local) + .setNegativeButton(android.R.string.cancel, null) + .setPositiveButton(R.string.action_open, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + newTab(activity, urlToLoad, incognito); + } + }) + .show(); + } else { + newTab(activity, url, incognito); + } + } if (mWebViewList.size() == 0) { newTab(activity, null, incognito); } - // mCurrentTab = mWebViewList.get(0); } /** diff --git a/app/src/main/java/acr/browser/lightning/constant/BookmarkPage.java b/app/src/main/java/acr/browser/lightning/constant/BookmarkPage.java index 1355844..f1f2203 100644 --- a/app/src/main/java/acr/browser/lightning/constant/BookmarkPage.java +++ b/app/src/main/java/acr/browser/lightning/constant/BookmarkPage.java @@ -20,11 +20,16 @@ import acr.browser.lightning.utils.Utils; public final class BookmarkPage { + /** + * The bookmark page standard suffix + */ + public static final String FILENAME = "bookmarks.html"; + private static final String HEADING = "\n" + "\n" + "\n" + "\n" + - "\n" + + "\n" + "" + BrowserApp.getAppContext().getString(R.string.action_bookmarks) + "\n" + @@ -41,7 +46,7 @@ public final class BookmarkPage { "

\n" + ""; @@ -66,9 +71,9 @@ public final class BookmarkPage { final List list = manager.getBookmarksFromFolder(folder, true); final File bookmarkWebPage; if (folder == null || folder.isEmpty()) { - bookmarkWebPage = new File(FILES_DIR, Constants.BOOKMARKS_FILENAME); + bookmarkWebPage = new File(FILES_DIR, FILENAME); } else { - bookmarkWebPage = new File(FILES_DIR, folder + '-' + Constants.BOOKMARKS_FILENAME); + bookmarkWebPage = new File(FILES_DIR, folder + '-' + FILENAME); } final StringBuilder bookmarkBuilder = new StringBuilder(BookmarkPage.HEADING); @@ -77,7 +82,7 @@ public final class BookmarkPage { final HistoryItem item = list.get(n); bookmarkBuilder.append(BookmarkPage.PART1); if (item.isFolder()) { - final File folderPage = new File(FILES_DIR, item.getTitle() + '-' + Constants.BOOKMARKS_FILENAME); + final File folderPage = new File(FILES_DIR, item.getTitle() + '-' + FILENAME); bookmarkBuilder.append(Constants.FILE).append(folderPage); bookmarkBuilder.append(BookmarkPage.PART2); bookmarkBuilder.append(folderIconPath); diff --git a/app/src/main/java/acr/browser/lightning/constant/Constants.java b/app/src/main/java/acr/browser/lightning/constant/Constants.java index 33bc973..46feeec 100644 --- a/app/src/main/java/acr/browser/lightning/constant/Constants.java +++ b/app/src/main/java/acr/browser/lightning/constant/Constants.java @@ -43,11 +43,6 @@ public final class Constants { public static final int PROXY_I2P = 2; public static final int PROXY_MANUAL = 3; - /** - * The bookmark page standard suffix - */ - public static final String BOOKMARKS_FILENAME = "bookmarks.html"; - public static final String DEFAULT_ENCODING = "UTF-8"; public static final String[] TEXT_ENCODINGS = {"ISO-8859-1", "UTF-8", "GBK", "Big5", "ISO-2022-JP", "SHIFT_JS", "EUC-JP", "EUC-KR"}; diff --git a/app/src/main/java/acr/browser/lightning/constant/StartPage.java b/app/src/main/java/acr/browser/lightning/constant/StartPage.java index f640023..b13d426 100644 --- a/app/src/main/java/acr/browser/lightning/constant/StartPage.java +++ b/app/src/main/java/acr/browser/lightning/constant/StartPage.java @@ -16,7 +16,7 @@ import acr.browser.lightning.utils.Utils; public class StartPage { - private static final String FILENAME = "homepage.html"; + public static final String FILENAME = "homepage.html"; private static final String HEAD = "" + "" diff --git a/app/src/main/java/acr/browser/lightning/dialog/LightningDialogBuilder.java b/app/src/main/java/acr/browser/lightning/dialog/LightningDialogBuilder.java index 93682ba..02c3f8e 100644 --- a/app/src/main/java/acr/browser/lightning/dialog/LightningDialogBuilder.java +++ b/app/src/main/java/acr/browser/lightning/dialog/LightningDialogBuilder.java @@ -24,6 +24,7 @@ import acr.browser.lightning.R; import acr.browser.lightning.app.BrowserApp; import acr.browser.lightning.bus.BookmarkEvents; import acr.browser.lightning.bus.BrowserEvents; +import acr.browser.lightning.constant.BookmarkPage; import acr.browser.lightning.constant.Constants; import acr.browser.lightning.constant.HistoryPage; import acr.browser.lightning.database.BookmarkManager; @@ -60,11 +61,11 @@ public class LightningDialogBuilder { */ public void showLongPressedDialogForBookmarkUrl(final Context context, final String url) { final HistoryItem item; - if (url.startsWith(Constants.FILE) && url.endsWith(Constants.BOOKMARKS_FILENAME)) { + if (url.startsWith(Constants.FILE) && url.endsWith(BookmarkPage.FILENAME)) { // TODO hacky, make a better bookmark mechanism in the future final Uri uri = Uri.parse(url); final String filename = uri.getLastPathSegment(); - final String folderTitle = filename.substring(0, filename.length() - Constants.BOOKMARKS_FILENAME.length() - 1); + final String folderTitle = filename.substring(0, filename.length() - BookmarkPage.FILENAME.length() - 1); item = new HistoryItem(); item.setIsFolder(true); item.setTitle(folderTitle); diff --git a/app/src/main/java/acr/browser/lightning/fragment/BookmarksFragment.java b/app/src/main/java/acr/browser/lightning/fragment/BookmarksFragment.java index cde8686..d7584cb 100644 --- a/app/src/main/java/acr/browser/lightning/fragment/BookmarksFragment.java +++ b/app/src/main/java/acr/browser/lightning/fragment/BookmarksFragment.java @@ -49,6 +49,7 @@ import acr.browser.lightning.dialog.LightningDialogBuilder; import acr.browser.lightning.preference.PreferenceManager; import acr.browser.lightning.async.ImageDownloadTask; import acr.browser.lightning.utils.ThemeUtils; +import acr.browser.lightning.utils.UrlUtils; import acr.browser.lightning.view.LightningView; /** @@ -193,12 +194,14 @@ public class BookmarksFragment extends Fragment implements View.OnClickListener, @Subscribe public void addBookmark(final BrowserEvents.AddBookmark event) { final HistoryItem item = new HistoryItem(event.url, event.title); - if (mBookmarkManager.addBookmark(item)) { - mBookmarks.add(item); - Collections.sort(mBookmarks, new BookmarkManager.SortIgnoreCase()); - mBookmarkAdapter.notifyDataSetChanged(); - mEventBus.post(new BookmarkEvents.Added(item)); - updateBookmarkIndicator(event.url); + if (!UrlUtils.isSpecialUrl(item.getUrl())) { + if (mBookmarkManager.addBookmark(item)) { + mBookmarks.add(item); + Collections.sort(mBookmarks, new BookmarkManager.SortIgnoreCase()); + mBookmarkAdapter.notifyDataSetChanged(); + mEventBus.post(new BookmarkEvents.Added(item)); + updateBookmarkIndicator(event.url); + } } } diff --git a/app/src/main/java/acr/browser/lightning/fragment/GeneralSettingsFragment.java b/app/src/main/java/acr/browser/lightning/fragment/GeneralSettingsFragment.java index d3f6ac0..aa3b129 100644 --- a/app/src/main/java/acr/browser/lightning/fragment/GeneralSettingsFragment.java +++ b/app/src/main/java/acr/browser/lightning/fragment/GeneralSettingsFragment.java @@ -5,6 +5,7 @@ package acr.browser.lightning.fragment; import android.app.Activity; import android.content.DialogInterface; +import android.os.Build; import android.os.Bundle; import android.os.Environment; import android.preference.CheckBoxPreference; @@ -101,7 +102,7 @@ public class GeneralSettingsFragment extends LightningPreferenceFragment impleme proxy.setSummary(mProxyChoices[choice]); } - if (API >= 19) { + if (API >= Build.VERSION_CODES.KITKAT) { mPreferenceManager.setFlashSupport(0); } @@ -138,7 +139,7 @@ public class GeneralSettingsFragment extends LightningPreferenceFragment impleme boolean enableJSBool = mPreferenceManager.getJavaScriptEnabled(); cbAds.setEnabled(Constants.FULL_VERSION); - cbFlash.setEnabled(API < 19); + cbFlash.setEnabled(API < Build.VERSION_CODES.KITKAT); cbImages.setChecked(imagesBool); cbJsScript.setChecked(enableJSBool); @@ -343,7 +344,8 @@ public class GeneralSettingsFragment extends LightningPreferenceFragment impleme if (!mHomepage.startsWith("about:")) { getHome.setText(mHomepage); } else { - getHome.setText("http://www.google.com"); + String defaultUrl = "https://www.google.com"; + getHome.setText(defaultUrl); } homePicker.setView(getHome); homePicker.setPositiveButton(getResources().getString(R.string.action_ok), @@ -526,44 +528,41 @@ public class GeneralSettingsFragment extends LightningPreferenceFragment impleme @Override public boolean onPreferenceChange(Preference preference, Object newValue) { - // switch preferences + boolean checked = false; + if (newValue instanceof Boolean) { + checked = (Boolean) newValue; + } switch (preference.getKey()) { case SETTINGS_FLASH: - if (cbFlash.isChecked()) { - getFlashChoice(); - } else { - mPreferenceManager.setFlashSupport(0); - } - if (!Utils.isFlashInstalled(mActivity) && cbFlash.isChecked()) { + if (!Utils.isFlashInstalled(mActivity) && checked) { Utils.createInformativeDialog(mActivity, R.string.title_warning, R.string.dialog_adobe_not_installed); - cbFlash.setEnabled(false); mPreferenceManager.setFlashSupport(0); + return false; + } else { + if (checked) { + getFlashChoice(); + } else { + mPreferenceManager.setFlashSupport(0); + } } - cbFlash.setChecked((Boolean) newValue); return true; case SETTINGS_ADS: - mPreferenceManager.setAdBlockEnabled((Boolean) newValue); - cbAds.setChecked((Boolean) newValue); + mPreferenceManager.setAdBlockEnabled(checked); return true; case SETTINGS_IMAGES: - mPreferenceManager.setBlockImagesEnabled((Boolean) newValue); - cbImages.setChecked((Boolean) newValue); + mPreferenceManager.setBlockImagesEnabled(checked); return true; case SETTINGS_JAVASCRIPT: - mPreferenceManager.setJavaScriptEnabled((Boolean) newValue); - cbJsScript.setChecked((Boolean) newValue); + mPreferenceManager.setJavaScriptEnabled(checked); return true; case SETTINGS_COLORMODE: - mPreferenceManager.setColorModeEnabled((Boolean) newValue); - cbColorMode.setChecked((Boolean) newValue); + mPreferenceManager.setColorModeEnabled(checked); return true; case SETTINGS_GOOGLESUGGESTIONS: - mPreferenceManager.setGoogleSearchSuggestionsEnabled((Boolean) newValue); - cbgooglesuggest.setChecked((Boolean) newValue); + mPreferenceManager.setGoogleSearchSuggestionsEnabled(checked); return true; case SETTINGS_DRAWERTABS: - mPreferenceManager.setShowTabsInDrawer((Boolean) newValue); - cbDrawerTabs.setChecked((Boolean) newValue); + mPreferenceManager.setShowTabsInDrawer(checked); default: return false; } diff --git a/app/src/main/java/acr/browser/lightning/fragment/PrivacySettingsFragment.java b/app/src/main/java/acr/browser/lightning/fragment/PrivacySettingsFragment.java index 2ea48aa..4b76aa9 100644 --- a/app/src/main/java/acr/browser/lightning/fragment/PrivacySettingsFragment.java +++ b/app/src/main/java/acr/browser/lightning/fragment/PrivacySettingsFragment.java @@ -17,6 +17,7 @@ import android.webkit.WebView; import acr.browser.lightning.R; import acr.browser.lightning.utils.Utils; import acr.browser.lightning.utils.WebUtils; +import acr.browser.lightning.view.LightningView; public class PrivacySettingsFragment extends LightningPreferenceFragment implements Preference.OnPreferenceClickListener, Preference.OnPreferenceChangeListener { @@ -31,10 +32,10 @@ public class PrivacySettingsFragment extends LightningPreferenceFragment impleme private static final String SETTINGS_CLEARCOOKIES = "clear_cookies"; private static final String SETTINGS_CLEARWEBSTORAGE = "clear_webstorage"; private static final String SETTINGS_WEBSTORAGEEXIT = "clear_webstorage_exit"; + private static final String SETTINGS_DONOTTRACK = "do_not_track"; + private static final String SETTINGS_IDENTIFYINGHEADERS = "remove_identifying_headers"; private Activity mActivity; - private CheckBoxPreference cblocation, cb3cookies, cbsavepasswords, cbcacheexit, cbhistoryexit, - cbcookiesexit, cbwebstorageexit; private Handler messageHandler; @Override @@ -54,13 +55,15 @@ public class PrivacySettingsFragment extends LightningPreferenceFragment impleme Preference clearcookies = findPreference(SETTINGS_CLEARCOOKIES); Preference clearwebstorage = findPreference(SETTINGS_CLEARWEBSTORAGE); - cblocation = (CheckBoxPreference) findPreference(SETTINGS_LOCATION); - cb3cookies = (CheckBoxPreference) findPreference(SETTINGS_THIRDPCOOKIES); - cbsavepasswords = (CheckBoxPreference) findPreference(SETTINGS_SAVEPASSWORD); - cbcacheexit = (CheckBoxPreference) findPreference(SETTINGS_CACHEEXIT); - cbhistoryexit = (CheckBoxPreference) findPreference(SETTINGS_HISTORYEXIT); - cbcookiesexit = (CheckBoxPreference) findPreference(SETTINGS_COOKIEEXIT); - cbwebstorageexit = (CheckBoxPreference) findPreference(SETTINGS_WEBSTORAGEEXIT); + CheckBoxPreference cblocation = (CheckBoxPreference) findPreference(SETTINGS_LOCATION); + CheckBoxPreference cb3cookies = (CheckBoxPreference) findPreference(SETTINGS_THIRDPCOOKIES); + CheckBoxPreference cbsavepasswords = (CheckBoxPreference) findPreference(SETTINGS_SAVEPASSWORD); + CheckBoxPreference cbcacheexit = (CheckBoxPreference) findPreference(SETTINGS_CACHEEXIT); + CheckBoxPreference cbhistoryexit = (CheckBoxPreference) findPreference(SETTINGS_HISTORYEXIT); + CheckBoxPreference cbcookiesexit = (CheckBoxPreference) findPreference(SETTINGS_COOKIEEXIT); + CheckBoxPreference cbwebstorageexit = (CheckBoxPreference) findPreference(SETTINGS_WEBSTORAGEEXIT); + CheckBoxPreference cbDoNotTrack = (CheckBoxPreference) findPreference(SETTINGS_DONOTTRACK); + CheckBoxPreference cbIdentifyingHeaders = (CheckBoxPreference) findPreference(SETTINGS_IDENTIFYINGHEADERS); clearcache.setOnPreferenceClickListener(this); clearhistory.setOnPreferenceClickListener(this); @@ -74,6 +77,8 @@ public class PrivacySettingsFragment extends LightningPreferenceFragment impleme cbhistoryexit.setOnPreferenceChangeListener(this); cbcookiesexit.setOnPreferenceChangeListener(this); cbwebstorageexit.setOnPreferenceChangeListener(this); + cbDoNotTrack.setOnPreferenceChangeListener(this); + cbIdentifyingHeaders.setOnPreferenceChangeListener(this); cblocation.setChecked(mPreferenceManager.getLocationEnabled()); cbsavepasswords.setChecked(mPreferenceManager.getSavePasswordsEnabled()); @@ -82,6 +87,11 @@ public class PrivacySettingsFragment extends LightningPreferenceFragment impleme cbcookiesexit.setChecked(mPreferenceManager.getClearCookiesExitEnabled()); cb3cookies.setChecked(mPreferenceManager.getBlockThirdPartyCookiesEnabled()); cbwebstorageexit.setChecked(mPreferenceManager.getClearWebStorageExitEnabled()); + cbDoNotTrack.setChecked(mPreferenceManager.getDoNotTrackEnabled()); + cbIdentifyingHeaders.setChecked(mPreferenceManager.getRemoveIdentifyingHeadersEnabled()); + + String identifyingHeadersSummary = LightningView.HEADER_REQUESTED_WITH + ", " + LightningView.HEADER_WAP_PROFILE; + cbIdentifyingHeaders.setSummary(identifyingHeadersSummary); cb3cookies.setEnabled(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP); @@ -194,35 +204,33 @@ public class PrivacySettingsFragment extends LightningPreferenceFragment impleme @Override public boolean onPreferenceChange(Preference preference, Object newValue) { - // switch preferences switch (preference.getKey()) { case SETTINGS_LOCATION: mPreferenceManager.setLocationEnabled((Boolean) newValue); - cblocation.setChecked((Boolean) newValue); return true; case SETTINGS_THIRDPCOOKIES: mPreferenceManager.setBlockThirdPartyCookiesEnabled((Boolean) newValue); - cb3cookies.setChecked((Boolean) newValue); return true; case SETTINGS_SAVEPASSWORD: mPreferenceManager.setSavePasswordsEnabled((Boolean) newValue); - cbsavepasswords.setChecked((Boolean) newValue); return true; case SETTINGS_CACHEEXIT: mPreferenceManager.setClearCacheExit((Boolean) newValue); - cbcacheexit.setChecked((Boolean) newValue); return true; case SETTINGS_HISTORYEXIT: mPreferenceManager.setClearHistoryExitEnabled((Boolean) newValue); - cbhistoryexit.setChecked((Boolean) newValue); return true; case SETTINGS_COOKIEEXIT: mPreferenceManager.setClearCookiesExitEnabled((Boolean) newValue); - cbcookiesexit.setChecked((Boolean) newValue); return true; case SETTINGS_WEBSTORAGEEXIT: mPreferenceManager.setClearWebStorageExitEnabled((Boolean) newValue); - cbwebstorageexit.setChecked((Boolean) newValue); + return true; + case SETTINGS_DONOTTRACK: + mPreferenceManager.setDoNotTrackEnabled((Boolean) newValue); + return true; + case SETTINGS_IDENTIFYINGHEADERS: + mPreferenceManager.setRemoveIdentifyingHeadersEnabled((Boolean) newValue); return true; default: return false; diff --git a/app/src/main/java/acr/browser/lightning/object/SearchAdapter.java b/app/src/main/java/acr/browser/lightning/object/SearchAdapter.java index c79baee..e3f1fff 100644 --- a/app/src/main/java/acr/browser/lightning/object/SearchAdapter.java +++ b/app/src/main/java/acr/browser/lightning/object/SearchAdapter.java @@ -63,6 +63,7 @@ public class SearchAdapter extends BaseAdapter implements Filterable { private final boolean mIncognito; private static final String CACHE_FILE_TYPE = ".sgg"; private static final String ENCODING = "ISO-8859-1"; + private static final String DEFAULT_LANGUAGE = "en"; private static final long INTERVAL_DAY = 86400000; private static final int MAX_SUGGESTIONS = 5; private static final SuggestionsComparator mComparator = new SuggestionsComparator(); @@ -374,9 +375,13 @@ public class SearchAdapter extends BaseAdapter implements Filterable { } InputStream in = null; FileOutputStream fos = null; + String language = Locale.getDefault().getLanguage(); + if (language.isEmpty()) { + language = DEFAULT_LANGUAGE; + } try { - URL url = new URL("http://google.com/complete/search?q=" + query - + "&output=toolbar&hl=en"); + URL url = new URL("https://google.com/complete/search?q=" + query + + "&output=toolbar&hl=" + language); HttpURLConnection connection = (HttpURLConnection) url.openConnection(); connection.setDoInput(true); connection.connect(); diff --git a/app/src/main/java/acr/browser/lightning/preference/PreferenceManager.java b/app/src/main/java/acr/browser/lightning/preference/PreferenceManager.java index 401a670..d948e42 100644 --- a/app/src/main/java/acr/browser/lightning/preference/PreferenceManager.java +++ b/app/src/main/java/acr/browser/lightning/preference/PreferenceManager.java @@ -51,6 +51,8 @@ public class PreferenceManager { public static final String TEXT_ENCODING = "textEncoding"; public static final String CLEAR_WEBSTORAGE_EXIT = "clearWebStorageExit"; public static final String SHOW_TABS_IN_DRAWER = "showTabsInDrawer"; + public static final String DO_NOT_TRACK = "doNotTrack"; + public static final String IDENTIFYING_HEADERS = "removeIdentifyingHeaders"; public static final String USE_PROXY = "useProxy"; public static final String PROXY_CHOICE = "proxyChoice"; @@ -245,6 +247,14 @@ public class PreferenceManager { return mPrefs.getBoolean(Name.SHOW_TABS_IN_DRAWER, defaultValue); } + public boolean getDoNotTrackEnabled() { + return mPrefs.getBoolean(Name.DO_NOT_TRACK, false); + } + + public boolean getRemoveIdentifyingHeadersEnabled(){ + return mPrefs.getBoolean(Name.IDENTIFYING_HEADERS, false); + } + private void putBoolean(String name, boolean value) { mPrefs.edit().putBoolean(name, value).apply(); } @@ -257,6 +267,14 @@ public class PreferenceManager { mPrefs.edit().putString(name, value).apply(); } + public void setRemoveIdentifyingHeadersEnabled(boolean enabled){ + putBoolean(Name.IDENTIFYING_HEADERS, enabled); + } + + public void setDoNotTrackEnabled(boolean doNotTrack) { + putBoolean(Name.DO_NOT_TRACK, doNotTrack); + } + public void setShowTabsInDrawer(boolean show) { putBoolean(Name.SHOW_TABS_IN_DRAWER, show); } diff --git a/app/src/main/java/acr/browser/lightning/reading/HtmlFetcher.java b/app/src/main/java/acr/browser/lightning/reading/HtmlFetcher.java index 3c58342..c6d7a8b 100644 --- a/app/src/main/java/acr/browser/lightning/reading/HtmlFetcher.java +++ b/app/src/main/java/acr/browser/lightning/reading/HtmlFetcher.java @@ -394,8 +394,8 @@ public class HtmlFetcher { if (responseCode / 100 == 3 && newUrl != null && num_redirects < 5) { newUrl = SPACE.matcher(newUrl).replaceAll("+"); // some services use (none-standard) utf8 in their location header - if (urlAsString.startsWith("http://bit.ly") - || urlAsString.startsWith("http://is.gd")) + if (urlAsString.contains("://bit.ly") + || urlAsString.contains("://is.gd")) newUrl = encodeUriFromHeader(newUrl); // AP: This code is not longer need, instead we always follow diff --git a/app/src/main/java/acr/browser/lightning/reading/SHelper.java b/app/src/main/java/acr/browser/lightning/reading/SHelper.java index 7293f3a..1554ed7 100644 --- a/app/src/main/java/acr/browser/lightning/reading/SHelper.java +++ b/app/src/main/java/acr/browser/lightning/reading/SHelper.java @@ -251,8 +251,8 @@ class SHelper { } public static String getUrlFromUglyGoogleRedirect(String url) { - if (url.startsWith("http://www.google.com/url?")) { - url = url.substring("http://www.google.com/url?".length()); + if (url.startsWith("https://www.google.com/url?")) { + url = url.substring("https://www.google.com/url?".length()); String arr[] = urlDecode(url).split("&"); for (String str : arr) { if (str.startsWith("q=")) @@ -264,8 +264,8 @@ class SHelper { } public static String getUrlFromUglyFacebookRedirect(String url) { - if (url.startsWith("http://www.facebook.com/l.php?u=")) { - url = url.substring("http://www.facebook.com/l.php?u=".length()); + if (url.startsWith("https://www.facebook.com/l.php?u=")) { + url = url.substring("https://www.facebook.com/l.php?u=".length()); return urlDecode(url); } diff --git a/app/src/main/java/acr/browser/lightning/utils/UrlUtils.java b/app/src/main/java/acr/browser/lightning/utils/UrlUtils.java index 1e02907..06b5c7c 100644 --- a/app/src/main/java/acr/browser/lightning/utils/UrlUtils.java +++ b/app/src/main/java/acr/browser/lightning/utils/UrlUtils.java @@ -21,6 +21,11 @@ import android.webkit.URLUtil; import java.util.regex.Matcher; import java.util.regex.Pattern; +import acr.browser.lightning.constant.BookmarkPage; +import acr.browser.lightning.constant.Constants; +import acr.browser.lightning.constant.HistoryPage; +import acr.browser.lightning.constant.StartPage; + /** * Utility methods for Url manipulation */ @@ -145,4 +150,14 @@ public class UrlUtils { } return inUrl; } + + /** + * Returns whether the given url is the bookmarks/history page or a normal website + */ + public static boolean isSpecialUrl(String url) { + return url != null && url.startsWith(Constants.FILE) && + (url.endsWith(BookmarkPage.FILENAME) || + url.endsWith(HistoryPage.FILENAME) || + url.endsWith(StartPage.FILENAME)); + } } \ No newline at end of file diff --git a/app/src/main/java/acr/browser/lightning/utils/Utils.java b/app/src/main/java/acr/browser/lightning/utils/Utils.java index 43bd90a..7681877 100644 --- a/app/src/main/java/acr/browser/lightning/utils/Utils.java +++ b/app/src/main/java/acr/browser/lightning/utils/Utils.java @@ -12,6 +12,7 @@ import android.content.Intent; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.content.res.Resources; +import android.database.Cursor; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Color; @@ -29,6 +30,9 @@ import android.util.Log; import android.view.View; import android.webkit.URLUtil; +import com.anthonycr.grant.PermissionsManager; +import com.anthonycr.grant.PermissionsResultAction; + import java.io.Closeable; import java.io.File; import java.io.IOException; @@ -40,8 +44,6 @@ import java.util.Date; import acr.browser.lightning.R; import acr.browser.lightning.constant.Constants; import acr.browser.lightning.download.DownloadHandler; -import com.anthonycr.grant.PermissionsManager; -import com.anthonycr.grant.PermissionsResultAction; public final class Utils { @@ -274,6 +276,24 @@ public final class Utils { } } + /** + * Utility method to close cursors. Cursor did not + * implement Closeable until API 16, so using this + * method for when we want to close a cursor. + * + * @param cursor the cursor to close + */ + public static void close(Cursor cursor) { + if (cursor == null) { + return; + } + try { + cursor.close(); + } catch (Exception e) { + e.printStackTrace(); + } + } + /** * Draws the trapezoid background for the horizontal tabs on a canvas object using * the specified color. diff --git a/app/src/main/java/acr/browser/lightning/view/LightningView.java b/app/src/main/java/acr/browser/lightning/view/LightningView.java index 3df86b3..ff80b8b 100644 --- a/app/src/main/java/acr/browser/lightning/view/LightningView.java +++ b/app/src/main/java/acr/browser/lightning/view/LightningView.java @@ -18,6 +18,7 @@ import android.os.Handler; import android.os.Message; import android.support.annotation.NonNull; import android.support.annotation.Nullable; +import android.support.v4.util.ArrayMap; import android.util.Log; import android.view.GestureDetector; import android.view.GestureDetector.SimpleOnGestureListener; @@ -37,12 +38,14 @@ import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.lang.ref.WeakReference; +import java.util.Map; import javax.inject.Inject; import acr.browser.lightning.R; import acr.browser.lightning.app.BrowserApp; import acr.browser.lightning.bus.BrowserEvents; +import acr.browser.lightning.constant.BookmarkPage; import acr.browser.lightning.constant.Constants; import acr.browser.lightning.constant.HistoryPage; import acr.browser.lightning.constant.StartPage; @@ -52,10 +55,15 @@ import acr.browser.lightning.download.LightningDownloadListener; import acr.browser.lightning.preference.PreferenceManager; import acr.browser.lightning.utils.ProxyUtils; import acr.browser.lightning.utils.ThemeUtils; +import acr.browser.lightning.utils.UrlUtils; import acr.browser.lightning.utils.Utils; public class LightningView { + public static final String HEADER_REQUESTED_WITH = "X-Requested-With"; + public static final String HEADER_WAP_PROFILE = "X-Wap-Profile"; + public static final String HEADER_DNT = "DNT"; + final LightningViewTitle mTitle; private WebView mWebView; final boolean mIsIncognitoTab; @@ -78,6 +86,7 @@ public class LightningView { 0, 0, 0, 1.0f, 0 // alpha }; private final WebViewHandler mWebViewHandler = new WebViewHandler(this); + private final Map mRequestHeaders = new ArrayMap<>(); @Inject Bus mEventBus; @@ -126,7 +135,7 @@ public class LightningView { if (url != null) { if (!url.trim().isEmpty()) { - mWebView.loadUrl(url); + mWebView.loadUrl(url, mRequestHeaders); } else { // don't load anything, the user is looking for a blank tab } @@ -140,11 +149,11 @@ public class LightningView { return; } if (mHomepage.startsWith("about:home")) { - mWebView.loadUrl(StartPage.getHomepage(mActivity)); + mWebView.loadUrl(StartPage.getHomepage(mActivity), mRequestHeaders); } else if (mHomepage.startsWith("about:bookmarks")) { loadBookmarkpage(); } else { - mWebView.loadUrl(mHomepage); + mWebView.loadUrl(mHomepage, mRequestHeaders); } } @@ -166,10 +175,10 @@ public class LightningView { } finally { Utils.close(outputStream); } - File bookmarkWebPage = new File(mActivity.getFilesDir(), Constants.BOOKMARKS_FILENAME); + File bookmarkWebPage = new File(mActivity.getFilesDir(), BookmarkPage.FILENAME); BrowserApp.getAppComponent().getBookmarkPage().buildBookmarkPage(null); - mWebView.loadUrl(Constants.FILE + bookmarkWebPage); + mWebView.loadUrl(Constants.FILE + bookmarkWebPage, mRequestHeaders); } @@ -180,7 +189,7 @@ public class LightningView { * if you don't have a reference to them * @param context the context in which the WebView was created */ - @SuppressLint("NewApi") + @SuppressLint({"NewApi", "SetJavaScriptEnabled"}) public synchronized void initializePreferences(@Nullable WebSettings settings, Context context) { if (settings == null && mWebView == null) { return; @@ -188,6 +197,20 @@ public class LightningView { settings = mWebView.getSettings(); } + if (mPreferences.getDoNotTrackEnabled()) { + mRequestHeaders.put(HEADER_DNT, "1"); + } else { + mRequestHeaders.remove(HEADER_DNT); + } + + if (mPreferences.getRemoveIdentifyingHeadersEnabled()) { + mRequestHeaders.put(HEADER_REQUESTED_WITH, ""); + mRequestHeaders.put(HEADER_WAP_PROFILE, ""); + } else { + mRequestHeaders.remove(HEADER_REQUESTED_WITH); + mRequestHeaders.remove(HEADER_WAP_PROFILE); + } + settings.setDefaultTextEncodingName(mPreferences.getTextEncoding()); mHomepage = mPreferences.getHomepage(); setColorMode(mPreferences.getRenderingMode()); @@ -382,6 +405,11 @@ public class LightningView { } } + @NonNull + protected Map getRequestHeaders() { + return mRequestHeaders; + } + public boolean isShown() { return mWebView != null && mWebView.isShown(); } @@ -615,7 +643,7 @@ public class LightningView { private void longClickPage(final String url) { final WebView.HitTestResult result = mWebView.getHitTestResult(); String currentUrl = mWebView.getUrl(); - if (currentUrl != null && currentUrl.startsWith(Constants.FILE)) { + if (currentUrl != null && UrlUtils.isSpecialUrl(currentUrl)) { if (currentUrl.endsWith(HistoryPage.FILENAME)) { if (url != null) { mBookmarksDialogBuilder.showLongPressedHistoryLinkDialog(mActivity, url); @@ -623,7 +651,7 @@ public class LightningView { final String newUrl = result.getExtra(); mBookmarksDialogBuilder.showLongPressedHistoryLinkDialog(mActivity, newUrl); } - } else if (currentUrl.endsWith(Constants.BOOKMARKS_FILENAME)) { + } else if (currentUrl.endsWith(BookmarkPage.FILENAME)) { if (url != null) { mBookmarksDialogBuilder.showLongPressedDialogForBookmarkUrl(mActivity, url); } else if (result != null && result.getExtra() != null) { @@ -677,7 +705,7 @@ public class LightningView { } if (mWebView != null) { - mWebView.loadUrl(url); + mWebView.loadUrl(url, mRequestHeaders); } } @@ -782,7 +810,7 @@ public class LightningView { private static class WebViewHandler extends Handler { - private WeakReference mReference; + private final WeakReference mReference; public WebViewHandler(LightningView view) { mReference = new WeakReference<>(view); diff --git a/app/src/main/java/acr/browser/lightning/view/LightningWebClient.java b/app/src/main/java/acr/browser/lightning/view/LightningWebClient.java index fec911b..5e48f16 100644 --- a/app/src/main/java/acr/browser/lightning/view/LightningWebClient.java +++ b/app/src/main/java/acr/browser/lightning/view/LightningWebClient.java @@ -30,6 +30,7 @@ import java.io.ByteArrayInputStream; import java.net.URISyntaxException; import java.util.ArrayList; import java.util.List; +import java.util.Map; import acr.browser.lightning.R; import acr.browser.lightning.app.BrowserApp; @@ -41,12 +42,9 @@ import acr.browser.lightning.utils.IntentUtils; import acr.browser.lightning.utils.ProxyUtils; import acr.browser.lightning.utils.Utils; -/** - * @author Stefano Pacifici based on Anthony C. Restaino's code - * @date 2015/09/22 - */ class LightningWebClient extends WebViewClient { + private final Activity mActivity; private final LightningView mLightningView; private final UIController mUIController; @@ -152,7 +150,6 @@ class LightningWebClient extends WebViewClient { @Override public void onClick(DialogInterface dialog, int id) { handler.cancel(); - } }); AlertDialog alert = builder.create(); @@ -275,13 +272,17 @@ class LightningWebClient extends WebViewClient { return true; } + Map headers = mLightningView.getRequestHeaders(); + if (mLightningView.mIsIncognitoTab) { - return super.shouldOverrideUrlLoading(view, url); + view.loadUrl(url, headers); + return true; } if (url.startsWith("about:")) { - return super.shouldOverrideUrlLoading(view, url); + view.loadUrl(url, headers); + return true; } - if (url.contains("mailto:")) { + if (url.startsWith("mailto:")) { MailTo mailTo = MailTo.parse(url); Intent i = Utils.newEmailIntent(mailTo.getTo(), mailTo.getSubject(), mailTo.getBody(), mailTo.getCc()); @@ -292,8 +293,8 @@ class LightningWebClient extends WebViewClient { Intent intent; try { intent = Intent.parseUri(url, Intent.URI_INTENT_SCHEME); - } catch (URISyntaxException ex) { - return false; + } catch (URISyntaxException ignored) { + intent = null; } if (intent != null) { intent.addCategory(Intent.CATEGORY_BROWSABLE); @@ -309,6 +310,10 @@ class LightningWebClient extends WebViewClient { return true; } } - return mIntentUtils.startActivityForUrl(view, url); + + if (!mIntentUtils.startActivityForUrl(view, url)) { + view.loadUrl(url, headers); + } + return true; } } diff --git a/app/src/main/res/values-sr/strings.xml b/app/src/main/res/values-sr/strings.xml index f397970..4d624c7 100644 --- a/app/src/main/res/values-sr/strings.xml +++ b/app/src/main/res/values-sr/strings.xml @@ -1,10 +1,13 @@ - + Муња Нови језичак @@ -57,6 +60,7 @@ Отвори Шта желите да урадите са овом везом? Подели ову страницу + Шта желите да урадите са овом ставком историјата? Шта желите да урадите са овим обележивачем? Обриши Празна страница @@ -97,7 +101,9 @@ Назад Нађи на страници Покрећем преузимање\u2026 - Преузимање је могуће само са „http“ или „https“ адреса. + Могу да преузмем само са „http“ или „https“ адреса. + Неисправан УРЛ, не могу да преузмем + Не могу да преузмем у наведену локацију Нема СД картице УСБ складиште је потребно за преузимање фајла. УСБ складиште није доступно @@ -121,6 +127,13 @@ Лиценце отвореног кôда Тражи Блокирај рекламе + Веза са овим сајтом није безбедна:\n%1$s\nДа наставим свеједно? + датум сертификата је неважећи + сертификат је истекао + домен на сертификату се не поклапа са доменом сајта + сертификат је неважећи + сертификат још није важећи + сертификат није поуздан Поновно слање формулара Желите ли да поново пошаљете податке? \nЖелите ли да користите вашу локацију @@ -131,8 +144,21 @@ Лозинка Предлози претраге Погоњено Гуглом + ХТТП прокси + + Ништа + Орбот + I2P + Ручно + + Ручне поставке проксија + Домаћин: + Порт: Изгледа да имате Орбот инсталиран. Желите ли да користите Тор? + Изгледа да имате I2P инсталиран. Желите ли да користите I2P? Инсталирајте Орбот да бисте користили Тор. + I2P није покренут. + I2P тунели још нису спремни. Да Не Очисти колачиће по затварању @@ -169,13 +195,14 @@ Затвори све језичке Блокирај колачиће треће стране Режим боје - Режим исцртавања + Режим за читање Учитавам… Нисам могао ништа да учитам са странице. Snacktory jsoup: Јава ХТМЛ рашчлањивач МИТ лиценца Садржај УРЛ бокса + Кодирање текста Домен (подраз.) УРЛ @@ -183,5 +210,19 @@ Обрнута боја Језичци - Тамна тема + Тема + Светла + Тамна + Црна (АМОЛЕД) + Назив фасцикле + Фасцикла + Преименуј + Преименуј фасциклу + Шта желите да урадите са овом фасциклом? + Очисти веб складиште + Очисти веб складиште по затварању + Веб складиште је очишћено + Извор hosts фајла за блокирање реклама + Поставке Адблока + Језичци у фиоци навигације diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 35cff5a..e33b2b4 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -225,4 +225,6 @@ Hosts File Ad Blocking Source Ad Block Settings Show tabs in Navigation Drawer + Request \'Do Not Track\' + Remove Identifying Headers diff --git a/app/src/main/res/xml/preference_privacy.xml b/app/src/main/res/xml/preference_privacy.xml index cb95f5d..b0a5e4a 100644 --- a/app/src/main/res/xml/preference_privacy.xml +++ b/app/src/main/res/xml/preference_privacy.xml @@ -5,43 +5,51 @@ + android:title="@string/location"/> + android:title="@string/third_party"/> + android:title="@string/password"/> + + + android:title="@string/cache"/> + android:title="@string/clear_history_exit"/> + android:title="@string/clear_cookies_exit"/> + android:title="@string/clear_web_storage_exit"/> + android:title="@string/clear_cache"/> + android:title="@string/clear_history"/> + android:title="@string/clear_cookies"/> + android:title="@string/clear_web_storage"/> \ No newline at end of file