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 4d69b5c..5b7b602 100644 --- a/app/src/main/java/acr/browser/lightning/activity/BrowserActivity.java +++ b/app/src/main/java/acr/browser/lightning/activity/BrowserActivity.java @@ -194,7 +194,7 @@ public abstract class BrowserActivity extends ThemableActivity implements Browse private static final FrameLayout.LayoutParams COVER_SCREEN_PARAMS = new FrameLayout.LayoutParams( LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT); - public abstract boolean isIncognito(); + abstract boolean isIncognito(); abstract void initializeTabs(); @@ -356,12 +356,13 @@ public abstract class BrowserActivity extends ThemableActivity implements Browse mDrawerLayout.setDrawerShadow(R.drawable.drawer_right_shadow, GravityCompat.END); mDrawerLayout.setDrawerShadow(R.drawable.drawer_left_shadow, GravityCompat.START); - initializeTabs(); if (API <= Build.VERSION_CODES.JELLY_BEAN_MR2) { WebIconDatabase.getInstance().open(getDir("icons", MODE_PRIVATE).getPath()); } + initializeTabs(); + mProxyUtils.checkForProxy(this); } @@ -1227,7 +1228,7 @@ public abstract class BrowserActivity extends ThemableActivity implements Browse return false; } mIsNewIntent = false; - LightningView startingTab = new LightningView(mActivity, url, mDarkTheme); + LightningView startingTab = new LightningView(mActivity, url, mDarkTheme, isIncognito()); if (mIdGenerator == 0) { startingTab.resumeTimers(); } @@ -1452,7 +1453,7 @@ public abstract class BrowserActivity extends ThemableActivity implements Browse initializePreferences(); for (int n = 0; n < mWebViewList.size(); n++) { if (mWebViewList.get(n) != null) { - mWebViewList.get(n).initializePreferences(this); + mWebViewList.get(n).initializePreferences(null, this); } else { mWebViewList.remove(n); } diff --git a/app/src/main/java/acr/browser/lightning/controller/BrowserController.java b/app/src/main/java/acr/browser/lightning/controller/BrowserController.java index b76a7b1..bfb166b 100644 --- a/app/src/main/java/acr/browser/lightning/controller/BrowserController.java +++ b/app/src/main/java/acr/browser/lightning/controller/BrowserController.java @@ -50,8 +50,6 @@ public interface BrowserController { void closeEmptyTab(); - boolean isIncognito(); - boolean proxyIsNotReady(); void updateBookmarkIndicator(String url); 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 ce9cd78..d9fcc72 100644 --- a/app/src/main/java/acr/browser/lightning/object/SearchAdapter.java +++ b/app/src/main/java/acr/browser/lightning/object/SearchAdapter.java @@ -51,6 +51,7 @@ public class SearchAdapter extends BaseAdapter implements Filterable { private final List mSuggestions = new ArrayList<>(); private final List mFilteredList = new ArrayList<>(); private final List mAllBookmarks = new ArrayList<>(); + private final Object mLock = new Object(); private HistoryDatabase mDatabaseHandler; private final Context mContext; private boolean mUseGoogle = true; @@ -58,6 +59,7 @@ public class SearchAdapter extends BaseAdapter implements Filterable { private final boolean mDarkTheme; private final boolean mIncognito; private final BookmarkManager mBookmarkManager; + private static final String CACHE_FILE_TYPE = ".sgg"; private static final String ENCODING = "ISO-8859-1"; private static final long INTERVAL_DAY = 86400000; private static final int MAX_SUGGESTIONS = 5; @@ -105,11 +107,9 @@ public class SearchAdapter extends BaseAdapter implements Filterable { private class NameFilter implements FilenameFilter { - private static final String ext = ".sgg"; - @Override public boolean accept(File dir, String filename) { - return filename.endsWith(ext); + return filename.endsWith(CACHE_FILE_TYPE); } } @@ -117,14 +117,18 @@ public class SearchAdapter extends BaseAdapter implements Filterable { public void refreshPreferences() { mUseGoogle = PreferenceManager.getInstance().getGoogleSearchSuggestionsEnabled(); if (!mUseGoogle) { - mSuggestions.clear(); + synchronized (mSuggestions) { + mSuggestions.clear(); + } } mDatabaseHandler = HistoryDatabase.getInstance(mContext.getApplicationContext()); } public void refreshBookmarks() { - mAllBookmarks.clear(); - mAllBookmarks.addAll(mBookmarkManager.getAllBookmarks(true)); + synchronized (mLock) { + mAllBookmarks.clear(); + mAllBookmarks.addAll(mBookmarkManager.getAllBookmarks(true)); + } } @Override @@ -217,27 +221,33 @@ public class SearchAdapter extends BaseAdapter implements Filterable { } int counter = 0; - mBookmarks.clear(); - for (int n = 0; n < mAllBookmarks.size(); n++) { - if (counter >= 5) { - break; - } - if (mAllBookmarks.get(n).getTitle().toLowerCase(Locale.getDefault()) - .startsWith(query)) { - mBookmarks.add(mAllBookmarks.get(n)); - counter++; - } else if (mAllBookmarks.get(n).getUrl().contains(query)) { - mBookmarks.add(mAllBookmarks.get(n)); - counter++; - } + synchronized (mBookmarks) { + mBookmarks.clear(); + synchronized (mLock) { + for (int n = 0; n < mAllBookmarks.size(); n++) { + if (counter >= 5) { + break; + } + if (mAllBookmarks.get(n).getTitle().toLowerCase(Locale.getDefault()) + .startsWith(query)) { + mBookmarks.add(mAllBookmarks.get(n)); + counter++; + } else if (mAllBookmarks.get(n).getUrl().contains(query)) { + mBookmarks.add(mAllBookmarks.get(n)); + counter++; + } + } + } } if (mDatabaseHandler == null || mDatabaseHandler.isClosed()) { mDatabaseHandler = HistoryDatabase.getInstance(mContext.getApplicationContext()); } List historyList = mDatabaseHandler.findItemsContaining(constraint.toString()); - mHistory.clear(); - mHistory.addAll(historyList); + synchronized (mHistory) { + mHistory.clear(); + mHistory.addAll(historyList); + } results.count = 1; return results; } @@ -249,10 +259,12 @@ public class SearchAdapter extends BaseAdapter implements Filterable { @Override protected void publishResults(CharSequence constraint, FilterResults results) { - mFilteredList.clear(); - List filtered = getFilteredList(); - Collections.sort(filtered, mComparator); - mFilteredList.addAll(filtered); + synchronized (mFilteredList) { + mFilteredList.clear(); + List filtered = getFilteredList(); + Collections.sort(filtered, mComparator); + mFilteredList.addAll(filtered); + } notifyDataSetChanged(); } @@ -320,20 +332,24 @@ public class SearchAdapter extends BaseAdapter implements Filterable { @Override protected void onPostExecute(List result) { - mSuggestions.clear(); - mSuggestions.addAll(result); - mFilteredList.clear(); - List filtered = getFilteredList(); - Collections.sort(filtered, mComparator); - mFilteredList.addAll(filtered); - notifyDataSetChanged(); + synchronized (mSuggestions) { + mSuggestions.clear(); + mSuggestions.addAll(result); + } + synchronized (mFilteredList) { + mFilteredList.clear(); + List filtered = getFilteredList(); + Collections.sort(filtered, mComparator); + mFilteredList.addAll(filtered); + notifyDataSetChanged(); + } mIsExecuting = false; } } private File downloadSuggestionsForQuery(String query) { - File cacheFile = new File(mContext.getCacheDir(), query.hashCode() + ".sgg"); + File cacheFile = new File(mContext.getCacheDir(), query.hashCode() + CACHE_FILE_TYPE); if (System.currentTimeMillis() - INTERVAL_DAY < cacheFile.lastModified()) { return cacheFile; } @@ -410,23 +426,28 @@ public class SearchAdapter extends BaseAdapter implements Filterable { private List getFilteredList() { List list = new ArrayList<>(); - Iterator bookmark = mBookmarks.iterator(); - Iterator history = mHistory.iterator(); - Iterator suggestion = mSuggestions.listIterator(); - while (list.size() < MAX_SUGGESTIONS) { - if (!bookmark.hasNext() && !suggestion.hasNext() && !history.hasNext()) { - return list; - } - if (bookmark.hasNext()) { - list.add(bookmark.next()); - } - if (suggestion.hasNext() && list.size() < MAX_SUGGESTIONS) { - list.add(suggestion.next()); - } - if (history.hasNext() && list.size() < MAX_SUGGESTIONS) { - list.add(history.next()); + synchronized (mBookmarks) { + synchronized (mHistory) { + synchronized (mSuggestions) { + Iterator bookmark = mBookmarks.iterator(); + Iterator history = mHistory.iterator(); + Iterator suggestion = mSuggestions.listIterator(); + while (list.size() < MAX_SUGGESTIONS) { + if (!bookmark.hasNext() && !suggestion.hasNext() && !history.hasNext()) { + return list; + } + if (bookmark.hasNext()) { + list.add(bookmark.next()); + } + if (suggestion.hasNext() && list.size() < MAX_SUGGESTIONS) { + list.add(suggestion.next()); + } + if (history.hasNext() && list.size() < MAX_SUGGESTIONS) { + list.add(history.next()); + } + } + } } - } return list; } 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 34e92fc..6a18532 100644 --- a/app/src/main/java/acr/browser/lightning/view/LightningView.java +++ b/app/src/main/java/acr/browser/lightning/view/LightningView.java @@ -69,10 +69,10 @@ public class LightningView { private final Title mTitle; private WebView mWebView; + private boolean mIsIncognitoTab; private BrowserController mBrowserController; private GestureDetector mGestureDetector; private final Activity mActivity; - private WebSettings mSettings; private static String mHomepage; private static String mDefaultUserAgent; private static Bitmap mWebpageBitmap; @@ -93,10 +93,11 @@ public class LightningView { 0, 0, 0, 1.0f, 0 // alpha }; - public LightningView(Activity activity, String url, boolean darkTheme) { + public LightningView(Activity activity, String url, boolean darkTheme, boolean isIncognito) { mActivity = activity; mWebView = new WebView(activity); + mIsIncognitoTab = isIncognito; mTitle = new Title(activity, darkTheme); mAdBlock = AdBlock.getInstance(activity.getApplicationContext()); @@ -134,9 +135,8 @@ public class LightningView { mGestureDetector = new GestureDetector(activity, new CustomGestureListener()); mWebView.setOnTouchListener(new TouchListener()); mDefaultUserAgent = mWebView.getSettings().getUserAgentString(); - mSettings = mWebView.getSettings(); initializeSettings(mWebView.getSettings(), activity); - initializePreferences(activity); + initializePreferences(mWebView.getSettings(), activity); if (url != null) { if (!url.trim().isEmpty()) { @@ -155,6 +155,12 @@ public class LightningView { } } + /** + * This method builds the homepage and returns the local URL to be loaded + * when it finishes building. + * + * @return the URL to load + */ private String getHomepage() { StringBuilder homepageBuilder = new StringBuilder(); homepageBuilder.append(StartPage.HEAD); @@ -252,35 +258,42 @@ public class LightningView { return Constants.FILE + homepage; } - public synchronized void initializePreferences(Context context) { + /** + * Initialize the preference driven settings of the WebView + * + * @param settings the WebSettings object to use, you can pass in null + * if you don't have a reference to them + * @param context the context in which the WebView was created + */ + public synchronized void initializePreferences(@Nullable WebSettings settings, Context context) { + if (settings == null && mWebView == null) { + return; + } else if (settings == null) { + settings = mWebView.getSettings(); + } mPreferences = PreferenceManager.getInstance(); - mSettings.setDefaultTextEncodingName(mPreferences.getTextEncoding()); + settings.setDefaultTextEncodingName(mPreferences.getTextEncoding()); mHomepage = mPreferences.getHomepage(); mAdBlock.updatePreference(); - if (mSettings == null && mWebView != null) { - mSettings = mWebView.getSettings(); - } else if (mSettings == null) { - return; - } setColorMode(mPreferences.getRenderingMode()); - if (!mBrowserController.isIncognito()) { - mSettings.setGeolocationEnabled(mPreferences.getLocationEnabled()); + if (!mIsIncognitoTab) { + settings.setGeolocationEnabled(mPreferences.getLocationEnabled()); } else { - mSettings.setGeolocationEnabled(false); + settings.setGeolocationEnabled(false); } if (API < 19) { switch (mPreferences.getFlashSupport()) { case 0: - mSettings.setPluginState(PluginState.OFF); + settings.setPluginState(PluginState.OFF); break; case 1: - mSettings.setPluginState(PluginState.ON_DEMAND); + settings.setPluginState(PluginState.ON_DEMAND); break; case 2: - mSettings.setPluginState(PluginState.ON); + settings.setPluginState(PluginState.ON); break; default: break; @@ -289,29 +302,29 @@ public class LightningView { setUserAgent(context, mPreferences.getUserAgentChoice()); - if (mPreferences.getSavePasswordsEnabled() && !mBrowserController.isIncognito()) { + if (mPreferences.getSavePasswordsEnabled() && !mIsIncognitoTab) { if (API < 18) { - mSettings.setSavePassword(true); + settings.setSavePassword(true); } - mSettings.setSaveFormData(true); + settings.setSaveFormData(true); } else { if (API < 18) { - mSettings.setSavePassword(false); + settings.setSavePassword(false); } - mSettings.setSaveFormData(false); + settings.setSaveFormData(false); } if (mPreferences.getJavaScriptEnabled()) { - mSettings.setJavaScriptEnabled(true); - mSettings.setJavaScriptCanOpenWindowsAutomatically(true); + settings.setJavaScriptEnabled(true); + settings.setJavaScriptCanOpenWindowsAutomatically(true); } if (mPreferences.getTextReflowEnabled()) { mTextReflow = true; - mSettings.setLayoutAlgorithm(LayoutAlgorithm.NARROW_COLUMNS); + settings.setLayoutAlgorithm(LayoutAlgorithm.NARROW_COLUMNS); if (API >= android.os.Build.VERSION_CODES.KITKAT) { try { - mSettings.setLayoutAlgorithm(LayoutAlgorithm.TEXT_AUTOSIZING); + settings.setLayoutAlgorithm(LayoutAlgorithm.TEXT_AUTOSIZING); } catch (Exception e) { // This shouldn't be necessary, but there are a number // of KitKat devices that crash trying to set this @@ -320,31 +333,35 @@ public class LightningView { } } else { mTextReflow = false; - mSettings.setLayoutAlgorithm(LayoutAlgorithm.NORMAL); + settings.setLayoutAlgorithm(LayoutAlgorithm.NORMAL); } - mSettings.setBlockNetworkImage(mPreferences.getBlockImagesEnabled()); - mSettings.setSupportMultipleWindows(mPreferences.getPopupsEnabled()); - mSettings.setUseWideViewPort(mPreferences.getUseWideViewportEnabled()); - mSettings.setLoadWithOverviewMode(mPreferences.getOverviewModeEnabled()); + settings.setBlockNetworkImage(mPreferences.getBlockImagesEnabled()); + if (!mIsIncognitoTab) { + settings.setSupportMultipleWindows(mPreferences.getPopupsEnabled()); + } else { + settings.setSupportMultipleWindows(false); + } + settings.setUseWideViewPort(mPreferences.getUseWideViewportEnabled()); + settings.setLoadWithOverviewMode(mPreferences.getOverviewModeEnabled()); switch (mPreferences.getTextSize()) { case 0: - mSettings.setTextZoom(200); + settings.setTextZoom(200); break; case 1: - mSettings.setTextZoom(150); + settings.setTextZoom(150); break; case 2: - mSettings.setTextZoom(125); + settings.setTextZoom(125); break; case 3: - mSettings.setTextZoom(100); + settings.setTextZoom(100); break; case 4: - mSettings.setTextZoom(75); + settings.setTextZoom(75); break; case 5: - mSettings.setTextZoom(50); + settings.setTextZoom(50); break; } if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { @@ -353,6 +370,13 @@ public class LightningView { } } + /** + * Initialize the settings of the WebView that are intrinsic to Lightning and cannot + * be altered by the user. Distinguish between Incognito and Regular tabs here. + * + * @param settings the WebSettings object to use. + * @param context the Context which was used to construct the WebView. + */ private void initializeSettings(WebSettings settings, Context context) { if (API < Build.VERSION_CODES.JELLY_BEAN_MR2) { settings.setAppCacheMaxSize(Long.MAX_VALUE); @@ -363,16 +387,23 @@ public class LightningView { if (API > Build.VERSION_CODES.JELLY_BEAN) { settings.setMediaPlaybackRequiresUserGesture(true); } - if (API >= Build.VERSION_CODES.LOLLIPOP && !mBrowserController.isIncognito()) { + if (API >= Build.VERSION_CODES.LOLLIPOP && !mIsIncognitoTab) { settings.setMixedContentMode(WebSettings.MIXED_CONTENT_COMPATIBILITY_MODE); } else if (API >= Build.VERSION_CODES.LOLLIPOP) { // We're in Incognito mode, reject settings.setMixedContentMode(WebSettings.MIXED_CONTENT_NEVER_ALLOW); } - settings.setDomStorageEnabled(true); - settings.setAppCacheEnabled(true); - settings.setCacheMode(WebSettings.LOAD_DEFAULT); - settings.setDatabaseEnabled(true); + if (!mIsIncognitoTab) { + settings.setDomStorageEnabled(true); + settings.setAppCacheEnabled(true); + settings.setCacheMode(WebSettings.LOAD_DEFAULT); + settings.setDatabaseEnabled(true); + } else { + settings.setDomStorageEnabled(false); + settings.setAppCacheEnabled(false); + settings.setDatabaseEnabled(false); + settings.setCacheMode(WebSettings.LOAD_NO_CACHE); + } settings.setSupportZoom(true); settings.setBuiltInZoomControls(true); settings.setDisplayZoomControls(false); @@ -401,22 +432,24 @@ public class LightningView { } public void setUserAgent(Context context, int choice) { + if (mWebView == null) return; + WebSettings settings = mWebView.getSettings(); switch (choice) { case 1: if (API > 16) { - mSettings.setUserAgentString(WebSettings.getDefaultUserAgent(context)); + settings.setUserAgentString(WebSettings.getDefaultUserAgent(context)); } else { - mSettings.setUserAgentString(mDefaultUserAgent); + settings.setUserAgentString(mDefaultUserAgent); } break; case 2: - mSettings.setUserAgentString(Constants.DESKTOP_USER_AGENT); + settings.setUserAgentString(Constants.DESKTOP_USER_AGENT); break; case 3: - mSettings.setUserAgentString(Constants.MOBILE_USER_AGENT); + settings.setUserAgentString(Constants.MOBILE_USER_AGENT); break; case 4: - mSettings.setUserAgentString(mPreferences.getUserAgentString(mDefaultUserAgent)); + settings.setUserAgentString(mPreferences.getUserAgentString(mDefaultUserAgent)); break; } } @@ -854,7 +887,7 @@ public class LightningView { return true; } - if (mBrowserController.isIncognito()) { + if (mIsIncognitoTab) { return super.shouldOverrideUrlLoading(view, url); } if (url.startsWith("about:")) {