Browse Source

Merge latest changes from Anthony's dev branch

master
Stefano Pacifici 9 years ago
parent
commit
3cb576d358
  1. 15
      app/build.gradle
  2. 174
      app/src/LightningLite/java/acr/browser/lightning/utils/ProxyUtils.java
  3. 1
      app/src/LightningPlus/java/acr/browser/lightning/utils/ProxyUtils.java
  4. 19
      app/src/main/AndroidManifest.xml
  5. 344
      app/src/main/java/acr/browser/lightning/activity/BrowserActivity.java
  6. 2
      app/src/main/java/acr/browser/lightning/activity/ThemableBrowserActivity.java
  7. 2
      app/src/main/java/acr/browser/lightning/app/BrowserApp.java
  8. 52
      app/src/main/java/acr/browser/lightning/async/AsyncExecutor.java
  9. 57
      app/src/main/java/acr/browser/lightning/async/ImageDownloadTask.java
  10. 14
      app/src/main/java/acr/browser/lightning/constant/BookmarkPage.java
  11. 4
      app/src/main/java/acr/browser/lightning/constant/Constants.java
  12. 8
      app/src/main/java/acr/browser/lightning/constant/StartPage.java
  13. 3
      app/src/main/java/acr/browser/lightning/controller/BrowserController.java
  14. 145
      app/src/main/java/acr/browser/lightning/database/BookmarkLocalSync.java
  15. 46
      app/src/main/java/acr/browser/lightning/database/BookmarkManager.java
  16. 18
      app/src/main/java/acr/browser/lightning/database/HistoryDatabase.java
  17. 74
      app/src/main/java/acr/browser/lightning/database/HistoryItem.java
  18. 4
      app/src/main/java/acr/browser/lightning/dialog/LightningDialogBuilder.java
  19. 140
      app/src/main/java/acr/browser/lightning/download/DownloadHandler.java
  20. 13
      app/src/main/java/acr/browser/lightning/download/FetchUrlMimeType.java
  21. 26
      app/src/main/java/acr/browser/lightning/download/WebAddress.java
  22. 60
      app/src/main/java/acr/browser/lightning/fragment/AdvancedSettingsFragment.java
  23. 62
      app/src/main/java/acr/browser/lightning/fragment/BookmarkSettingsFragment.java
  24. 93
      app/src/main/java/acr/browser/lightning/fragment/BookmarksFragment.java
  25. 76
      app/src/main/java/acr/browser/lightning/fragment/DisplaySettingsFragment.java
  26. 227
      app/src/main/java/acr/browser/lightning/fragment/GeneralSettingsFragment.java
  27. 2
      app/src/main/java/acr/browser/lightning/fragment/LightningPreferenceFragment.java
  28. 44
      app/src/main/java/acr/browser/lightning/fragment/PrivacySettingsFragment.java
  29. 69
      app/src/main/java/acr/browser/lightning/object/SearchAdapter.java
  30. 10
      app/src/main/java/acr/browser/lightning/preference/PreferenceManager.java
  31. 30
      app/src/main/java/acr/browser/lightning/reading/ArticleTextExtractor.java
  32. 22
      app/src/main/java/acr/browser/lightning/reading/Converter.java
  33. 33
      app/src/main/java/acr/browser/lightning/reading/HtmlFetcher.java
  34. 14
      app/src/main/java/acr/browser/lightning/reading/ImageResult.java
  35. 4
      app/src/main/java/acr/browser/lightning/reading/JResult.java
  36. 26
      app/src/main/java/acr/browser/lightning/reading/OutputFormatter.java
  37. 12
      app/src/main/java/acr/browser/lightning/reading/SHelper.java
  38. 5
      app/src/main/java/acr/browser/lightning/utils/AdBlock.java
  39. 6
      app/src/main/java/acr/browser/lightning/utils/IntentUtils.java
  40. 42
      app/src/main/java/acr/browser/lightning/utils/ThemeUtils.java
  41. 2
      app/src/main/java/acr/browser/lightning/utils/UrlUtils.java
  42. 13
      app/src/main/java/acr/browser/lightning/utils/Utils.java
  43. 4
      app/src/main/java/acr/browser/lightning/utils/WebUtils.java
  44. 44
      app/src/main/java/acr/browser/lightning/view/IconCacheTask.java
  45. 42
      app/src/main/java/acr/browser/lightning/view/LightningView.java
  46. 3
      app/src/main/res/layout/two_line_autocomplete.xml
  47. 2
      app/src/main/res/values/colors.xml
  48. 1
      app/src/main/res/values/dimens.xml
  49. 2
      app/src/main/res/values/strings.xml
  50. 1
      app/src/main/res/xml/preference_about.xml
  51. 3
      app/src/main/res/xml/preference_bookmarks.xml

15
app/build.gradle

@ -3,11 +3,11 @@ apply plugin: 'com.neenbedankt.android-apt' @@ -3,11 +3,11 @@ apply plugin: 'com.neenbedankt.android-apt'
android {
compileSdkVersion 23
buildToolsVersion "23.0.0"
buildToolsVersion "23.0.1"
defaultConfig {
minSdkVersion 14
targetSdkVersion 23
versionName "4.1.1a"
versionName "4.2.0a"
}
sourceSets {
lightningPlus.setRoot('src/LightningPlus')
@ -30,16 +30,16 @@ android { @@ -30,16 +30,16 @@ android {
lightningPlus {
buildConfigField "boolean", "FULL_VERSION", "true"
applicationId "acr.browser.lightning"
versionCode 80
versionCode 81
}
lightningLite {
buildConfigField "boolean", "FULL_VERSION", "false"
applicationId "acr.browser.barebones"
versionCode 81
versionCode 82
}
}
lintOptions {
abortOnError false
abortOnError true
}
}
@ -52,14 +52,15 @@ dependencies { @@ -52,14 +52,15 @@ dependencies {
compile 'com.squareup:otto:1.3.8'
compile 'com.google.dagger:dagger:2.0.1'
apt 'com.google.dagger:dagger-compiler:2.0.1'
compile 'com.jakewharton:butterknife:7.0.1'
// Only Lightning Plus needs the proxy libraries
lightningPlusCompile 'net.i2p.android:client:0.7'
compile 'net.i2p.android:client:0.7'
// Use the following code to update the libnetcipher submodule
// git submodule foreach git reset --hard
// git submodule update --remote
lightningPlusCompile(project(':libnetcipher'))
compile(project(':libnetcipher'))
debugCompile 'com.squareup.leakcanary:leakcanary-android:1.3.1'
releaseCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.3.1'

174
app/src/LightningLite/java/acr/browser/lightning/utils/ProxyUtils.java

@ -2,18 +2,39 @@ package acr.browser.lightning.utils; @@ -2,18 +2,39 @@ package acr.browser.lightning.utils;
import android.app.Activity;
import android.content.Context;
import android.content.DialogInterface;
import android.support.v7.app.AlertDialog;
import android.util.Log;
import com.squareup.otto.Bus;
import net.i2p.android.ui.I2PAndroidHelper;
import acr.browser.lightning.R;
import acr.browser.lightning.app.BrowserApp;
import acr.browser.lightning.bus.BrowserEvents;
import acr.browser.lightning.constant.Constants;
import acr.browser.lightning.preference.PreferenceManager;
import info.guardianproject.netcipher.proxy.OrbotHelper;
import info.guardianproject.netcipher.web.WebkitProxy;
/**
* 6/4/2015 Anthony Restaino
*/
public class ProxyUtils {
// Helper
private final I2PAndroidHelper mI2PHelper;
private static boolean mI2PHelperBound;
private static boolean mI2PProxyInitialized;
private final PreferenceManager mPreferences;
private static ProxyUtils mInstance;
private ProxyUtils(Context context) {
private final Bus mEventBus;
private ProxyUtils(Context context) {
mPreferences = BrowserApp.getAppComponent().getPreferenceManager();
mEventBus = BrowserApp.getAppComponent().getBus();
mI2PHelper = new I2PAndroidHelper(context.getApplicationContext());
}
public static ProxyUtils getInstance() {
@ -28,33 +49,172 @@ public class ProxyUtils { @@ -28,33 +49,172 @@ public class ProxyUtils {
* proxying for this session
*/
public void checkForProxy(final Activity activity) {
boolean useProxy = mPreferences.getUseProxy();
final boolean orbotInstalled = OrbotHelper.isOrbotInstalled(activity);
boolean orbotChecked = mPreferences.getCheckedForTor();
boolean orbot = orbotInstalled && !orbotChecked;
boolean i2pInstalled = mI2PHelper.isI2PAndroidInstalled();
boolean i2pChecked = mPreferences.getCheckedForI2P();
boolean i2p = i2pInstalled && !i2pChecked;
// TODO Is the idea to show this per-session, or only once?
if (!useProxy && (orbot || i2p)) {
if (orbot) mPreferences.setCheckedForTor(true);
if (i2p) mPreferences.setCheckedForI2P(true);
AlertDialog.Builder builder = new AlertDialog.Builder(activity);
if (orbotInstalled && i2pInstalled) {
String[] proxyChoices = activity.getResources().getStringArray(R.array.proxy_choices_array);
builder.setTitle(activity.getResources().getString(R.string.http_proxy))
.setSingleChoiceItems(proxyChoices, mPreferences.getProxyChoice(),
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
mPreferences.setProxyChoice(which);
}
})
.setNeutralButton(activity.getResources().getString(R.string.action_ok),
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
if (mPreferences.getUseProxy())
initializeProxy(activity);
}
});
} else {
DialogInterface.OnClickListener dialogClickListener = new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
switch (which) {
case DialogInterface.BUTTON_POSITIVE:
mPreferences.setProxyChoice(orbotInstalled ?
Constants.PROXY_ORBOT : Constants.PROXY_I2P);
initializeProxy(activity);
break;
case DialogInterface.BUTTON_NEGATIVE:
mPreferences.setProxyChoice(Constants.NO_PROXY);
break;
}
}
};
builder.setMessage(orbotInstalled ? R.string.use_tor_prompt : R.string.use_i2p_prompt)
.setPositiveButton(R.string.yes, dialogClickListener)
.setNegativeButton(R.string.no, dialogClickListener);
}
builder.show();
}
}
/*
* Initialize WebKit Proxying
*/
private void initializeProxy(Activity activity) {
String host;
int port;
switch (mPreferences.getProxyChoice()) {
case Constants.NO_PROXY:
// We shouldn't be here
return;
case Constants.PROXY_ORBOT:
if (!OrbotHelper.isOrbotRunning(activity))
OrbotHelper.requestStartTor(activity);
host = "localhost";
port = 8118;
break;
case Constants.PROXY_I2P:
mI2PProxyInitialized = true;
if (mI2PHelperBound && !mI2PHelper.isI2PAndroidRunning()) {
mI2PHelper.requestI2PAndroidStart(activity);
}
host = "localhost";
port = 4444;
break;
default:
host = mPreferences.getProxyHost();
port = mPreferences.getProxyPort();
}
try {
WebkitProxy.setProxy(BrowserApp.class.getName(), activity.getApplicationContext(), null, host, port);
} catch (Exception e) {
Log.d(Constants.TAG, "error enabling web proxying", e);
}
}
public boolean isProxyReady(Context context) {
public boolean isProxyReady() {
if (mPreferences.getProxyChoice() == Constants.PROXY_I2P) {
if (!mI2PHelper.isI2PAndroidRunning()) {
mEventBus.post(new BrowserEvents.ShowSnackBarMessage(R.string.i2p_not_running));
return false;
} else if (!mI2PHelper.areTunnelsActive()) {
mEventBus.post(new BrowserEvents.ShowSnackBarMessage(R.string.i2p_tunnels_not_ready));
return false;
}
}
return true;
}
public void updateProxySettings(Activity activity) {
if (mPreferences.getUseProxy()) {
initializeProxy(activity);
} else {
try {
WebkitProxy.resetProxy(BrowserApp.class.getName(), activity.getApplicationContext());
} catch (Exception e) {
e.printStackTrace();
}
mI2PProxyInitialized = false;
}
}
public void onStop() {
mI2PHelper.unbind();
mI2PHelperBound = false;
}
public void onStart(final Activity activity) {
if (mPreferences.getProxyChoice() == Constants.PROXY_I2P) {
// Try to bind to I2P Android
mI2PHelper.bind(new I2PAndroidHelper.Callback() {
@Override
public void onI2PAndroidBound() {
mI2PHelperBound = true;
if (mI2PProxyInitialized && !mI2PHelper.isI2PAndroidRunning())
mI2PHelper.requestI2PAndroidStart(activity);
}
});
}
}
public static int setProxyChoice(int choice, Activity activity) {
switch (choice) {
case Constants.PROXY_ORBOT:
if (!OrbotHelper.isOrbotInstalled(activity)) {
choice = Constants.NO_PROXY;
Utils.showSnackbar(activity, R.string.install_orbot);
}
break;
case Constants.PROXY_I2P:
I2PAndroidHelper ih = new I2PAndroidHelper(activity.getApplicationContext());
if (!ih.isI2PAndroidInstalled()) {
choice = Constants.NO_PROXY;
ih.promptToInstall(activity);
}
break;
case Constants.PROXY_MANUAL:
break;
}
return choice;
}
}

1
app/src/LightningPlus/java/acr/browser/lightning/utils/ProxyUtils.java

@ -3,7 +3,6 @@ package acr.browser.lightning.utils; @@ -3,7 +3,6 @@ package acr.browser.lightning.utils;
import android.app.Activity;
import android.content.Context;
import android.content.DialogInterface;
import android.support.annotation.NonNull;
import android.support.v7.app.AlertDialog;
import android.util.Log;

19
app/src/main/AndroidManifest.xml

@ -1,13 +1,14 @@ @@ -1,13 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright 2014 A.C.R. Development -->
<?xml version="1.0" encoding="utf-8"?><!-- Copyright 2014 A.C.R. Development -->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="acr.browser.lightning" >
package="acr.browser.lightning">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="com.android.browser.permission.READ_HISTORY_BOOKMARKS" />
<uses-permission android:name="com.android.browser.permission.WRITE_HISTORY_BOOKMARKS" />
<uses-feature
android:name="android.hardware.location.gps"
@ -24,14 +25,14 @@ @@ -24,14 +25,14 @@
android:allowBackup="true"
android:hardwareAccelerated="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name" >
android:label="@string/app_name">
<activity
android:name=".activity.MainActivity"
android:alwaysRetainTaskState="true"
android:configChanges="orientation|screenSize|keyboardHidden|keyboard"
android:label="@string/app_name"
android:launchMode="singleTask"
android:theme="@style/Theme.LightTheme" >
android:theme="@style/Theme.LightTheme">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
@ -96,7 +97,7 @@ @@ -96,7 +97,7 @@
android:name=".activity.SettingsActivity"
android:configChanges="orientation|screenSize|keyboardHidden|keyboard"
android:label="@string/settings"
android:theme="@style/Theme.SettingsTheme" >
android:theme="@style/Theme.SettingsTheme">
<intent-filter>
<action android:name="android.intent.action.SETTINGS" />
@ -109,9 +110,9 @@ @@ -109,9 +110,9 @@
android:configChanges="orientation|screenSize|keyboardHidden|keyboard"
android:label="@string/app_name"
android:launchMode="singleTask"
android:process=":incognito"
android:theme="@style/Theme.DarkTheme"
android:windowSoftInputMode="stateHidden"
android:process=":incognito">
android:windowSoftInputMode="stateHidden">
<intent-filter>
<action android:name="android.intent.action.INCOGNITO" />
@ -122,7 +123,7 @@ @@ -122,7 +123,7 @@
android:name=".activity.ReadingActivity"
android:configChanges="orientation|screenSize|keyboardHidden|keyboard"
android:label="@string/reading_mode"
android:theme="@style/Theme.SettingsTheme" >
android:theme="@style/Theme.SettingsTheme">
<intent-filter>
<action android:name="android.intent.action.READING" />

344
app/src/main/java/acr/browser/lightning/activity/BrowserActivity.java

@ -32,6 +32,7 @@ import android.provider.MediaStore; @@ -32,6 +32,7 @@ import android.provider.MediaStore;
import android.support.annotation.IdRes;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.content.ContextCompat;
import android.support.v4.view.GravityCompat;
import android.support.v4.widget.DrawerLayout;
import android.support.v4.widget.DrawerLayout.DrawerListener;
@ -85,6 +86,8 @@ import com.squareup.otto.Subscribe; @@ -85,6 +86,8 @@ import com.squareup.otto.Subscribe;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import javax.inject.Inject;
@ -113,20 +116,43 @@ import acr.browser.lightning.utils.Utils; @@ -113,20 +116,43 @@ import acr.browser.lightning.utils.Utils;
import acr.browser.lightning.utils.WebUtils;
import acr.browser.lightning.view.AnimatedProgressBar;
import acr.browser.lightning.view.LightningView;
import butterknife.Bind;
import butterknife.ButterKnife;
public abstract class BrowserActivity extends ThemableBrowserActivity implements BrowserController, OnClickListener, OnLongClickListener {
// Layout
private DrawerLayout mDrawerLayout;
private FrameLayout mBrowserFrame;
private FullscreenHolder mFullscreenContainer;
private ViewGroup mDrawerLeft, mDrawerRight, mUiLayout, mToolbarLayout;
private RelativeLayout mSearchBar;
// Static Layout
@Bind(R.id.drawer_layout)
DrawerLayout mDrawerLayout;
// Views
private AnimatedProgressBar mProgressBar;
@Bind(R.id.content_frame)
FrameLayout mBrowserFrame;
@Bind(R.id.left_drawer)
ViewGroup mDrawerLeft;
@Bind(R.id.right_drawer)
ViewGroup mDrawerRight;
@Bind(R.id.ui_layout)
ViewGroup mUiLayout;
@Bind(R.id.toolbar_layout)
ViewGroup mToolbarLayout;
@Bind(R.id.progress_view)
AnimatedProgressBar mProgressBar;
@Bind(R.id.search_bar)
RelativeLayout mSearchBar;
// Toolbar Views
private AutoCompleteTextView mSearch;
private ImageView mArrowImage;
// Full Screen Video Views
private FrameLayout mFullscreenContainer;
private VideoView mVideoView;
private View mCustomView;
@ -138,9 +164,6 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements @@ -138,9 +164,6 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements
private ValueCallback<Uri> mUploadMessage;
private ValueCallback<Uri[]> mFilePathCallback;
// Context
private Activity mActivity;
// Primatives
private boolean mFullScreen, mColorMode, mDarkTheme,
mIsNewIntent = false,
@ -153,14 +176,14 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements @@ -153,14 +176,14 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements
// The singleton BookmarkManager
@Inject
BookmarkManager bookmarkManager;
BookmarkManager mBookmarkManager;
// Event bus
@Inject
Bus eventBus;
Bus mEventBus;
@Inject
BookmarkPage bookmarkPage;
BookmarkPage mBookmarkPage;
@Inject
LightningDialogBuilder bookmarksDialogBuilder;
@ -206,11 +229,12 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements @@ -206,11 +229,12 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
BrowserApp.getAppComponent().inject(this);
setContentView(R.layout.activity_main);
ButterKnife.bind(this);
initialize();
}
private synchronized void initialize() {
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
ActionBar actionBar = getSupportActionBar();
@ -220,20 +244,12 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements @@ -220,20 +244,12 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements
mIconColor = mDarkTheme ? ThemeUtils.getIconDarkThemeColor(this) : ThemeUtils.getIconLightThemeColor(this);
mShowTabsInDrawer = mPreferences.getShowTabsInDrawer(!isTablet());
mActivity = this;
mBrowserFrame = (FrameLayout) findViewById(R.id.content_frame);
mToolbarLayout = (LinearLayout) findViewById(R.id.toolbar_layout);
// initialize background ColorDrawable
mBackground.setColor(((ColorDrawable) mToolbarLayout.getBackground()).getColor());
mUiLayout = (LinearLayout) findViewById(R.id.ui_layout);
mProgressBar = (AnimatedProgressBar) findViewById(R.id.progress_view);
mDrawerLeft = (FrameLayout) findViewById(R.id.left_drawer);
// Drawer stutters otherwise
mDrawerLeft.setLayerType(View.LAYER_TYPE_HARDWARE, null);
mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
mDrawerRight = (ViewGroup) findViewById(R.id.right_drawer);
mDrawerRight.setLayerType(View.LAYER_TYPE_HARDWARE, null);
// TODO Please review this
// ImageView tabTitleImage = (ImageView) findViewById(R.id.plusIcon);
@ -273,15 +289,14 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements @@ -273,15 +289,14 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements
actionBar.setDisplayShowCustomEnabled(true);
actionBar.setCustomView(R.layout.toolbar_content);
View v = actionBar.getCustomView();
LayoutParams lp = v.getLayoutParams();
View customView = actionBar.getCustomView();
LayoutParams lp = customView.getLayoutParams();
lp.width = LayoutParams.MATCH_PARENT;
lp.height = LayoutParams.MATCH_PARENT;
v.setLayoutParams(lp);
customView.setLayoutParams(lp);
mArrowImage = (ImageView) actionBar.getCustomView().findViewById(R.id.arrow);
FrameLayout arrowButton = (FrameLayout) actionBar.getCustomView().findViewById(
R.id.arrow_button);
mArrowImage = (ImageView) customView.findViewById(R.id.arrow);
FrameLayout arrowButton = (FrameLayout) customView.findViewById(R.id.arrow_button);
if (mShowTabsInDrawer) {
// Use hardware acceleration for the animation
mArrowDrawable = new DrawerArrowDrawable(this);
@ -295,17 +310,10 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements @@ -295,17 +310,10 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements
mProxyUtils = ProxyUtils.getInstance();
setupFrameLayoutButton(R.id.action_reading, R.id.icon_reading);
setupFrameLayoutButton(R.id.action_toggle_desktop, R.id.icon_desktop);
// create the search EditText in the ToolBar
mSearch = (AutoCompleteTextView) actionBar.getCustomView().findViewById(R.id.search);
mSearch = (AutoCompleteTextView) customView.findViewById(R.id.search);
mUntitledTitle = getString(R.string.untitled);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
mBackgroundColor = getColor(R.color.primary_color);
} else {
mBackgroundColor = getResources().getColor(R.color.primary_color);
}
mBackgroundColor = ContextCompat.getColor(this, R.color.primary_color);
mDeleteIcon = ThemeUtils.getLightThemedDrawable(this, R.drawable.ic_action_delete);
mRefreshIcon = ThemeUtils.getLightThemedDrawable(this, R.drawable.ic_action_refresh);
mClearIcon = ThemeUtils.getLightThemedDrawable(this, R.drawable.ic_action_delete);
@ -335,6 +343,7 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements @@ -335,6 +343,7 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements
mDrawerLayout.setDrawerShadow(R.drawable.drawer_left_shadow, GravityCompat.START);
if (API <= Build.VERSION_CODES.JELLY_BEAN_MR2) {
//noinspection deprecation
WebIconDatabase.getInstance().open(getDir("icons", MODE_PRIVATE).getPath());
}
@ -391,11 +400,7 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements @@ -391,11 +400,7 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements
public void onFocusChange(View v, final boolean hasFocus) {
final LightningView currentView = tabsManager.getCurrentTab();
if (!hasFocus && currentView != null) {
if (currentView.getProgress() < 100) {
setIsLoading();
} else {
setIsFinishedLoading();
}
setIsLoading(currentView.getProgress() < 100);
updateUrl(currentView.getUrl(), true);
} else if (hasFocus) {
String url = currentView.getUrl();
@ -704,7 +709,7 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements @@ -704,7 +709,7 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements
ClipboardManager clipboard = (ClipboardManager) getSystemService(CLIPBOARD_SERVICE);
ClipData clip = ClipData.newPlainText("label", currentView.getUrl());
clipboard.setPrimaryClip(clip);
Utils.showSnackbar(mActivity, R.string.message_link_copied);
Utils.showSnackbar(this, R.string.message_link_copied);
}
return true;
case R.id.action_settings:
@ -715,7 +720,7 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements @@ -715,7 +720,7 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements
return true;
case R.id.action_add_bookmark:
if (currentView != null && !currentView.getUrl().startsWith(Constants.FILE)) {
eventBus.post(new BrowserEvents.AddBookmark(currentView.getTitle(),
mEventBus.post(new BrowserEvents.AddBookmark(currentView.getTitle(),
currentView.getUrl()));
}
return true;
@ -737,7 +742,7 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements @@ -737,7 +742,7 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements
* for. It highlights the text entered.
*/
private void findInPage() {
final AlertDialog.Builder finder = new AlertDialog.Builder(mActivity);
final AlertDialog.Builder finder = new AlertDialog.Builder(this);
finder.setTitle(getResources().getString(R.string.action_find));
final EditText getHome = new EditText(this);
getHome.setHint(getResources().getString(R.string.search_hint));
@ -760,7 +765,6 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements @@ -760,7 +765,6 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements
if (currentView != null) {
currentView.find(text);
}
mSearchBar = (RelativeLayout) findViewById(R.id.search_bar);
mSearchBar.setVisibility(View.VISIBLE);
TextView tw = (TextView) findViewById(R.id.search_query);
@ -780,11 +784,11 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements @@ -780,11 +784,11 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements
if (position < 0) {
return;
}
AlertDialog.Builder builder = new AlertDialog.Builder(mActivity);
ArrayAdapter<String> adapter = new ArrayAdapter<>(mActivity,
AlertDialog.Builder builder = new AlertDialog.Builder(this);
ArrayAdapter<String> adapter = new ArrayAdapter<>(this,
android.R.layout.simple_dropdown_item_1line);
adapter.add(mActivity.getString(R.string.close_tab));
adapter.add(mActivity.getString(R.string.close_all_tabs));
adapter.add(this.getString(R.string.close_tab));
adapter.add(this.getString(R.string.close_all_tabs));
builder.setAdapter(adapter, new DialogInterface.OnClickListener() {
@Override
@ -818,7 +822,7 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements @@ -818,7 +822,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 == null || currentView == newView) {
if (newView == currentView && !currentView.isShown()) {
return;
}
mIsNewIntent = false;
@ -871,7 +875,7 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements @@ -871,7 +875,7 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements
}, 200);
// Should update the bookmark status in BookmarksFragment
eventBus.post(new BrowserEvents.CurrentPageUrl(newView.getUrl()));
mEventBus.post(new BrowserEvents.CurrentPageUrl(newView.getUrl()));
// new Handler().postDelayed(new Runnable() {
// @Override
@ -916,7 +920,7 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements @@ -916,7 +920,7 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements
}
currentTab.loadUrl(url);
eventBus.post(new BrowserEvents.CurrentPageUrl(url));
mEventBus.post(new BrowserEvents.CurrentPageUrl(url));
}
@Override
@ -936,8 +940,8 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements @@ -936,8 +940,8 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements
if (level > TRIM_MEMORY_MODERATE && Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
Log.d(Constants.TAG, "Low Memory, Free Memory");
tabsManager.freeMemory();
}
}
}
synchronized boolean newTab(String url, boolean show) {
// Limit number of tabs for limited version of app
@ -956,7 +960,7 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements @@ -956,7 +960,7 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements
showTab(tabsManager.size() - 1);
}
// TODO Check is this is callable directly from LightningView
eventBus.post(new BrowserEvents.TabsChanged());
mEventBus.post(new BrowserEvents.TabsChanged());
// TODO Restore this
// new Handler().postDelayed(new Runnable() {
@ -992,14 +996,14 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements @@ -992,14 +996,14 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements
if (current > position) {
tabsManager.deleteTab(position);
showTab(current - 1);
eventBus.post(new BrowserEvents.TabsChanged());
mEventBus.post(new BrowserEvents.TabsChanged());
tabToDelete.onDestroy();
} else if (tabsManager.size() > position + 1) {
if (current == position) {
showTab(position + 1);
tabsManager.deleteTab(position);
showTab(position);
eventBus.post(new BrowserEvents.TabsChanged());
mEventBus.post(new BrowserEvents.TabsChanged());
} else {
tabsManager.deleteTab(position);
}
@ -1010,9 +1014,8 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements @@ -1010,9 +1014,8 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements
showTab(position - 1);
tabsManager.deleteTab(position);
showTab(position - 1);
eventBus.post(new BrowserEvents.TabsChanged());
mEventBus.post(new BrowserEvents.TabsChanged());
} else {
tabsManager.deleteTab(position);
}
tabToDelete.onDestroy();
@ -1024,11 +1027,11 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements @@ -1024,11 +1027,11 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements
performExitCleanUp();
tabToDelete.pauseTimers();
tabToDelete.onDestroy();
eventBus.post(new BrowserEvents.TabsChanged());
mEventBus.post(new BrowserEvents.TabsChanged());
finish();
}
}
eventBus.post(new BrowserEvents.TabsChanged());
mEventBus.post(new BrowserEvents.TabsChanged());
if (mIsNewIntent && isShown) {
mIsNewIntent = false;
@ -1043,17 +1046,14 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements @@ -1043,17 +1046,14 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements
if (mPreferences.getClearCacheExit() && currentTab != null && !isIncognito()) {
WebUtils.clearCache(currentTab.getWebView());
Log.d(Constants.TAG, "Cache Cleared");
}
if (mPreferences.getClearHistoryExitEnabled() && !isIncognito()) {
WebUtils.clearHistory(this);
Log.d(Constants.TAG, "History Cleared");
}
if (mPreferences.getClearCookiesExitEnabled() && !isIncognito()) {
WebUtils.clearCookies(this);
Log.d(Constants.TAG, "Cookies Cleared");
}
if (mPreferences.getClearWebStorageExitEnabled() && !isIncognito()) {
WebUtils.clearWebStorage();
@ -1076,7 +1076,7 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements @@ -1076,7 +1076,7 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements
mBrowserFrame.setBackgroundColor(mBackgroundColor);
performExitCleanUp();
tabsManager.shutdown();
eventBus.post(new BrowserEvents.TabsChanged());
mEventBus.post(new BrowserEvents.TabsChanged());
finish();
}
@ -1086,7 +1086,7 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements @@ -1086,7 +1086,7 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements
if (mDrawerLayout.isDrawerOpen(mDrawerLeft)) {
mDrawerLayout.closeDrawer(mDrawerLeft);
} else if (mDrawerLayout.isDrawerOpen(mDrawerRight)) {
eventBus
mEventBus
.post(new BrowserEvents.UserPressedBack());
} else {
if (currentTab != null) {
@ -1127,13 +1127,13 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements @@ -1127,13 +1127,13 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements
overridePendingTransition(R.anim.fade_in_scale, R.anim.slide_down_out);
}
eventBus.unregister(busEventListener);
mEventBus.unregister(mBusEventListener);
}
void saveOpenTabs() {
if (mPreferences.getRestoreLostTabsEnabled()) {
final String s = tabsManager.tabsString();
mPreferences.setMemoryUrl(s);
mPreferences.setMemoryUrl(s.toString());
}
}
@ -1181,7 +1181,7 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements @@ -1181,7 +1181,7 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements
filter.addAction(NETWORK_BROADCAST_ACTION);
registerReceiver(mNetworkReceiver, filter);
eventBus.register(busEventListener);
mEventBus.register(mBusEventListener);
}
/**
@ -1210,12 +1210,7 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements @@ -1210,12 +1210,7 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements
* @param tabBackground the optional LinearLayout to color
*/
private void changeToolbarBackground(@NonNull Bitmap favicon, @Nullable final Drawable tabBackground) {
final int defaultColor;
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.LOLLIPOP_MR1) {
defaultColor = getResources().getColor(R.color.primary_color);
} else {
defaultColor = getColor(R.color.primary_color);
}
final int defaultColor = ContextCompat.getColor(this, R.color.primary_color);
if (mCurrentUiColor == Color.BLACK) {
mCurrentUiColor = defaultColor;
}
@ -1268,7 +1263,7 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements @@ -1268,7 +1263,7 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements
if (url == null || mSearch == null || mSearch.hasFocus()) {
return;
}
eventBus.post(new BrowserEvents.CurrentPageUrl(url));
mEventBus.post(new BrowserEvents.CurrentPageUrl(url));
if (shortUrl && !url.startsWith(Constants.FILE)) {
switch (mPreferences.getUrlBoxContentChoice()) {
case 0: // Default, show only the domain
@ -1297,11 +1292,7 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements @@ -1297,11 +1292,7 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements
@Override
public void updateProgress(int n) {
if (n >= 100) {
setIsFinishedLoading();
} else {
setIsLoading();
}
setIsLoading(n < 100);
mProgressBar.setProgress(n);
}
@ -1341,7 +1332,7 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements @@ -1341,7 +1332,7 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements
try {
String url;
url = ((TextView) arg1.findViewById(R.id.url)).getText().toString();
if (url.startsWith(mActivity.getString(R.string.suggestion))) {
if (url.startsWith(BrowserActivity.this.getString(R.string.suggestion))) {
url = ((TextView) arg1.findViewById(R.id.title)).getText().toString();
} else {
getUrl.setText(url);
@ -1360,7 +1351,7 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements @@ -1360,7 +1351,7 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements
});
getUrl.setSelectAllOnFocus(true);
mSearchAdapter = new SearchAdapter(mActivity, mDarkTheme, isIncognito());
mSearchAdapter = new SearchAdapter(this, mDarkTheme, isIncognito());
getUrl.setAdapter(mSearchAdapter);
}
@ -1373,7 +1364,7 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements @@ -1373,7 +1364,7 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements
@Override
public void run() {
loadUrlInCurrentView(HistoryPage.getHistoryPage(mActivity));
loadUrlInCurrentView(HistoryPage.getHistoryPage(BrowserActivity.this));
mSearch.setText("");
}
@ -1471,7 +1462,7 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements @@ -1471,7 +1462,7 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements
mFilePathCallback = filePathCallback;
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (takePictureIntent.resolveActivity(mActivity.getPackageManager()) != null) {
if (takePictureIntent.resolveActivity(this.getPackageManager()) != null) {
// Create the File where the photo should go
File photoFile = null;
try {
@ -1493,7 +1484,7 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements @@ -1493,7 +1484,7 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements
Intent contentSelectionIntent = new Intent(Intent.ACTION_GET_CONTENT);
contentSelectionIntent.addCategory(Intent.CATEGORY_OPENABLE);
contentSelectionIntent.setType("image/*");
contentSelectionIntent.setType("*/*");
Intent[] intentArray;
if (takePictureIntent != null) {
@ -1507,7 +1498,7 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements @@ -1507,7 +1498,7 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements
chooserIntent.putExtra(Intent.EXTRA_TITLE, "Image Chooser");
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, intentArray);
mActivity.startActivityForResult(chooserIntent, 1);
this.startActivityForResult(chooserIntent, 1);
}
@Override
@ -1527,7 +1518,8 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements @@ -1527,7 +1518,8 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements
}
mOriginalOrientation = getRequestedOrientation();
FrameLayout decor = (FrameLayout) getWindow().getDecorView();
mFullscreenContainer = new FullscreenHolder(this);
mFullscreenContainer = new FrameLayout(this);
mFullscreenContainer.setBackgroundColor(ContextCompat.getColor(this, android.R.color.black));
mCustomView = view;
mFullscreenContainer.addView(mCustomView, COVER_SCREEN_PARAMS);
decor.addView(mFullscreenContainer, COVER_SCREEN_PARAMS);
@ -1603,9 +1595,15 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements @@ -1603,9 +1595,15 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements
}
/**
* turns on fullscreen mode in the app
* This method sets whether or not the activity will display
* in full-screen mode (i.e. the ActionBar will be hidden) and
* whether or not immersive mode should be set. This is used to
* set both parameters correctly as during a full-screen video,
* both need to be set, but other-wise we leave it up to user
* preference.
*
* @param enabled whether to enable fullscreen or not
* @param enabled true to enable full-screen, false otherwise
* @param immersive true to enable immersive mode, false otherwise
*/
private void setFullscreen(boolean enabled, boolean immersive) {
mIsFullScreen = enabled;
@ -1630,31 +1628,25 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements @@ -1630,31 +1628,25 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements
}
/**
* a class extending FramLayout used to display fullscreen videos
* This interface method is used by the LightningView to obtain an
* image that is displayed as a placeholder on a video until the video
* has initialized and can begin loading.
*
* @return a Bitmap that can be used as a place holder for videos.
*/
private class FullscreenHolder extends FrameLayout {
public FullscreenHolder(Context ctx) {
super(ctx);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
setBackgroundColor(ctx.getColor(android.R.color.black));
} else {
setBackgroundColor(ctx.getResources().getColor(android.R.color.black));
}
}
@Override
public boolean onTouchEvent(@NonNull MotionEvent evt) {
return true;
}
}
@Override
public Bitmap getDefaultVideoPoster() {
return BitmapFactory.decodeResource(getResources(), android.R.drawable.spinner_background);
}
/**
* An interface method so that we can inflate a view to send to
* a LightningView when it needs to display a video and has to
* show a loading dialog. Inflates a progress view and returns it.
*
* @return A view that should be used to display the state
* of a video's loading progress.
*/
@Override
public View getVideoLoadingProgressView() {
LayoutInflater inflater = LayoutInflater.from(this);
@ -1662,7 +1654,12 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements @@ -1662,7 +1654,12 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements
}
/**
* handles javascript requests to create a new window in the browser
* This method handles the JavaScript callback to create a new tab.
* Basically this handles the event that JavaScript needs to create
* a popup.
*
* @param resultMsg the transport message used to send the URL to
* the newly created WebView.
*/
@Override
public void onCreateWindow(Message resultMsg) {
@ -1679,9 +1676,12 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements @@ -1679,9 +1676,12 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements
}
/**
* Closes the specified view, implementing the JavaScript callback to close a window
* Closes the specified {@link LightningView}. This implements
* the JavaScript callback that asks the tab to close itself and
* is especially helpful when a page creates a redirect and does
* not need the tab to stay open any longer.
*
* @param view the LightningView to close
* @param view the LightningView to close, delete it.
*/
@Override
public void onCloseWindow(LightningView view) {
@ -1689,16 +1689,9 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements @@ -1689,16 +1689,9 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements
}
/**
* returns the Activity instance for this activity,
* very helpful when creating things in other classes... I think
*/
@Override
public Activity getActivity() {
return mActivity;
}
/**
* it hides the action bar, seriously what else were you expecting
* Hide the ActionBar using an animation if we are in full-screen
* mode. This method also re-parents the ActionBar if its parent is
* incorrect so that the animation can happen correctly.
*/
@Override
public void hideActionBar() {
@ -1730,14 +1723,15 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements @@ -1730,14 +1723,15 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements
};
show.setDuration(250);
show.setInterpolator(new DecelerateInterpolator());
// show.setFillAfter(true);
currentWebView.startAnimation(show);
}
}
}
/**
* obviously it shows the action bar if it's hidden
* Display the ActionBar using an animation if we are in full-screen
* mode. This method also re-parents the ActionBar if its parent is
* incorrect so that the animation can happen correctly.
*/
@Override
public void showActionBar() {
@ -1761,7 +1755,7 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements @@ -1761,7 +1755,7 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements
mToolbarLayout.setTranslationY(0);
if (view != null) {
view.setTranslationY(height);
}
}
}
final LightningView currentTab = tabsManager.getCurrentTab();
if (currentTab == null)
@ -1781,7 +1775,6 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements @@ -1781,7 +1775,6 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements
};
show.setDuration(250);
show.setInterpolator(new DecelerateInterpolator());
// show.setFillAfter(true);
if (view != null) {
view.startAnimation(show);
}
@ -1794,28 +1787,16 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements @@ -1794,28 +1787,16 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements
* and that it should display the stop icon to indicate to the user that
* pressing it stops the page from loading
*/
private 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
*/
private void setIsFinishedLoading() {
private void setIsLoading(boolean isLoading) {
if (!mSearch.hasFocus()) {
mIcon = mRefreshIcon;
mSearch.setCompoundDrawables(null, null, mRefreshIcon, null);
mIcon = isLoading ? mDeleteIcon : mRefreshIcon;
mSearch.setCompoundDrawables(null, null, mIcon, 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.
* <p/>
* See setIsFinishedLoading and setIsLoading for displaying the correct icon
*/
private void refreshOrStop() {
@ -1829,6 +1810,13 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements @@ -1829,6 +1810,13 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements
}
}
/**
* Handle the click event for the views that are using
* this class as a click listener. This method should
* distinguish between the various views using their IDs.
*
* @param v the view that the user has clicked
*/
@Override
public void onClick(View v) {
final LightningView currentTab = tabsManager.getCurrentTab();
@ -1866,12 +1854,33 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements @@ -1866,12 +1854,33 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements
}
}
/**
* Handle long presses on views that use this class
* as their OnLongClickListener. This method should
* distinguish between the IDs of the views that are
* getting clicked.
*
* @param view the view that has been long pressed
* @return returns true since the method handles the long press
* event
*/
@Override
public boolean onLongClick(View view) {
return true;
}
// TODO Check if all the calls are relative to TabsFragement
/**
* A utility method that creates a FrameLayout button with the given ID and
* sets the image of the button to the given image ID. The OnClick and OnLongClick
* listeners are set to this class, so BrowserActivity should handle those events
* there. Additionally, it tints the images according to the current theme.
* This method only is a convenience so that this code does not have to be repeated
* for the several "Buttons" that use this.
*
* @param buttonId the view id of the button
* @param imageId the image to set as the button image
*/
private void setupFrameLayoutButton(@IdRes int buttonId, @IdRes int imageId) {
final View frameButton = findViewById(buttonId);
final ImageView buttonImage = (ImageView) findViewById(imageId);
@ -1880,6 +1889,12 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements @@ -1880,6 +1889,12 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements
buttonImage.setColorFilter(mIconColor, PorterDuff.Mode.SRC_IN);
}
/**
* This NetworkReceiver notifies each of the WebViews in the browser whether
* the network is currently connected or not. This is important because some
* JavaScript properties rely on the WebView knowing the current network state.
* It is used to help the browser be compliant with the HTML5 spec, sec. 5.7.7
*/
private final NetworkReceiver mNetworkReceiver = new NetworkReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
@ -1887,21 +1902,32 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements @@ -1887,21 +1902,32 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements
boolean isConnected = isConnected(context);
Log.d(Constants.TAG, "Network Connected: " + String.valueOf(isConnected));
tabsManager.notifyConnectioneStatus(isConnected);
}
}
};
/**
* Handle the callback that permissions requested have been granted or not.
* This method should act upon the results of the permissions request.
*
* @param requestCode the request code sent when initially making the request
* @param permissions the array of the permissions that was requested
* @param grantResults the results of the permissions requests that provides
* information on whether the request was granted or not
*/
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
PermissionsManager.getInstance().notifyPermissionsChange(permissions);
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
private final Object busEventListener = new Object() {
private final Object mBusEventListener = new Object() {
/**
* Load the given url in the current tab, used by the the
* {@link acr.browser.lightning.fragment.BookmarksFragment} and by the
* {@link LightningDialogBuilder}
* @param event The event as it comes from the bus
*
* @param event Bus event indicating that the user has clicked a bookmark
*/
@Subscribe
public void loadUrlInCurrentTab(final BrowserEvents.OpenUrlInCurrentTab event) {
@ -1921,7 +1947,9 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements @@ -1921,7 +1947,9 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements
* Load the given url in a new tab, used by the the
* {@link acr.browser.lightning.fragment.BookmarksFragment} and by the
* {@link LightningDialogBuilder}
* @param event The event as it comes from the bus
*
* @param event Bus event indicating that the user wishes
* to open a bookmark in a new tab
*/
@Subscribe
public void loadUrlInNewTab(final BrowserEvents.OpenUrlInNewTab event) {
@ -1934,13 +1962,13 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements @@ -1934,13 +1962,13 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements
* message this receiver answer firing the
* {@link acr.browser.lightning.bus.BrowserEvents.AddBookmark} message
*
* @param event basically a marker
* @param event an event that the user wishes to bookmark the current page
*/
@Subscribe
public void bookmarkCurrentPage(final BookmarkEvents.WantToBookmarkCurrentPage event) {
final LightningView currentTab = tabsManager.getCurrentTab();
if (currentTab != null) {
eventBus.post(new BrowserEvents.AddBookmark(currentTab.getTitle(), currentTab.getUrl()));
mEventBus.post(new BrowserEvents.AddBookmark(currentTab.getTitle(), currentTab.getUrl()));
}
}
@ -1948,7 +1976,7 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements @@ -1948,7 +1976,7 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements
* This message is received when a bookmark was added by the
* {@link acr.browser.lightning.fragment.BookmarksFragment}
*
* @param event a marker
* @param event the event that a bookmark has been added
*/
@Subscribe
public void bookmarkAdded(final BookmarkEvents.Added event) {
@ -1956,9 +1984,9 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements @@ -1956,9 +1984,9 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements
}
/**
* This is received when the user edit a bookmark
* This method is called when the user edits a bookmark.
*
* @param event the event that the bookmark has changed
* @param event the event that the bookmark has changed.
*/
@Subscribe
public void bookmarkChanged(final BookmarkEvents.BookmarkChanged event) {
@ -1969,12 +1997,12 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements @@ -1969,12 +1997,12 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements
currentTab.loadBookmarkpage();
}
if (currentTab != null) {
eventBus.post(new BrowserEvents.CurrentPageUrl(currentTab.getUrl()));
mEventBus.post(new BrowserEvents.CurrentPageUrl(currentTab.getUrl()));
}
}
/**
* Notify the browser that a bookmark was deleted
* Notify the browser that a bookmark was deleted.
*
* @param event the event that the bookmark has been deleted
*/
@ -1987,7 +2015,7 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements @@ -1987,7 +2015,7 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements
currentTab.loadBookmarkpage();
}
if (currentTab != null) {
eventBus.post(new BrowserEvents.CurrentPageUrl(currentTab.getUrl()));
mEventBus.post(new BrowserEvents.CurrentPageUrl(currentTab.getUrl()));
}
}
@ -1996,7 +2024,8 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements @@ -1996,7 +2024,8 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements
* to {@link acr.browser.lightning.bus.BrowserEvents.UserPressedBack} message if the
* fragement is showing the boomarks root folder.
*
* @param event a marker
* @param event an event notifying the browser that the bookmark drawer
* should be closed.
*/
@Subscribe
public void closeBookmarks(final BookmarkEvents.CloseBookmarks event) {
@ -2086,7 +2115,7 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements @@ -2086,7 +2115,7 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements
if (url != null) {
BrowserActivity.this.newTab(url, true);
Utils.showSnackbar(mActivity, R.string.deleted_tab);
Utils.showSnackbar(BrowserActivity.this, R.string.deleted_tab);
}
mPreferences.setSavedUrl(null);
}
@ -2096,7 +2125,8 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements @@ -2096,7 +2125,8 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements
if (event.message != null) {
Utils.showSnackbar(BrowserActivity.this, event.message);
} else {
Utils.showSnackbar(mActivity, event.stringRes); }
Utils.showSnackbar(BrowserActivity.this, event.stringRes);
}
}
};
}

2
app/src/main/java/acr/browser/lightning/activity/ThemableBrowserActivity.java

@ -37,7 +37,7 @@ public abstract class ThemableBrowserActivity extends AppCompatActivity { @@ -37,7 +37,7 @@ public abstract class ThemableBrowserActivity extends AppCompatActivity {
}
}
public boolean isTablet() {
boolean isTablet() {
return (getResources().getConfiguration().screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK) == Configuration.SCREENLAYOUT_SIZE_XLARGE;
}

2
app/src/main/java/acr/browser/lightning/app/BrowserApp.java

@ -26,7 +26,7 @@ public class BrowserApp extends Application { @@ -26,7 +26,7 @@ public class BrowserApp extends Application {
return appComponent;
}
public void buildDepencyGraph() {
private void buildDepencyGraph() {
appComponent = DaggerAppComponent.builder().appModule(new AppModule(this)).build();
}

52
app/src/main/java/acr/browser/lightning/async/AsyncExecutor.java

@ -0,0 +1,52 @@ @@ -0,0 +1,52 @@
package acr.browser.lightning.async;
import android.support.annotation.NonNull;
import android.util.Log;
import java.util.ArrayDeque;
import java.util.Queue;
import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.RejectedExecutionException;
/**
* Created 9/27/2015 Anthony Restaino
*/
public class AsyncExecutor implements Executor {
private static final String TAG = AsyncExecutor.class.getSimpleName();
private static final AsyncExecutor INSTANCE = new AsyncExecutor();
private final Queue<Runnable> mQueue = new ArrayDeque<>(1);
private final ExecutorService mExecutor = Executors.newFixedThreadPool(4);
private AsyncExecutor() {}
public static AsyncExecutor getInstance() {
return INSTANCE;
}
public synchronized void notifyThreadFinish() {
if (mQueue.isEmpty()) {
return;
}
Runnable runnable = mQueue.remove();
execute(runnable);
}
@Override
protected void finalize() throws Throwable {
mExecutor.shutdownNow();
super.finalize();
}
@Override
public void execute(@NonNull Runnable command) {
try {
mExecutor.execute(command);
} catch (RejectedExecutionException ignored) {
mQueue.add(command);
Log.d(TAG, "Thread was enqueued");
}
}
}

57
app/src/main/java/acr/browser/lightning/utils/DownloadImageTask.java → app/src/main/java/acr/browser/lightning/async/ImageDownloadTask.java

@ -1,4 +1,4 @@ @@ -1,4 +1,4 @@
package acr.browser.lightning.utils;
package acr.browser.lightning.async;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
@ -11,33 +11,35 @@ import android.widget.ImageView; @@ -11,33 +11,35 @@ import android.widget.ImageView;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.lang.ref.WeakReference;
import java.net.HttpURLConnection;
import java.net.URL;
import acr.browser.lightning.app.BrowserApp;
import acr.browser.lightning.constant.Constants;
import acr.browser.lightning.database.HistoryItem;
import acr.browser.lightning.utils.Utils;
/**
* Created by Stefano Pacifici on 25/08/15.
*/
public class DownloadImageTask extends AsyncTask<Void, Void, Bitmap> {
public class ImageDownloadTask extends AsyncTask<Void, Void, Bitmap> {
final ImageView bmImage;
final HistoryItem mWeb;
final File mCacheDir;
final String mUrl;
final Bitmap mDefaultBitmap;
private static final String TAG = ImageDownloadTask.class.getSimpleName();
private static final File mCacheDir = BrowserApp.getAppContext().getCacheDir();
private final WeakReference<ImageView> bmImage;
private final HistoryItem mWeb;
private final String mUrl;
private final Bitmap mDefaultBitmap;
public DownloadImageTask(@NonNull ImageView bmImage, @NonNull HistoryItem web,
@NonNull Bitmap defaultBitmap) {
this.bmImage = bmImage;
public ImageDownloadTask(@NonNull ImageView bmImage, @NonNull HistoryItem web, @NonNull Bitmap defaultBitmap) {
// Set a tag on the ImageView so we know if the view
// has gone out of scope and should not be used
bmImage.setTag(web.getUrl().hashCode());
this.bmImage = new WeakReference<>(bmImage);
this.mWeb = web;
this.mCacheDir = BrowserApp.getAppContext().getCacheDir();
this.mUrl = web.getUrl();
this.mDefaultBitmap = defaultBitmap;
}
@Override
protected Bitmap doInBackground(Void... params) {
Bitmap mIcon = null;
// unique path for each url that is bookmarked.
@ -60,6 +62,8 @@ public class DownloadImageTask extends AsyncTask<Void, Void, Bitmap> { @@ -60,6 +62,8 @@ public class DownloadImageTask extends AsyncTask<Void, Void, Bitmap> {
final URL urlDownload = new URL(urlDisplay);
final HttpURLConnection connection = (HttpURLConnection) urlDownload.openConnection();
connection.setDoInput(true);
connection.setConnectTimeout(1000);
connection.setReadTimeout(1000);
connection.connect();
in = connection.getInputStream();
@ -74,8 +78,8 @@ public class DownloadImageTask extends AsyncTask<Void, Void, Bitmap> { @@ -74,8 +78,8 @@ public class DownloadImageTask extends AsyncTask<Void, Void, Bitmap> {
Log.d(Constants.TAG, "Downloaded: " + urlDisplay);
}
} catch (Exception e) {
e.printStackTrace();
} catch (Exception ignored) {
Log.d(TAG, "Could not download: " + urlDisplay);
} finally {
Utils.close(in);
Utils.close(fos);
@ -89,10 +93,11 @@ public class DownloadImageTask extends AsyncTask<Void, Void, Bitmap> { @@ -89,10 +93,11 @@ public class DownloadImageTask extends AsyncTask<Void, Void, Bitmap> {
FileOutputStream fos = null;
try {
// if not, download it...
final URL urlDownload = new URL("https://www.google.com/s2/favicons?domain_url="
+ uri.toString());
final URL urlDownload = new URL("https://www.google.com/s2/favicons?domain_url=" + uri.toString());
final HttpURLConnection connection = (HttpURLConnection) urlDownload.openConnection();
connection.setDoInput(true);
connection.setConnectTimeout(1000);
connection.setReadTimeout(1000);
connection.connect();
in = connection.getInputStream();
@ -107,7 +112,7 @@ public class DownloadImageTask extends AsyncTask<Void, Void, Bitmap> { @@ -107,7 +112,7 @@ public class DownloadImageTask extends AsyncTask<Void, Void, Bitmap> {
}
} catch (Exception e) {
e.printStackTrace();
Log.d(TAG, "Could not download Google favicon");
} finally {
Utils.close(in);
Utils.close(fos);
@ -120,10 +125,16 @@ public class DownloadImageTask extends AsyncTask<Void, Void, Bitmap> { @@ -120,10 +125,16 @@ public class DownloadImageTask extends AsyncTask<Void, Void, Bitmap> {
}
}
protected void onPostExecute(Bitmap result) {
final Bitmap fav = Utils.padFavicon(result);
bmImage.setImageBitmap(fav);
@Override
protected void onPostExecute(Bitmap bitmap) {
super.onPostExecute(bitmap);
AsyncExecutor.getInstance().notifyThreadFinish();
final Bitmap fav = Utils.padFavicon(bitmap);
ImageView view = bmImage.get();
if (view != null && view.getTag().equals(mWeb.getUrl().hashCode())) {
view.setImageBitmap(fav);
}
mWeb.setBitmap(fav);
// notifyBookmarkDataSetChanged();
}
}

14
app/src/main/java/acr/browser/lightning/constant/BookmarkPage.java

@ -20,7 +20,7 @@ import acr.browser.lightning.utils.Utils; @@ -20,7 +20,7 @@ import acr.browser.lightning.utils.Utils;
public final class BookmarkPage {
public static final String HEADING = "<!DOCTYPE html><html xmlns=http://www.w3.org/1999/xhtml>\n" +
private static final String HEADING = "<!DOCTYPE html><html xmlns=http://www.w3.org/1999/xhtml>\n" +
"<head>\n" +
"<meta content=en-us http-equiv=Content-Language />\n" +
"<meta content='text/html; charset=utf-8' http-equiv=Content-Type />\n" +
@ -33,21 +33,21 @@ public final class BookmarkPage { @@ -33,21 +33,21 @@ public final class BookmarkPage {
"width:130px;font-size: small;font-family: Arial, Helvetica, 'sans-serif';white-space:nowrap;overflow:hidden;text-align:left;vertical-align:middle;margin:auto;text-overflow:ellipsis;-o-text-overflow:ellipsis;-ms-text-overflow:ellipsis}.box a{width:100%;height:100%;position:absolute;left:0;top:0}img{vertical-align:middle;margin-right:10px;width:20px;height:20px;}.margin{margin:10px}</style>\n" +
"<body><div id=content>";
public static final String PART1 = "<div class=box><a href='";
private static final String PART1 = "<div class=box><a href='";
public static final String PART2 = "'></a>\n" +
private static final String PART2 = "'></a>\n" +
"<div class=margin>\n" +
"<div class=box-content>\n" +
"<p class=ellipses>\n" +
"<img src='";
public static final String PART3 = "http://www.google.com/s2/favicons?domain=";
private static final String PART3 = "http://www.google.com/s2/favicons?domain=";
public static final String PART4 = "' />";
private static final String PART4 = "' />";
public static final String PART5 = "</p></div></div></div>";
private static final String PART5 = "</p></div></div></div>";
public static final String END = "</div></body></html>";
private static final String END = "</div></body></html>";
@Inject
BookmarkManager manager;

4
app/src/main/java/acr/browser/lightning/constant/Constants.java

@ -3,8 +3,6 @@ @@ -3,8 +3,6 @@
*/
package acr.browser.lightning.constant;
import android.os.Environment;
import acr.browser.lightning.BuildConfig;
public final class Constants {
@ -27,8 +25,6 @@ public final class Constants { @@ -27,8 +25,6 @@ public final class Constants {
public static final String HOMEPAGE = "about:home";
public static final String BAIDU_SEARCH = "https://www.baidu.com/s?wd=";
public static final String YANDEX_SEARCH = "https://yandex.ru/yandsearch?lr=21411&text=";
public static final String EXTERNAL_STORAGE = Environment.getExternalStorageDirectory()
.toString();
public static final String JAVASCRIPT_INVERT_PAGE = "javascript:(function(){var e='img {-webkit-filter: invert(100%);'+'-moz-filter: invert(100%);'+'-o-filter: invert(100%);'+'-ms-filter: invert(100%); }',t=document.getElementsByTagName('head')[0],n=document.createElement('style');if(!window.counter){window.counter=1}else{window.counter++;if(window.counter%2==0){var e='html {-webkit-filter: invert(0%); -moz-filter: invert(0%); -o-filter: invert(0%); -ms-filter: invert(0%); }'}}n.type='text/css';if(n.styleSheet){n.styleSheet.cssText=e}else{n.appendChild(document.createTextNode(e))}t.appendChild(n)})();";
public static final String JAVASCRIPT_TEXT_REFLOW = "javascript:document.getElementsByTagName('body')[0].style.width=window.innerWidth+'px';";

8
app/src/main/java/acr/browser/lightning/constant/StartPage.java

@ -16,9 +16,9 @@ import acr.browser.lightning.utils.Utils; @@ -16,9 +16,9 @@ import acr.browser.lightning.utils.Utils;
public class StartPage {
public static final String FILENAME = "homepage.html";
private static final String FILENAME = "homepage.html";
public static final String HEAD = "<!DOCTYPE html><html xmlns=\"http://www.w3.org/1999/xhtml\">"
private static final String HEAD = "<!DOCTYPE html><html xmlns=\"http://www.w3.org/1999/xhtml\">"
+ "<head>"
+ "<meta content=\"en-us\" http-equiv=\"Content-Language\" />"
+ "<meta content=\"text/html; charset=utf-8\" http-equiv=\"Content-Type\" />"
@ -41,11 +41,11 @@ public class StartPage { @@ -41,11 +41,11 @@ public class StartPage {
+ "font-size: 12px;-moz-border-radius: 2px;-webkit-border-radius: 2px;"
+ "border-radius: 2px;}</style><body> <div class=\"outer\"><div class=\"middle\"><div class=\"inner\"><img class=\"smaller\" src=\"";
public static final String MIDDLE = "\" ></br></br><form onsubmit=\"return search()\" class=\"search_bar\">"
private static final String MIDDLE = "\" ></br></br><form onsubmit=\"return search()\" class=\"search_bar\">"
+ "<input type=\"submit\" id=\"search_submit\" value=\"Search\" ><span><input class=\"search\" type=\"text\" value=\"\" id=\"search_input\" >"
+ "</span></form></br></br></div></div></div><script type=\"text/javascript\">function search(){if(document.getElementById(\"search_input\").value != \"\"){window.location.href = \"";
public static final String END = "\" + document.getElementById(\"search_input\").value;document.getElementById(\"search_input\").value = \"\";}return false;}</script></body></html>";
private static final String END = "\" + document.getElementById(\"search_input\").value;document.getElementById(\"search_input\").value = \"\";}return false;}</script></body></html>";
/**
* This method builds the homepage and returns the local URL to be loaded

3
app/src/main/java/acr/browser/lightning/controller/BrowserController.java

@ -3,7 +3,6 @@ @@ -3,7 +3,6 @@
*/
package acr.browser.lightning.controller;
import android.app.Activity;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Message;
@ -38,8 +37,6 @@ public interface BrowserController { @@ -38,8 +37,6 @@ public interface BrowserController {
void onCloseWindow(LightningView view);
Activity getActivity();
void hideActionBar();
void showActionBar();

145
app/src/main/java/acr/browser/lightning/database/BookmarkLocalSync.java

@ -0,0 +1,145 @@ @@ -0,0 +1,145 @@
package acr.browser.lightning.database;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.annotation.WorkerThread;
import android.util.Log;
import java.util.ArrayList;
import java.util.List;
import acr.browser.lightning.utils.Utils;
public class BookmarkLocalSync {
private static final String TAG = BookmarkLocalSync.class.getSimpleName();
private static final String STOCK_BOOKMARKS_CONTENT = "content://browser/bookmarks";
private static final String CHROME_BOOKMARKS_CONTENT = "content://com.android.chrome.browser/bookmarks";
private static final String COLUMN_TITLE = "title";
private static final String COLUMN_URL = "url";
private static final String COLUMN_BOOKMARK = "bookmark";
private final Context mContext;
public BookmarkLocalSync(Context context) {
mContext = context;
}
@NonNull
@WorkerThread
public List<HistoryItem> getBookmarksFromStockBrowser() {
List<HistoryItem> list = new ArrayList<>();
if (!isStockSupported()) {
return list;
}
Cursor cursor = getStockCursor();
try {
if (cursor != null) {
for (int n = 0; n < cursor.getColumnCount(); n++) {
Log.d(TAG, cursor.getColumnName(n));
}
while (cursor.moveToNext()) {
if (cursor.getInt(2) == 1) {
String url = cursor.getString(0);
String title = cursor.getString(1);
if (url.isEmpty()) {
continue;
}
if (title == null || title.isEmpty()) {
title = Utils.getDomainName(url);
}
list.add(new HistoryItem(url, title));
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
Utils.close(cursor);
return list;
}
@NonNull
@WorkerThread
public List<HistoryItem> getBookmarksFromChrome() {
List<HistoryItem> list = new ArrayList<>();
if (!isChromeSupported()) {
return list;
}
Cursor cursor = getStockCursor();
try {
if (cursor != null) {
for (int n = 0; n < cursor.getColumnCount(); n++) {
Log.d(TAG, cursor.getColumnName(n));
}
while (cursor.moveToNext()) {
if (cursor.getInt(2) == 1) {
String url = cursor.getString(0);
String title = cursor.getString(1);
if (url.isEmpty()) {
continue;
}
if (title == null || title.isEmpty()) {
title = Utils.getDomainName(url);
}
list.add(new HistoryItem(url, title));
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
Utils.close(cursor);
return list;
}
@WorkerThread
public boolean isStockSupported() {
Cursor cursor = getStockCursor();
Utils.close(cursor);
return cursor != null;
}
@WorkerThread
public boolean isChromeSupported() {
Cursor cursor = getChromeCursor();
Utils.close(cursor);
return cursor != null;
}
@Nullable
@WorkerThread
private Cursor getChromeCursor() {
Cursor cursor;
Uri uri = Uri.parse(CHROME_BOOKMARKS_CONTENT);
try {
cursor = mContext.getContentResolver().query(uri,
new String[]{COLUMN_URL, COLUMN_TITLE, COLUMN_BOOKMARK}, null, null, null);
} catch (IllegalArgumentException e) {
return null;
}
return cursor;
}
@Nullable
@WorkerThread
private Cursor getStockCursor() {
Cursor cursor;
Uri uri = Uri.parse(STOCK_BOOKMARKS_CONTENT);
try {
cursor = mContext.getContentResolver().query(uri,
new String[]{COLUMN_URL, COLUMN_TITLE, COLUMN_BOOKMARK}, null, null, null);
} catch (IllegalArgumentException e) {
return null;
}
return cursor;
}
}

46
app/src/main/java/acr/browser/lightning/database/BookmarkManager.java

@ -66,7 +66,6 @@ public class BookmarkManager { @@ -66,7 +66,6 @@ public class BookmarkManager {
}
/**
*
* @return true if the BookmarkManager was initialized, false otherwise
*/
public boolean isReady() {
@ -75,8 +74,9 @@ public class BookmarkManager { @@ -75,8 +74,9 @@ public class BookmarkManager {
/**
* Look for bookmark using the url
* @param url the lookup url
* @return the bookmark as an {@link HistoryItem} or null
*
* @param url the lookup url
* @return the bookmark as an {@link HistoryItem} or null
*/
@Nullable
public HistoryItem findBookmarkForUrl(final String url) {
@ -87,7 +87,7 @@ public class BookmarkManager { @@ -87,7 +87,7 @@ public class BookmarkManager {
* Initialize the BookmarkManager, it's a one-time operation and will be executed asynchronously.
* When done, mReady flag will been set to true.
*/
private class BookmarkInitializer implements Runnable{
private class BookmarkInitializer implements Runnable {
private final Context mContext;
public BookmarkInitializer(Context context) {
@ -101,15 +101,14 @@ public class BookmarkManager { @@ -101,15 +101,14 @@ public class BookmarkManager {
final File bookmarksFile = new File(mFilesDir, FILE_BOOKMARKS);
BufferedReader bookmarksReader = null;
InputStream inputStream = null;
try {
final InputStream inputStream;
if (bookmarksFile.exists() && bookmarksFile.isFile()) {
inputStream = new FileInputStream(bookmarksFile);
} else {
inputStream = mContext.getResources().openRawResource(R.raw.default_bookmarks);
}
bookmarksReader =
new BufferedReader(new InputStreamReader(inputStream));
bookmarksReader = new BufferedReader(new InputStreamReader(inputStream));
String line;
while ((line = bookmarksReader.readLine()) != null) {
try {
@ -130,6 +129,7 @@ public class BookmarkManager { @@ -130,6 +129,7 @@ public class BookmarkManager {
Log.e(TAG, "Error reading the bookmarks file", e);
} finally {
Utils.close(bookmarksReader);
Utils.close(inputStream);
}
mBookmarksMap = bookmarks;
mReady = true;
@ -195,8 +195,8 @@ public class BookmarkManager { @@ -195,8 +195,8 @@ public class BookmarkManager {
* This method adds the the HistoryItem item to permanent bookmark storage.<br>
* This operation is blocking if the manager is still not ready.
*
* @param item the item to add
* @return It returns true if the operation was successful.
* @param item the item to add
* @return It returns true if the operation was successful.
*/
public synchronized boolean addBookmark(@NonNull HistoryItem item) {
final String url = item.getUrl();
@ -213,7 +213,7 @@ public class BookmarkManager { @@ -213,7 +213,7 @@ public class BookmarkManager {
*
* @param list the list of HistoryItems to add to bookmarks
*/
private synchronized void addBookmarkList(List<HistoryItem> list) {
public synchronized void addBookmarkList(List<HistoryItem> list) {
if (list == null || list.isEmpty()) {
return;
}
@ -251,7 +251,7 @@ public class BookmarkManager { @@ -251,7 +251,7 @@ public class BookmarkManager {
if (newName.isEmpty()) {
return;
}
for (HistoryItem item: mBookmarksMap.values()) {
for (HistoryItem item : mBookmarksMap.values()) {
if (item.getFolder().equals(oldName)) {
item.setFolder(newName);
} else if (item.isFolder() && item.getTitle().equals(oldName)) {
@ -269,7 +269,7 @@ public class BookmarkManager { @@ -269,7 +269,7 @@ public class BookmarkManager {
*/
public synchronized void deleteFolder(@NonNull String name) {
final Map<String, HistoryItem> bookmarks = new HashMap<>();
for (HistoryItem item: mBookmarksMap.values()) {
for (HistoryItem item : mBookmarksMap.values()) {
final String url = item.getUrl();
if (item.isFolder()) {
if (!item.getTitle().equals(name)) {
@ -357,8 +357,7 @@ public class BookmarkManager { @@ -357,8 +357,7 @@ public class BookmarkManager {
* This is a disk-bound operation and should not be
* done very frequently.
*
* @param sort force to sort the returned bookmarkList
*
* @param sort force to sort the returned bookmarkList
* @return returns a list of bookmarks that can be sorted
*/
public synchronized List<HistoryItem> getAllBookmarks(boolean sort) {
@ -385,7 +384,7 @@ public class BookmarkManager { @@ -385,7 +384,7 @@ public class BookmarkManager {
folder = "";
}
mCurrentFolder = folder;
for (HistoryItem item: mBookmarksMap.values()) {
for (HistoryItem item : mBookmarksMap.values()) {
if (item.getFolder().equals(folder))
bookmarks.add(item);
}
@ -404,6 +403,15 @@ public class BookmarkManager { @@ -404,6 +403,15 @@ public class BookmarkManager {
return mCurrentFolder.isEmpty();
}
/**
* Returns the current folder
*
* @return the current folder
*/
public String getCurrentFolder() {
return mCurrentFolder;
}
/**
* Method is used internally for searching the bookmarks
*
@ -411,7 +419,7 @@ public class BookmarkManager { @@ -411,7 +419,7 @@ public class BookmarkManager {
*/
private Set<String> getBookmarkUrls(List<HistoryItem> list) {
Set<String> set = new HashSet<>();
for (HistoryItem item: mBookmarksMap.values()) {
for (HistoryItem item : mBookmarksMap.values()) {
if (!item.isFolder())
set.add(item.getUrl());
}
@ -425,9 +433,9 @@ public class BookmarkManager { @@ -425,9 +433,9 @@ public class BookmarkManager {
*
* @return a list of all folders
*/
public synchronized List<HistoryItem> getFolders(boolean sort) {
private synchronized List<HistoryItem> getFolders(boolean sort) {
final HashMap<String, HistoryItem> folders = new HashMap<>();
for (HistoryItem item: mBookmarksMap.values()) {
for (HistoryItem item : mBookmarksMap.values()) {
final String folderName = item.getFolder();
if (folderName != null && !folderName.isEmpty() && !folders.containsKey(folderName)) {
final HistoryItem folder = new HistoryItem();
@ -453,7 +461,7 @@ public class BookmarkManager { @@ -453,7 +461,7 @@ public class BookmarkManager {
*/
public synchronized List<String> getFolderTitles() {
final Set<String> folders = new HashSet<>();
for (HistoryItem item: mBookmarksMap.values()) {
for (HistoryItem item : mBookmarksMap.values()) {
final String folderName = item.getFolder();
if (folderName != null && !folderName.isEmpty()) {
folders.add(folderName);

18
app/src/main/java/acr/browser/lightning/database/HistoryDatabase.java

@ -26,7 +26,7 @@ public class HistoryDatabase extends SQLiteOpenHelper { @@ -26,7 +26,7 @@ public class HistoryDatabase extends SQLiteOpenHelper {
private static final int DATABASE_VERSION = 2;
// Database Name
public static final String DATABASE_NAME = "historyManager";
private static final String DATABASE_NAME = "historyManager";
// HistoryItems table name
private static final String TABLE_HISTORY = "history";
@ -158,7 +158,6 @@ public class HistoryDatabase extends SQLiteOpenHelper { @@ -158,7 +158,6 @@ public class HistoryDatabase extends SQLiteOpenHelper {
if (cursor.moveToFirst()) {
do {
HistoryItem item = new HistoryItem();
item.setID(Integer.parseInt(cursor.getString(0)));
item.setUrl(cursor.getString(1));
item.setTitle(cursor.getString(2));
item.setImageId(R.drawable.ic_history);
@ -183,7 +182,6 @@ public class HistoryDatabase extends SQLiteOpenHelper { @@ -183,7 +182,6 @@ public class HistoryDatabase extends SQLiteOpenHelper {
if (cursor.moveToFirst()) {
do {
HistoryItem item = new HistoryItem();
item.setID(Integer.parseInt(cursor.getString(0)));
item.setUrl(cursor.getString(1));
item.setTitle(cursor.getString(2));
item.setImageId(R.drawable.ic_history);
@ -208,7 +206,6 @@ public class HistoryDatabase extends SQLiteOpenHelper { @@ -208,7 +206,6 @@ public class HistoryDatabase extends SQLiteOpenHelper {
if (cursor.moveToFirst()) {
do {
HistoryItem item = new HistoryItem();
item.setID(Integer.parseInt(cursor.getString(0)));
item.setUrl(cursor.getString(1));
item.setTitle(cursor.getString(2));
item.setImageId(R.drawable.ic_history);
@ -220,19 +217,6 @@ public class HistoryDatabase extends SQLiteOpenHelper { @@ -220,19 +217,6 @@ public class HistoryDatabase extends SQLiteOpenHelper {
return itemList;
}
public synchronized int updateHistoryItem(HistoryItem item) {
mLock = true;
openIfNecessary();
ContentValues values = new ContentValues();
values.put(KEY_URL, item.getUrl());
values.put(KEY_TITLE, item.getTitle());
values.put(KEY_TIME_VISITED, System.currentTimeMillis());
int update = mDatabase.update(TABLE_HISTORY, values, KEY_ID + " = ?",
new String[]{String.valueOf(item.getId())});
mLock = false;
return update;
}
public int getHistoryItemsCount() {
mLock = true;
openIfNecessary();

74
app/src/main/java/acr/browser/lightning/database/HistoryItem.java

@ -5,23 +5,29 @@ package acr.browser.lightning.database; @@ -5,23 +5,29 @@ package acr.browser.lightning.database;
import android.graphics.Bitmap;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
public class HistoryItem implements Comparable<HistoryItem> {
// private variables
private int mId = 0;
@NonNull
private String mUrl = "";
@NonNull
private String mTitle = "";
@NonNull
private String mFolder = "";
@Nullable
private Bitmap mBitmap = null;
private int mImageId = 0;
private int mOrder = 0;
private boolean mIsFolder = false;
// Empty constructor
public HistoryItem() {
}
public HistoryItem() {}
public HistoryItem(HistoryItem item) {
this.mUrl = item.mUrl;
@ -32,42 +38,24 @@ public class HistoryItem implements Comparable<HistoryItem> { @@ -32,42 +38,24 @@ public class HistoryItem implements Comparable<HistoryItem> {
}
// constructor
public HistoryItem(int id, String url, String title) {
this.mId = id;
this.mUrl = url;
this.mTitle = title;
this.mBitmap = null;
}
// constructor
public HistoryItem(String url, String title) {
public HistoryItem(@NonNull String url, @NonNull String title) {
this.mUrl = url;
this.mTitle = title;
this.mBitmap = null;
}
// constructor
public HistoryItem(String url, String title, int imageId) {
public HistoryItem(@NonNull String url, @NonNull String title, int imageId) {
this.mUrl = url;
this.mTitle = title;
this.mBitmap = null;
this.mImageId = imageId;
}
// getting ID
public int getId() {
return this.mId;
}
public int getImageId() {
return this.mImageId;
}
// setting id
public void setID(int id) {
this.mId = id;
}
public void setImageId(int id) {
this.mImageId = id;
}
@ -131,40 +119,34 @@ public class HistoryItem implements Comparable<HistoryItem> { @@ -131,40 +119,34 @@ public class HistoryItem implements Comparable<HistoryItem> {
@Override
public int compareTo(@NonNull HistoryItem another) {
return mTitle.compareTo(another.mTitle);
int compare = this.mTitle.compareTo(another.mTitle);
if (compare == 0) {
return this.mUrl.compareTo(another.mUrl);
}
return compare;
}
@Override
public boolean equals(Object o) {
public boolean equals(Object object) {
if (this == o) {
return true;
}
if (o == null || ((Object) this).getClass() != o.getClass()) {
return false;
}
if (this == object) return true;
if (object == null) return false;
if (!(object instanceof HistoryItem)) return false;
HistoryItem that = (HistoryItem) o;
HistoryItem that = (HistoryItem) object;
if (mId != that.mId) {
return false;
}
if (mImageId != that.mImageId) {
return false;
}
if (mBitmap != null ? !mBitmap.equals(that.mBitmap) : that.mBitmap != null) {
return false;
}
return mTitle.equals(that.mTitle) && mUrl.equals(that.mUrl);
return mImageId == that.mImageId &&
this.mTitle.equals(that.mTitle) && this.mUrl.equals(that.mUrl) &&
this.mFolder.equals(that.mFolder);
}
@Override
public int hashCode() {
int result = mId;
result = 31 * result + mUrl.hashCode();
int result = mUrl.hashCode();
result = 31 * result + mImageId;
result = 31 * result + mTitle.hashCode();
result = 31 * result + (mBitmap != null ? mBitmap.hashCode() : 0);
result = 32 * result + mFolder.hashCode();
result = 31 * result + mImageId;
return result;

4
app/src/main/java/acr/browser/lightning/dialog/LightningDialogBuilder.java

@ -114,7 +114,7 @@ public class LightningDialogBuilder { @@ -114,7 +114,7 @@ public class LightningDialogBuilder {
.show();
}
public void showEditBookmarkDialog(final Context context, final HistoryItem item) {
private void showEditBookmarkDialog(final Context context, final HistoryItem item) {
final AlertDialog.Builder editBookmarkDialog = new AlertDialog.Builder(context);
editBookmarkDialog.setTitle(R.string.title_edit_bookmark);
final View dialogLayout = View.inflate(context, R.layout.dialog_edit_bookmark, null);
@ -178,7 +178,7 @@ public class LightningDialogBuilder { @@ -178,7 +178,7 @@ public class LightningDialogBuilder {
.show();
}
public void showRenameFolderDialog(final Context context, final HistoryItem item) {
private void showRenameFolderDialog(final Context context, final HistoryItem item) {
// assert item.isFolder();
final AlertDialog.Builder editFolderDialog = new AlertDialog.Builder(context);
editFolderDialog.setTitle(R.string.title_rename_folder);

140
app/src/main/java/acr/browser/lightning/download/DownloadHandler.java

@ -19,8 +19,12 @@ import android.util.Log; @@ -19,8 +19,12 @@ import android.util.Log;
import android.webkit.CookieManager;
import android.webkit.URLUtil;
import java.io.File;
import java.io.IOException;
import acr.browser.lightning.R;
import acr.browser.lightning.app.BrowserApp;
import acr.browser.lightning.constant.Constants;
import acr.browser.lightning.preference.PreferenceManager;
import acr.browser.lightning.utils.Utils;
@ -29,7 +33,12 @@ import acr.browser.lightning.utils.Utils; @@ -29,7 +33,12 @@ import acr.browser.lightning.utils.Utils;
*/
public class DownloadHandler {
private static final String LOGTAG = "DLHandler";
private static final String TAG = DownloadHandler.class.getSimpleName();
private static final String COOKIE_REQUEST_HEADER = "Cookie";
public static final String DEFAULT_DOWNLOAD_PATH =
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS)
.getPath();
/**
@ -153,7 +162,8 @@ public class DownloadHandler { @@ -153,7 +162,8 @@ public class DownloadHandler {
} catch (Exception e) {
// This only happens for very bad urls, we want to catch the
// exception here
Log.e(LOGTAG, "Exception while trying to parse url '" + url + '\'', e);
Log.e(TAG, "Exception while trying to parse url '" + url + '\'', e);
Utils.showSnackbar(activity, R.string.problem_download);
return;
}
@ -172,15 +182,37 @@ public class DownloadHandler { @@ -172,15 +182,37 @@ public class DownloadHandler {
// depending on mimetype?
String location = BrowserApp.getAppComponent().getPreferenceManager().getDownloadDirectory();
request.setDestinationInExternalPublicDir(location, filename);
Uri downloadFolder;
if (location != null) {
location = addNecessarySlashes(location);
downloadFolder = Uri.parse(location);
} else {
location = addNecessarySlashes(DEFAULT_DOWNLOAD_PATH);
downloadFolder = Uri.parse(location);
BrowserApp.getAppComponent().getPreferenceManager().setDownloadDirectory(location);
}
File dir = new File(downloadFolder.getPath());
if (!dir.isDirectory() && !dir.mkdirs()) {
// Cannot make the directory
Utils.showSnackbar(activity, R.string.problem_location_download);
return;
}
if (!isWriteAccessAvailable(downloadFolder)) {
Utils.showSnackbar(activity, R.string.problem_location_download);
return;
}
request.setDestinationUri(Uri.parse(Constants.FILE + location + filename));
// let this downloaded file be scanned by MediaScanner - so that it can
// show up in Gallery app, for example.
request.setVisibleInDownloadsUi(true);
request.allowScanningByMediaScanner();
request.setDescription(webAddress.getHost());
// XXX: Have to use the old url since the cookies were stored using the
// old percent-encoded url.
String cookies = CookieManager.getInstance().getCookie(url);
request.addRequestHeader("cookie", cookies);
request.addRequestHeader(COOKIE_REQUEST_HEADER, cookies);
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
if (mimetype == null) {
if (TextUtils.isEmpty(addressString)) {
@ -192,7 +224,7 @@ public class DownloadHandler { @@ -192,7 +224,7 @@ public class DownloadHandler {
} else {
final DownloadManager manager = (DownloadManager) activity
.getSystemService(Context.DOWNLOAD_SERVICE);
new Thread("Browser download") {
new Thread() {
@Override
public void run() {
try {
@ -201,11 +233,107 @@ public class DownloadHandler { @@ -201,11 +233,107 @@ public class DownloadHandler {
// Probably got a bad URL or something
e.printStackTrace();
Utils.showSnackbar(activity, R.string.cannot_download);
} catch (SecurityException e) {
// TODO write a download utility that downloads files rather than rely on the system
// because the system can only handle Environment.getExternal... as a path
Utils.showSnackbar(activity, R.string.problem_location_download);
}
}
}.start();
Utils.showSnackbar(activity, R.string.download_pending);
Utils.showSnackbar(activity, activity.getString(R.string.download_pending) + ' ' + filename);
}
}
private static final String sFileName = "test";
private static final String sFileExtension = ".txt";
/**
* Determine whether there is write access in the given directory. Returns false if a
* file cannot be created in the directory or if the directory does not exist.
*
* @param directory the directory to check for write access
* @return returns true if the directory can be written to or is in a directory that can
* be written to. false if there is no write access.
*/
public static boolean isWriteAccessAvailable(String directory) {
if (directory == null || directory.isEmpty()) {
return false;
}
String dir = addNecessarySlashes(directory);
dir = getFirstRealParentDirectory(dir);
File file = new File(dir + sFileName + sFileExtension);
for (int n = 0; n < 100; n++) {
if (!file.exists()) {
try {
if (file.createNewFile()) {
file.delete();
}
return true;
} catch (IOException ignored) {
return false;
}
} else {
file = new File(dir + sFileName + '-' + n + sFileExtension);
}
}
return file.canWrite();
}
/**
* Returns the first parent directory of a directory that exists. This is useful
* for subdirectories that do not exist but their parents do.
*
* @param directory the directory to find the first existent parent
* @return the first existent parent
*/
private static String getFirstRealParentDirectory(String directory) {
if (directory == null || directory.isEmpty()) {
return "/";
}
directory = addNecessarySlashes(directory);
File file = new File(directory);
if (!file.isDirectory()) {
int indexSlash = directory.lastIndexOf('/');
if (indexSlash > 0) {
String parent = directory.substring(0, indexSlash);
int previousIndex = parent.lastIndexOf('/');
if (previousIndex > 0) {
return getFirstRealParentDirectory(parent.substring(0, previousIndex));
} else {
return "/";
}
} else {
return "/";
}
} else {
return directory;
}
}
private static boolean isWriteAccessAvailable(Uri fileUri) {
File file = new File(fileUri.getPath());
try {
if (file.createNewFile()) {
file.delete();
}
return true;
} catch (IOException ignored) {
return false;
}
}
public static String addNecessarySlashes(String originalPath) {
if (originalPath == null || originalPath.length() == 0) {
return "/";
}
if (originalPath.charAt(originalPath.length() - 1) != '/') {
originalPath = originalPath + '/';
}
if (originalPath.charAt(0) != '/') {
originalPath = '/' + originalPath;
}
return originalPath;
}
}

13
app/src/main/java/acr/browser/lightning/download/FetchUrlMimeType.java

@ -25,9 +25,9 @@ import acr.browser.lightning.utils.Utils; @@ -25,9 +25,9 @@ import acr.browser.lightning.utils.Utils;
* just clicks on the link, we will do the same steps of correcting the mimetype
* down in android.os.webkit.LoadListener rather than handling it here.
*/
public class FetchUrlMimeType extends Thread {
class FetchUrlMimeType extends Thread {
private final Context mContext;
private final Activity mActivity;
private final DownloadManager.Request mRequest;
@ -39,12 +39,11 @@ public class FetchUrlMimeType extends Thread { @@ -39,12 +39,11 @@ public class FetchUrlMimeType extends Thread {
public FetchUrlMimeType(Activity activity, DownloadManager.Request request, String uri,
String cookies, String userAgent) {
mContext = activity.getApplicationContext();
mActivity = activity;
mRequest = request;
mUri = uri;
mCookies = cookies;
mUserAgent = userAgent;
Utils.showSnackbar(activity, R.string.download_pending);
}
@Override
@ -87,6 +86,7 @@ public class FetchUrlMimeType extends Thread { @@ -87,6 +86,7 @@ public class FetchUrlMimeType extends Thread {
connection.disconnect();
}
String filename = "";
if (mimeType != null) {
if (mimeType.equalsIgnoreCase("text/plain")
|| mimeType.equalsIgnoreCase("application/octet-stream")) {
@ -96,13 +96,14 @@ public class FetchUrlMimeType extends Thread { @@ -96,13 +96,14 @@ public class FetchUrlMimeType extends Thread {
mRequest.setMimeType(newMimeType);
}
}
String filename = URLUtil.guessFileName(mUri, contentDisposition, mimeType);
filename = URLUtil.guessFileName(mUri, contentDisposition, mimeType);
mRequest.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, filename);
}
// Start the download
DownloadManager manager = (DownloadManager) mContext
DownloadManager manager = (DownloadManager) mActivity
.getSystemService(Context.DOWNLOAD_SERVICE);
manager.enqueue(mRequest);
Utils.showSnackbar(mActivity, mActivity.getString(R.string.download_pending) + ' ' + filename);
}
}

26
app/src/main/java/acr/browser/lightning/download/WebAddress.java

@ -3,6 +3,8 @@ @@ -3,6 +3,8 @@
*/
package acr.browser.lightning.download;
import android.support.annotation.NonNull;
import java.util.Locale;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@ -11,28 +13,28 @@ import static android.util.Patterns.GOOD_IRI_CHAR; @@ -11,28 +13,28 @@ import static android.util.Patterns.GOOD_IRI_CHAR;
/**
* Web Address Parser
*
* <p/>
* This is called WebAddress, rather than URL or URI, because it attempts to
* parse the stuff that a user will actually type into a browser address widget.
*
* <p/>
* Unlike java.net.uri, this parser will not choke on URIs missing schemes. It
* will only throw a ParseException if the input is really hosed.
*
* <p/>
* If given an https scheme but no port, fills in port
*/
public class WebAddress {
class WebAddress {
private String mScheme;
private String mHost;
private int mPort;
private String mPath;
private String mAuthInfo;
static final int MATCH_GROUP_SCHEME = 1;
static final int MATCH_GROUP_AUTHORITY = 2;
static final int MATCH_GROUP_HOST = 3;
static final int MATCH_GROUP_PORT = 4;
static final int MATCH_GROUP_PATH = 5;
static final Pattern sAddressPattern = Pattern.compile(
private static final int MATCH_GROUP_SCHEME = 1;
private static final int MATCH_GROUP_AUTHORITY = 2;
private static final int MATCH_GROUP_HOST = 3;
private static final int MATCH_GROUP_PORT = 4;
private static final int MATCH_GROUP_PATH = 5;
private static final Pattern sAddressPattern = Pattern.compile(
/* scheme */"(?:(http|https|file)\\:\\/\\/)?" +
/* authority */"(?:([-A-Za-z0-9$_.+!*'(),;?&=]+(?:\\:[-A-Za-z0-9$_.+!*'(),;?&=]+)?)@)?" +
/* host */"([" + GOOD_IRI_CHAR + "%_-][" + GOOD_IRI_CHAR + "%_\\.-]*|\\[[0-9a-fA-F:\\.]+\\])?" +
@ -43,7 +45,7 @@ public class WebAddress { @@ -43,7 +45,7 @@ public class WebAddress {
/**
* Parses given URI-like string.
*/
public WebAddress(String address) {
public WebAddress(String address) throws IllegalArgumentException {
if (address == null) {
throw new IllegalArgumentException("address can't be null");
@ -134,7 +136,7 @@ public class WebAddress { @@ -134,7 +136,7 @@ public class WebAddress {
return mScheme;
}
public void setHost(String host) {
public void setHost(@NonNull String host) {
mHost = host;
}

60
app/src/main/java/acr/browser/lightning/fragment/AdvancedSettingsFragment.java

@ -8,7 +8,6 @@ import android.content.DialogInterface; @@ -8,7 +8,6 @@ import android.content.DialogInterface;
import android.os.Bundle;
import android.preference.CheckBoxPreference;
import android.preference.Preference;
import android.preference.PreferenceFragment;
import android.support.v7.app.AlertDialog;
import java.util.Arrays;
@ -16,7 +15,6 @@ import java.util.List; @@ -16,7 +15,6 @@ import java.util.List;
import acr.browser.lightning.R;
import acr.browser.lightning.constant.Constants;
import acr.browser.lightning.preference.PreferenceManager;
public class AdvancedSettingsFragment extends LightningPreferenceFragment implements Preference.OnPreferenceClickListener, Preference.OnPreferenceChangeListener {
@ -62,7 +60,7 @@ public class AdvancedSettingsFragment extends LightningPreferenceFragment implem @@ -62,7 +60,7 @@ public class AdvancedSettingsFragment extends LightningPreferenceFragment implem
cbcookiesInkognito.setOnPreferenceChangeListener(this);
cbrestoreTabs.setOnPreferenceChangeListener(this);
switch (preferenceManager.getRenderingMode()) {
switch (mPreferenceManager.getRenderingMode()) {
case 0:
renderingmode.setSummary(getString(R.string.name_normal));
break;
@ -77,16 +75,16 @@ public class AdvancedSettingsFragment extends LightningPreferenceFragment implem @@ -77,16 +75,16 @@ public class AdvancedSettingsFragment extends LightningPreferenceFragment implem
break;
}
textEncoding.setSummary(preferenceManager.getTextEncoding());
textEncoding.setSummary(mPreferenceManager.getTextEncoding());
mUrlOptions = getResources().getStringArray(R.array.url_content_array);
int option = preferenceManager.getUrlBoxContentChoice();
int option = mPreferenceManager.getUrlBoxContentChoice();
urlcontent.setSummary(mUrlOptions[option]);
cbAllowPopups.setChecked(preferenceManager.getPopupsEnabled());
cbenablecookies.setChecked(preferenceManager.getCookiesEnabled());
cbcookiesInkognito.setChecked(preferenceManager.getIncognitoCookiesEnabled());
cbrestoreTabs.setChecked(preferenceManager.getRestoreLostTabsEnabled());
cbAllowPopups.setChecked(mPreferenceManager.getPopupsEnabled());
cbenablecookies.setChecked(mPreferenceManager.getCookiesEnabled());
cbcookiesInkognito.setChecked(mPreferenceManager.getIncognitoCookiesEnabled());
cbrestoreTabs.setChecked(mPreferenceManager.getRestoreLostTabsEnabled());
}
@Override
@ -111,19 +109,19 @@ public class AdvancedSettingsFragment extends LightningPreferenceFragment implem @@ -111,19 +109,19 @@ public class AdvancedSettingsFragment extends LightningPreferenceFragment implem
// switch preferences
switch (preference.getKey()) {
case SETTINGS_NEWWINDOW:
preferenceManager.setPopupsEnabled((Boolean) newValue);
mPreferenceManager.setPopupsEnabled((Boolean) newValue);
cbAllowPopups.setChecked((Boolean) newValue);
return true;
case SETTINGS_ENABLECOOKIES:
preferenceManager.setCookiesEnabled((Boolean) newValue);
mPreferenceManager.setCookiesEnabled((Boolean) newValue);
cbenablecookies.setChecked((Boolean) newValue);
return true;
case SETTINGS_COOKIESINKOGNITO:
preferenceManager.setIncognitoCookiesEnabled((Boolean) newValue);
mPreferenceManager.setIncognitoCookiesEnabled((Boolean) newValue);
cbcookiesInkognito.setChecked((Boolean) newValue);
return true;
case SETTINGS_RESTORETABS:
preferenceManager.setRestoreLostTabsEnabled((Boolean) newValue);
mPreferenceManager.setRestoreLostTabsEnabled((Boolean) newValue);
cbrestoreTabs.setChecked((Boolean) newValue);
return true;
default:
@ -139,12 +137,12 @@ public class AdvancedSettingsFragment extends LightningPreferenceFragment implem @@ -139,12 +137,12 @@ public class AdvancedSettingsFragment extends LightningPreferenceFragment implem
mActivity.getString(R.string.name_grayscale),
mActivity.getString(R.string.name_inverted_grayscale)};
int n = preferenceManager.getRenderingMode();
int n = mPreferenceManager.getRenderingMode();
picker.setSingleChoiceItems(chars, n, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
preferenceManager.setRenderingMode(which);
mPreferenceManager.setRenderingMode(which);
switch (which) {
case 0:
renderingmode.setSummary(getString(R.string.name_normal));
@ -161,13 +159,7 @@ public class AdvancedSettingsFragment extends LightningPreferenceFragment implem @@ -161,13 +159,7 @@ public class AdvancedSettingsFragment extends LightningPreferenceFragment implem
}
}
});
picker.setNeutralButton(getResources().getString(R.string.action_ok),
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
}
});
picker.setNeutralButton(getResources().getString(R.string.action_ok), null);
picker.show();
}
@ -175,22 +167,16 @@ public class AdvancedSettingsFragment extends LightningPreferenceFragment implem @@ -175,22 +167,16 @@ public class AdvancedSettingsFragment extends LightningPreferenceFragment implem
AlertDialog.Builder picker = new AlertDialog.Builder(mActivity);
picker.setTitle(getResources().getString(R.string.text_encoding));
final List<String> textEncodingList = Arrays.asList(Constants.TEXT_ENCODINGS);
int n = textEncodingList.indexOf(preferenceManager.getTextEncoding());
int n = textEncodingList.indexOf(mPreferenceManager.getTextEncoding());
picker.setSingleChoiceItems(Constants.TEXT_ENCODINGS, n, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
preferenceManager.setTextEncoding(Constants.TEXT_ENCODINGS[which]);
mPreferenceManager.setTextEncoding(Constants.TEXT_ENCODINGS[which]);
textEncoding.setSummary(Constants.TEXT_ENCODINGS[which]);
}
});
picker.setNeutralButton(getResources().getString(R.string.action_ok),
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
}
});
picker.setNeutralButton(getResources().getString(R.string.action_ok), null);
picker.show();
}
@ -198,24 +184,18 @@ public class AdvancedSettingsFragment extends LightningPreferenceFragment implem @@ -198,24 +184,18 @@ public class AdvancedSettingsFragment extends LightningPreferenceFragment implem
AlertDialog.Builder picker = new AlertDialog.Builder(mActivity);
picker.setTitle(getResources().getString(R.string.url_contents));
int n = preferenceManager.getUrlBoxContentChoice();
int n = mPreferenceManager.getUrlBoxContentChoice();
picker.setSingleChoiceItems(mUrlOptions, n, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
preferenceManager.setUrlBoxContentChoice(which);
mPreferenceManager.setUrlBoxContentChoice(which);
if (which < mUrlOptions.length) {
urlcontent.setSummary(mUrlOptions[which]);
}
}
});
picker.setNeutralButton(getResources().getString(R.string.action_ok),
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
}
});
picker.setNeutralButton(getResources().getString(R.string.action_ok), null);
picker.show();
}
}

62
app/src/main/java/acr/browser/lightning/fragment/BookmarkSettingsFragment.java

@ -6,6 +6,7 @@ package acr.browser.lightning.fragment; @@ -6,6 +6,7 @@ package acr.browser.lightning.fragment;
import android.Manifest;
import android.app.Activity;
import android.content.DialogInterface;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
@ -16,29 +17,64 @@ import android.support.v7.app.AlertDialog; @@ -16,29 +17,64 @@ import android.support.v7.app.AlertDialog;
import java.io.File;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import javax.inject.Inject;
import acr.browser.lightning.R;
import acr.browser.lightning.app.BrowserApp;
import acr.browser.lightning.database.BookmarkLocalSync;
import acr.browser.lightning.database.BookmarkManager;
import acr.browser.lightning.database.HistoryItem;
import acr.browser.lightning.utils.PermissionsManager;
import acr.browser.lightning.utils.Utils;
public class BookmarkSettingsFragment extends PreferenceFragment implements Preference.OnPreferenceClickListener {
private static final String SETTINGS_EXPORT = "export_bookmark";
private static final String SETTINGS_IMPORT = "import_bookmark";
private static final String SETTINGS_IMPORT_BROWSER = "import_browser";
private Activity mActivity;
@Inject BookmarkManager mBookmarkManager;
@Inject
BookmarkManager mBookmarkManager;
private File[] mFileList;
private String[] mFileNameList;
private BookmarkLocalSync mSync;
private static final String[] REQUIRED_PERMISSIONS = new String[]{
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.WRITE_EXTERNAL_STORAGE
};
private static final File mPath = new File(Environment.getExternalStorageDirectory().toString());
private class ImportBookmarksTask extends AsyncTask<Void, Void, Integer> {
@Override
protected Integer doInBackground(Void... params) {
List<HistoryItem> list = null;
if (mSync.isStockSupported()) {
list = mSync.getBookmarksFromStockBrowser();
} else if (mSync.isChromeSupported()) {
list = mSync.getBookmarksFromChrome();
}
int count = 0;
if (list != null && !list.isEmpty()) {
mBookmarkManager.addBookmarkList(list);
count = list.size();
}
return count;
}
@Override
protected void onPostExecute(Integer num) {
super.onPostExecute(num);
if (mActivity != null) {
int number = num;
final String message = mActivity.getResources().getString(R.string.message_import);
Utils.showSnackbar(mActivity, number + " " + message);
}
}
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@ -56,15 +92,34 @@ public class BookmarkSettingsFragment extends PreferenceFragment implements Pref @@ -56,15 +92,34 @@ public class BookmarkSettingsFragment extends PreferenceFragment implements Pref
}
}
@Override
public void onDestroy() {
super.onDestroy();
mActivity = null;
}
private void initPrefs() {
Preference exportpref = findPreference(SETTINGS_EXPORT);
Preference importpref = findPreference(SETTINGS_IMPORT);
mSync = new BookmarkLocalSync(mActivity);
exportpref.setOnPreferenceClickListener(this);
importpref.setOnPreferenceClickListener(this);
new Thread(mInitializeImportPreference).start();
}
private final Runnable mInitializeImportPreference = new Runnable() {
@Override
public void run() {
Preference importStock = findPreference(SETTINGS_IMPORT_BROWSER);
importStock.setEnabled(mSync.isStockSupported() || mSync.isChromeSupported());
importStock.setOnPreferenceClickListener(BookmarkSettingsFragment.this);
}
};
@Override
public boolean onPreferenceClick(Preference preference) {
switch (preference.getKey()) {
@ -79,6 +134,9 @@ public class BookmarkSettingsFragment extends PreferenceFragment implements Pref @@ -79,6 +134,9 @@ public class BookmarkSettingsFragment extends PreferenceFragment implements Pref
createDialog();
}
return true;
case SETTINGS_IMPORT_BROWSER:
new ImportBookmarksTask().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
return true;
default:
return false;
}
@ -114,7 +172,7 @@ public class BookmarkSettingsFragment extends PreferenceFragment implements Pref @@ -114,7 +172,7 @@ public class BookmarkSettingsFragment extends PreferenceFragment implements Pref
}
}
private class SortName implements Comparator<File> {
private static class SortName implements Comparator<File> {
@Override
public int compare(File a, File b) {

93
app/src/main/java/acr/browser/lightning/fragment/BookmarksFragment.java

@ -3,7 +3,6 @@ package acr.browser.lightning.fragment; @@ -3,7 +3,6 @@ package acr.browser.lightning.fragment;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.PorterDuff;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.annotation.IdRes;
import android.support.annotation.NonNull;
@ -38,13 +37,14 @@ import javax.inject.Inject; @@ -38,13 +37,14 @@ import javax.inject.Inject;
import acr.browser.lightning.R;
import acr.browser.lightning.activity.BrowserActivity;
import acr.browser.lightning.app.BrowserApp;
import acr.browser.lightning.async.AsyncExecutor;
import acr.browser.lightning.bus.BookmarkEvents;
import acr.browser.lightning.bus.BrowserEvents;
import acr.browser.lightning.database.BookmarkManager;
import acr.browser.lightning.database.HistoryItem;
import acr.browser.lightning.dialog.LightningDialogBuilder;
import acr.browser.lightning.preference.PreferenceManager;
import acr.browser.lightning.utils.DownloadImageTask;
import acr.browser.lightning.async.ImageDownloadTask;
import acr.browser.lightning.utils.ThemeUtils;
/**
@ -58,14 +58,14 @@ public class BookmarksFragment extends Fragment implements View.OnClickListener, @@ -58,14 +58,14 @@ public class BookmarksFragment extends Fragment implements View.OnClickListener,
// Event bus
@Inject
Bus eventBus;
Bus mEventBus;
// Dialog builder
@Inject
LightningDialogBuilder bookmarksDialogBuilder;
LightningDialogBuilder mBookmarksDialogBuilder;
@Inject
PreferenceManager preferenceManager;
PreferenceManager mPreferenceManager;
// Adapter
private BookmarkViewAdapter mBookmarkAdapter;
@ -81,10 +81,10 @@ public class BookmarksFragment extends Fragment implements View.OnClickListener, @@ -81,10 +81,10 @@ public class BookmarksFragment extends Fragment implements View.OnClickListener,
private ImageView mBookmarkTitleImage, mBookmarkImage;
// Colors
private int mIconColor;
private int mIconColor, mScrollIndex;
// Init asynchronously the bookmark manager
private final Runnable initBookmarkManager = new Runnable() {
private final Runnable mInitBookmarkManager = new Runnable() {
@Override
public void run() {
final Context context = getContext();
@ -101,20 +101,20 @@ public class BookmarksFragment extends Fragment implements View.OnClickListener, @@ -101,20 +101,20 @@ public class BookmarksFragment extends Fragment implements View.OnClickListener,
}
// Handle bookmark click
private final OnItemClickListener itemClickListener = new OnItemClickListener() {
private final OnItemClickListener mItemClickListener = new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
final HistoryItem item = mBookmarks.get(position);
if (item.isFolder()) {
setBookmarkDataSet(mBookmarkManager.getBookmarksFromFolder(item.getTitle(), true),
true);
mScrollIndex = mBookmarksListView.getFirstVisiblePosition();
setBookmarkDataSet(mBookmarkManager.getBookmarksFromFolder(item.getTitle(), true), true);
} else {
eventBus.post(new BrowserEvents.OpenUrlInCurrentTab(item.getUrl()));
mEventBus.post(new BrowserEvents.OpenUrlInCurrentTab(item.getUrl()));
}
}
};
private final OnItemLongClickListener itemLongClickListener = new OnItemLongClickListener() {
private final OnItemLongClickListener mItemLongClickListener = new OnItemLongClickListener() {
@Override
public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
final HistoryItem item = mBookmarks.get(position);
@ -123,56 +123,62 @@ public class BookmarksFragment extends Fragment implements View.OnClickListener, @@ -123,56 +123,62 @@ public class BookmarksFragment extends Fragment implements View.OnClickListener,
}
};
@Override
public void onResume() {
super.onResume();
setBookmarkDataSet(mBookmarkManager.getBookmarksFromFolder(null, true), false);
}
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
final View view = inflater.inflate(R.layout.bookmark_drawer, container, false);
mBookmarksListView = (ListView) view.findViewById(R.id.right_drawer_list);
mBookmarksListView.setOnItemClickListener(itemClickListener);
mBookmarksListView.setOnItemLongClickListener(itemLongClickListener);
mBookmarksListView.setOnItemClickListener(mItemClickListener);
mBookmarksListView.setOnItemLongClickListener(mItemLongClickListener);
mBookmarkTitleImage = (ImageView) view.findViewById(R.id.starIcon);
mBookmarkImage = (ImageView) view.findViewById(R.id.icon_star);
final View backView = view.findViewById(R.id.bookmark_back_button);
backView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (mBookmarkManager == null)
return;
if (mBookmarkManager == null) return;
if (!mBookmarkManager.isRootFolder()) {
setBookmarkDataSet(mBookmarkManager.getBookmarksFromFolder(null, true), true);
mBookmarksListView.setSelection(mScrollIndex);
}
}
});
setupNavigationButton(view, R.id.action_add_bookmark, R.id.icon_star);
// Must be called here, only here we have a reference to the ListView
new Thread(initBookmarkManager).run();
new Thread(mInitBookmarkManager).run();
return view;
}
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
// TODO this code depend way too much on BrowserActivity
// TODO remove dependency on BrowserActivity
super.onActivityCreated(savedInstanceState);
final BrowserActivity activity = (BrowserActivity) getActivity();
boolean darkTheme = preferenceManager.getUseTheme() != 0 || activity.isIncognito();
boolean darkTheme = mPreferenceManager.getUseTheme() != 0 || ((BrowserActivity) activity).isIncognito();
mWebpageBitmap = ThemeUtils.getThemedBitmap(activity, R.drawable.ic_webpage, darkTheme);
mFolderBitmap = ThemeUtils.getThemedBitmap(activity, R.drawable.ic_folder, darkTheme);
mIconColor = darkTheme ? ThemeUtils.getIconDarkThemeColor(activity) :
ThemeUtils.getIconLightThemeColor(activity);
setupFrameLayoutButton(getView(), R.id.action_add_bookmark, R.id.icon_star);
mBookmarkTitleImage.setColorFilter(mIconColor, PorterDuff.Mode.SRC_IN);
}
@Override
public void onStart() {
super.onStart();
eventBus.register(this);
mEventBus.register(this);
}
@Override
public void onStop() {
super.onStop();
eventBus.unregister(this);
mEventBus.unregister(this);
}
@Subscribe
@ -182,8 +188,7 @@ public class BookmarksFragment extends Fragment implements View.OnClickListener, @@ -182,8 +188,7 @@ public class BookmarksFragment extends Fragment implements View.OnClickListener,
mBookmarks.add(item);
Collections.sort(mBookmarks, new BookmarkManager.SortIgnoreCase());
mBookmarkAdapter.notifyDataSetChanged();
eventBus
.post(new BookmarkEvents.Added(item));
mEventBus.post(new BookmarkEvents.Added(item));
updateBookmarkIndicator(event.url);
}
}
@ -195,12 +200,8 @@ public class BookmarksFragment extends Fragment implements View.OnClickListener, @@ -195,12 +200,8 @@ public class BookmarksFragment extends Fragment implements View.OnClickListener,
@Subscribe
public void bookmarkChanged(BookmarkEvents.BookmarkChanged event) {
// final int size = mBookmarks.size();
mBookmarks.remove(event.oldBookmark);
// assert mBookmarks.size() < size;
mBookmarks.add(event.newBookmark);
mBookmarkAdapter.notifyDataSetChanged();
Collections.sort(mBookmarks, new BookmarkManager.SortIgnoreCase());
String folder = mBookmarkManager.getCurrentFolder();
setBookmarkDataSet(mBookmarkManager.getBookmarksFromFolder(folder, true), false);
}
private void updateBookmarkIndicator(final String url) {
@ -216,30 +217,33 @@ public class BookmarksFragment extends Fragment implements View.OnClickListener, @@ -216,30 +217,33 @@ public class BookmarksFragment extends Fragment implements View.OnClickListener,
@Subscribe
public void userPressedBack(final BrowserEvents.UserPressedBack event) {
if (mBookmarkManager.isRootFolder()) {
eventBus
.post(new BookmarkEvents.CloseBookmarks());
mEventBus.post(new BookmarkEvents.CloseBookmarks());
} else {
setBookmarkDataSet(mBookmarkManager.getBookmarksFromFolder(null, true), true);
mBookmarksListView.setSelection(mScrollIndex);
}
}
@Subscribe
public void bookmarkDeleted(final BookmarkEvents.Deleted event) {
// final int size = mBookmarks.size();
mBookmarks.remove(event.item);
// assert mBookmarks.size() < size;
if (event.item.isFolder()) {
setBookmarkDataSet(mBookmarkManager.getBookmarksFromFolder(null, true), false);
} else {
mBookmarkAdapter.notifyDataSetChanged();
}
}
private void setBookmarkDataSet(List<HistoryItem> items, boolean animate) {
mBookmarks.clear();
mBookmarks.addAll(items);
mBookmarkAdapter.notifyDataSetChanged();
final int resource;
if (mBookmarkManager.isRootFolder())
if (mBookmarkManager.isRootFolder()) {
resource = R.drawable.ic_action_star;
else
} else {
resource = R.drawable.ic_action_back;
}
final Animation startRotation = new Animation() {
@Override
@ -280,8 +284,7 @@ public class BookmarksFragment extends Fragment implements View.OnClickListener, @@ -280,8 +284,7 @@ public class BookmarksFragment extends Fragment implements View.OnClickListener,
}
}
// TODO this is basically a copy/paste from BrowserActivity, should be changed
private void setupFrameLayoutButton(@NonNull View view, @IdRes int buttonId, @IdRes int imageId) {
private void setupNavigationButton(@NonNull View view, @IdRes int buttonId, @IdRes int imageId) {
FrameLayout frameButton = (FrameLayout) view.findViewById(buttonId);
frameButton.setOnClickListener(this);
frameButton.setOnLongClickListener(this);
@ -291,9 +294,9 @@ public class BookmarksFragment extends Fragment implements View.OnClickListener, @@ -291,9 +294,9 @@ public class BookmarksFragment extends Fragment implements View.OnClickListener,
private void handleLongPress(final HistoryItem item, final int position) {
if (item.isFolder()) {
bookmarksDialogBuilder.showBookmarkFolderLongPressedDialog(getContext(), item);
mBookmarksDialogBuilder.showBookmarkFolderLongPressedDialog(getContext(), item);
} else {
bookmarksDialogBuilder.showLongPressLinkDialog(getContext(), item.getUrl());
mBookmarksDialogBuilder.showLongPressLinkDialog(getContext(), item.getUrl());
}
}
@ -301,7 +304,7 @@ public class BookmarksFragment extends Fragment implements View.OnClickListener, @@ -301,7 +304,7 @@ public class BookmarksFragment extends Fragment implements View.OnClickListener,
public void onClick(View v) {
switch (v.getId()) {
case R.id.action_add_bookmark:
eventBus.post(new BookmarkEvents.WantToBookmarkCurrentPage());
mEventBus.post(new BookmarkEvents.WantToBookmarkCurrentPage());
break;
default:
break;
@ -343,19 +346,19 @@ public class BookmarksFragment extends Fragment implements View.OnClickListener, @@ -343,19 +346,19 @@ public class BookmarksFragment extends Fragment implements View.OnClickListener,
HistoryItem web = mBookmarks.get(position);
holder.txtTitle.setText(web.getTitle());
holder.favicon.setImageBitmap(mWebpageBitmap);
if (web.isFolder()) {
holder.favicon.setImageBitmap(mFolderBitmap);
} else if (web.getBitmap() == null) {
new DownloadImageTask(holder.favicon, web, mWebpageBitmap)
.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
holder.favicon.setImageBitmap(mWebpageBitmap);
new ImageDownloadTask(holder.favicon, web, mWebpageBitmap)
.executeOnExecutor(AsyncExecutor.getInstance());
} else {
holder.favicon.setImageBitmap(web.getBitmap());
}
return row;
}
class BookmarkViewHolder {
private class BookmarkViewHolder {
TextView txtTitle;
ImageView favicon;
}

76
app/src/main/java/acr/browser/lightning/fragment/DisplaySettingsFragment.java

@ -8,7 +8,6 @@ import android.content.DialogInterface; @@ -8,7 +8,6 @@ import android.content.DialogInterface;
import android.os.Bundle;
import android.preference.CheckBoxPreference;
import android.preference.Preference;
import android.preference.PreferenceFragment;
import android.support.v7.app.AlertDialog;
import android.view.Gravity;
import android.view.LayoutInflater;
@ -19,7 +18,6 @@ import android.widget.SeekBar; @@ -19,7 +18,6 @@ import android.widget.SeekBar;
import android.widget.TextView;
import acr.browser.lightning.R;
import acr.browser.lightning.preference.PreferenceManager;
public class DisplaySettingsFragment extends LightningPreferenceFragment implements Preference.OnPreferenceClickListener, Preference.OnPreferenceChangeListener {
@ -57,7 +55,7 @@ public class DisplaySettingsFragment extends LightningPreferenceFragment impleme @@ -57,7 +55,7 @@ public class DisplaySettingsFragment extends LightningPreferenceFragment impleme
private void initPrefs() {
// mPreferences storage
mThemeOptions = this.getResources().getStringArray(R.array.themes);
mCurrentTheme = preferenceManager.getUseTheme();
mCurrentTheme = mPreferenceManager.getUseTheme();
theme = findPreference(SETTINGS_THEME);
Preference textsize = findPreference(SETTINGS_TEXTSIZE);
@ -75,13 +73,13 @@ public class DisplaySettingsFragment extends LightningPreferenceFragment impleme @@ -75,13 +73,13 @@ public class DisplaySettingsFragment extends LightningPreferenceFragment impleme
cboverview.setOnPreferenceChangeListener(this);
cbreflow.setOnPreferenceChangeListener(this);
cbstatus.setChecked(preferenceManager.getHideStatusBarEnabled());
cbfullscreen.setChecked(preferenceManager.getFullScreenEnabled());
cbviewport.setChecked(preferenceManager.getUseWideViewportEnabled());
cboverview.setChecked(preferenceManager.getOverviewModeEnabled());
cbreflow.setChecked(preferenceManager.getTextReflowEnabled());
cbstatus.setChecked(mPreferenceManager.getHideStatusBarEnabled());
cbfullscreen.setChecked(mPreferenceManager.getFullScreenEnabled());
cbviewport.setChecked(mPreferenceManager.getUseWideViewportEnabled());
cboverview.setChecked(mPreferenceManager.getOverviewModeEnabled());
cbreflow.setChecked(mPreferenceManager.getTextReflowEnabled());
theme.setSummary(mThemeOptions[preferenceManager.getUseTheme()]);
theme.setSummary(mThemeOptions[mPreferenceManager.getUseTheme()]);
}
@Override
@ -103,23 +101,23 @@ public class DisplaySettingsFragment extends LightningPreferenceFragment impleme @@ -103,23 +101,23 @@ public class DisplaySettingsFragment extends LightningPreferenceFragment impleme
// switch preferences
switch (preference.getKey()) {
case SETTINGS_HIDESTATUSBAR:
preferenceManager.setHideStatusBarEnabled((Boolean) newValue);
mPreferenceManager.setHideStatusBarEnabled((Boolean) newValue);
cbstatus.setChecked((Boolean) newValue);
return true;
case SETTINGS_FULLSCREEN:
preferenceManager.setFullScreenEnabled((Boolean) newValue);
mPreferenceManager.setFullScreenEnabled((Boolean) newValue);
cbfullscreen.setChecked((Boolean) newValue);
return true;
case SETTINGS_VIEWPORT:
preferenceManager.setUseWideViewportEnabled((Boolean) newValue);
mPreferenceManager.setUseWideViewportEnabled((Boolean) newValue);
cbviewport.setChecked((Boolean) newValue);
return true;
case SETTINGS_OVERVIEWMODE:
preferenceManager.setOverviewModeEnabled((Boolean) newValue);
mPreferenceManager.setOverviewModeEnabled((Boolean) newValue);
cboverview.setChecked((Boolean) newValue);
return true;
case SETTINGS_REFLOW:
preferenceManager.setTextReflowEnabled((Boolean) newValue);
mPreferenceManager.setTextReflowEnabled((Boolean) newValue);
cbreflow.setChecked((Boolean) newValue);
return true;
default:
@ -137,32 +135,17 @@ public class DisplaySettingsFragment extends LightningPreferenceFragment impleme @@ -137,32 +135,17 @@ public class DisplaySettingsFragment extends LightningPreferenceFragment impleme
sample.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.WRAP_CONTENT));
sample.setGravity(Gravity.CENTER_HORIZONTAL);
view.addView(sample);
bar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar view, int size, boolean user) {
sample.setTextSize(getTextSize(size));
}
@Override
public void onStartTrackingTouch(SeekBar arg0) {
}
@Override
public void onStopTrackingTouch(SeekBar arg0) {
}
});
bar.setOnSeekBarChangeListener(new TextSeekBarListener(sample));
final int MAX = 5;
bar.setMax(MAX);
bar.setProgress(MAX - preferenceManager.getTextSize());
bar.setProgress(MAX - mPreferenceManager.getTextSize());
builder.setView(view);
builder.setTitle(R.string.title_text_size);
builder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface arg0, int arg1) {
preferenceManager.setTextSize(MAX - bar.getProgress());
mPreferenceManager.setTextSize(MAX - bar.getProgress());
}
});
@ -192,12 +175,12 @@ public class DisplaySettingsFragment extends LightningPreferenceFragment impleme @@ -192,12 +175,12 @@ public class DisplaySettingsFragment extends LightningPreferenceFragment impleme
AlertDialog.Builder picker = new AlertDialog.Builder(mActivity);
picker.setTitle(getResources().getString(R.string.theme));
int n = preferenceManager.getUseTheme();
int n = mPreferenceManager.getUseTheme();
picker.setSingleChoiceItems(mThemeOptions, n, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
preferenceManager.setUseTheme(which);
mPreferenceManager.setUseTheme(which);
if (which < mThemeOptions.length) {
theme.setSummary(mThemeOptions[which]);
}
@ -208,7 +191,7 @@ public class DisplaySettingsFragment extends LightningPreferenceFragment impleme @@ -208,7 +191,7 @@ public class DisplaySettingsFragment extends LightningPreferenceFragment impleme
@Override
public void onClick(DialogInterface dialog, int which) {
if (mCurrentTheme != preferenceManager.getUseTheme()) {
if (mCurrentTheme != mPreferenceManager.getUseTheme()) {
getActivity().onBackPressed();
}
}
@ -216,11 +199,32 @@ public class DisplaySettingsFragment extends LightningPreferenceFragment impleme @@ -216,11 +199,32 @@ public class DisplaySettingsFragment extends LightningPreferenceFragment impleme
picker.setOnCancelListener(new DialogInterface.OnCancelListener() {
@Override
public void onCancel(DialogInterface dialog) {
if (mCurrentTheme != preferenceManager.getUseTheme()) {
if (mCurrentTheme != mPreferenceManager.getUseTheme()) {
getActivity().onBackPressed();
}
}
});
picker.show();
}
private static class TextSeekBarListener implements SeekBar.OnSeekBarChangeListener {
private final TextView sample;
public TextSeekBarListener(TextView sample) {this.sample = sample;}
@Override
public void onProgressChanged(SeekBar view, int size, boolean user) {
this.sample.setTextSize(getTextSize(size));
}
@Override
public void onStartTrackingTouch(SeekBar arg0) {
}
@Override
public void onStopTrackingTouch(SeekBar arg0) {
}
}
}

227
app/src/main/java/acr/browser/lightning/fragment/GeneralSettingsFragment.java

@ -5,27 +5,26 @@ package acr.browser.lightning.fragment; @@ -5,27 +5,26 @@ package acr.browser.lightning.fragment;
import android.app.Activity;
import android.content.DialogInterface;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.preference.CheckBoxPreference;
import android.preference.Preference;
import android.preference.PreferenceFragment;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AlertDialog;
import android.text.Editable;
import android.text.InputFilter;
import android.util.Log;
import android.util.TypedValue;
import android.text.TextWatcher;
import android.view.View;
import android.view.ViewGroup;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.TextView;
import acr.browser.lightning.R;
import acr.browser.lightning.constant.Constants;
import acr.browser.lightning.download.DownloadHandler;
import acr.browser.lightning.preference.PreferenceManager;
import acr.browser.lightning.utils.ProxyUtils;
import acr.browser.lightning.utils.ThemeUtils;
import acr.browser.lightning.utils.Utils;
public class GeneralSettingsFragment extends LightningPreferenceFragment implements Preference.OnPreferenceClickListener, Preference.OnPreferenceChangeListener {
@ -91,25 +90,25 @@ public class GeneralSettingsFragment extends LightningPreferenceFragment impleme @@ -91,25 +90,25 @@ public class GeneralSettingsFragment extends LightningPreferenceFragment impleme
cbgooglesuggest.setOnPreferenceChangeListener(this);
cbDrawerTabs.setOnPreferenceChangeListener(this);
mAgentChoice = preferenceManager.getUserAgentChoice();
mHomepage = preferenceManager.getHomepage();
mDownloadLocation = preferenceManager.getDownloadDirectory();
mAgentChoice = mPreferenceManager.getUserAgentChoice();
mHomepage = mPreferenceManager.getHomepage();
mDownloadLocation = mPreferenceManager.getDownloadDirectory();
mProxyChoices = getResources().getStringArray(R.array.proxy_choices_array);
int choice = preferenceManager.getProxyChoice();
int choice = mPreferenceManager.getProxyChoice();
if (choice == Constants.PROXY_MANUAL) {
proxy.setSummary(preferenceManager.getProxyHost() + ':' + preferenceManager.getProxyPort());
proxy.setSummary(mPreferenceManager.getProxyHost() + ':' + mPreferenceManager.getProxyPort());
} else {
proxy.setSummary(mProxyChoices[choice]);
}
if (API >= 19) {
preferenceManager.setFlashSupport(0);
mPreferenceManager.setFlashSupport(0);
}
setSearchEngineSummary(preferenceManager.getSearchChoice());
setSearchEngineSummary(mPreferenceManager.getSearchChoice());
downloadloc.setSummary(Constants.EXTERNAL_STORAGE + '/' + mDownloadLocation);
downloadloc.setSummary(mDownloadLocation);
if (mHomepage.contains("about:home")) {
home.setSummary(getResources().getString(R.string.action_homepage));
@ -135,28 +134,28 @@ public class GeneralSettingsFragment extends LightningPreferenceFragment impleme @@ -135,28 +134,28 @@ public class GeneralSettingsFragment extends LightningPreferenceFragment impleme
useragent.setSummary(getResources().getString(R.string.agent_custom));
}
int flashNum = preferenceManager.getFlashSupport();
boolean imagesBool = preferenceManager.getBlockImagesEnabled();
boolean enableJSBool = preferenceManager.getJavaScriptEnabled();
int flashNum = mPreferenceManager.getFlashSupport();
boolean imagesBool = mPreferenceManager.getBlockImagesEnabled();
boolean enableJSBool = mPreferenceManager.getJavaScriptEnabled();
proxy.setEnabled(Constants.FULL_VERSION);
// proxy.setEnabled(Constants.FULL_VERSION);
cbAds.setEnabled(Constants.FULL_VERSION);
cbFlash.setEnabled(API < 19);
cbImages.setChecked(imagesBool);
cbJsScript.setChecked(enableJSBool);
cbFlash.setChecked(flashNum > 0);
cbAds.setChecked(Constants.FULL_VERSION && preferenceManager.getAdBlockEnabled());
cbColorMode.setChecked(preferenceManager.getColorModeEnabled());
cbgooglesuggest.setChecked(preferenceManager.getGoogleSearchSuggestionsEnabled());
cbDrawerTabs.setChecked(preferenceManager.getShowTabsInDrawer(true));
cbAds.setChecked(Constants.FULL_VERSION && mPreferenceManager.getAdBlockEnabled());
cbColorMode.setChecked(mPreferenceManager.getColorModeEnabled());
cbgooglesuggest.setChecked(mPreferenceManager.getGoogleSearchSuggestionsEnabled());
cbDrawerTabs.setChecked(mPreferenceManager.getShowTabsInDrawer(true));
}
private void searchUrlPicker() {
final AlertDialog.Builder urlPicker = new AlertDialog.Builder(mActivity);
urlPicker.setTitle(getResources().getString(R.string.custom_url));
final EditText getSearchUrl = new EditText(mActivity);
String mSearchUrl = preferenceManager.getSearchUrl();
String mSearchUrl = mPreferenceManager.getSearchUrl();
getSearchUrl.setText(mSearchUrl);
urlPicker.setView(getSearchUrl);
urlPicker.setPositiveButton(getResources().getString(R.string.action_ok),
@ -164,7 +163,7 @@ public class GeneralSettingsFragment extends LightningPreferenceFragment impleme @@ -164,7 +163,7 @@ public class GeneralSettingsFragment extends LightningPreferenceFragment impleme
@Override
public void onClick(DialogInterface dialog, int which) {
String text = getSearchUrl.getText().toString();
preferenceManager.setSearchUrl(text);
mPreferenceManager.setSearchUrl(text);
searchengine.setSummary(getResources().getString(R.string.custom_url) + ": "
+ text);
}
@ -181,7 +180,7 @@ public class GeneralSettingsFragment extends LightningPreferenceFragment impleme @@ -181,7 +180,7 @@ public class GeneralSettingsFragment extends LightningPreferenceFragment impleme
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int id) {
preferenceManager.setFlashSupport(1);
mPreferenceManager.setFlashSupport(1);
}
})
.setNegativeButton(getResources().getString(R.string.action_auto),
@ -189,13 +188,13 @@ public class GeneralSettingsFragment extends LightningPreferenceFragment impleme @@ -189,13 +188,13 @@ public class GeneralSettingsFragment extends LightningPreferenceFragment impleme
@Override
public void onClick(DialogInterface dialog, int which) {
preferenceManager.setFlashSupport(2);
mPreferenceManager.setFlashSupport(2);
}
}).setOnCancelListener(new DialogInterface.OnCancelListener() {
@Override
public void onCancel(DialogInterface dialog) {
preferenceManager.setFlashSupport(0);
mPreferenceManager.setFlashSupport(0);
}
});
@ -206,7 +205,7 @@ public class GeneralSettingsFragment extends LightningPreferenceFragment impleme @@ -206,7 +205,7 @@ public class GeneralSettingsFragment extends LightningPreferenceFragment impleme
private void proxyChoicePicker() {
AlertDialog.Builder picker = new AlertDialog.Builder(mActivity);
picker.setTitle(getResources().getString(R.string.http_proxy));
picker.setSingleChoiceItems(mProxyChoices, preferenceManager.getProxyChoice(),
picker.setSingleChoiceItems(mProxyChoices, mPreferenceManager.getProxyChoice(),
new DialogInterface.OnClickListener() {
@Override
@ -214,12 +213,7 @@ public class GeneralSettingsFragment extends LightningPreferenceFragment impleme @@ -214,12 +213,7 @@ public class GeneralSettingsFragment extends LightningPreferenceFragment impleme
setProxyChoice(which);
}
});
picker.setNeutralButton(getResources().getString(R.string.action_ok),
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
}
});
picker.setNeutralButton(getResources().getString(R.string.action_ok), null);
picker.show();
}
@ -236,7 +230,7 @@ public class GeneralSettingsFragment extends LightningPreferenceFragment impleme @@ -236,7 +230,7 @@ public class GeneralSettingsFragment extends LightningPreferenceFragment impleme
break;
}
preferenceManager.setProxyChoice(choice);
mPreferenceManager.setProxyChoice(choice);
if (choice < mProxyChoices.length)
proxy.setSummary(mProxyChoices[choice]);
}
@ -254,8 +248,8 @@ public class GeneralSettingsFragment extends LightningPreferenceFragment impleme @@ -254,8 +248,8 @@ public class GeneralSettingsFragment extends LightningPreferenceFragment impleme
filterArray[0] = new InputFilter.LengthFilter(maxCharacters - 1);
eProxyPort.setFilters(filterArray);
eProxyHost.setText(preferenceManager.getProxyHost());
eProxyPort.setText(Integer.toString(preferenceManager.getProxyPort()));
eProxyHost.setText(mPreferenceManager.getProxyHost());
eProxyPort.setText(Integer.toString(mPreferenceManager.getProxyPort()));
new AlertDialog.Builder(mActivity)
.setTitle(R.string.manual_proxy)
@ -270,10 +264,10 @@ public class GeneralSettingsFragment extends LightningPreferenceFragment impleme @@ -270,10 +264,10 @@ public class GeneralSettingsFragment extends LightningPreferenceFragment impleme
// larger than max integer
proxyPort = Integer.parseInt(eProxyPort.getText().toString());
} catch (NumberFormatException ignored) {
proxyPort = preferenceManager.getProxyPort();
proxyPort = mPreferenceManager.getProxyPort();
}
preferenceManager.setProxyHost(proxyHost);
preferenceManager.setProxyPort(proxyPort);
mPreferenceManager.setProxyHost(proxyHost);
mPreferenceManager.setProxyPort(proxyPort);
proxy.setSummary(proxyHost + ':' + proxyPort);
}
}).show();
@ -287,29 +281,24 @@ public class GeneralSettingsFragment extends LightningPreferenceFragment impleme @@ -287,29 +281,24 @@ public class GeneralSettingsFragment extends LightningPreferenceFragment impleme
"DuckDuckGo (Privacy)", "DuckDuckGo Lite (Privacy)", "Baidu (Chinese)",
"Yandex (Russian)"};
int n = preferenceManager.getSearchChoice();
int n = mPreferenceManager.getSearchChoice();
picker.setSingleChoiceItems(chars, n, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
preferenceManager.setSearchChoice(which);
mPreferenceManager.setSearchChoice(which);
setSearchEngineSummary(which);
}
});
picker.setNeutralButton(getResources().getString(R.string.action_ok),
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
}
});
picker.setNeutralButton(getResources().getString(R.string.action_ok), null);
picker.show();
}
private void homepageDialog() {
AlertDialog.Builder picker = new AlertDialog.Builder(mActivity);
picker.setTitle(getResources().getString(R.string.home));
mHomepage = preferenceManager.getHomepage();
mHomepage = mPreferenceManager.getHomepage();
int n;
if (mHomepage.contains("about:home")) {
n = 1;
@ -327,15 +316,15 @@ public class GeneralSettingsFragment extends LightningPreferenceFragment impleme @@ -327,15 +316,15 @@ public class GeneralSettingsFragment extends LightningPreferenceFragment impleme
public void onClick(DialogInterface dialog, int which) {
switch (which + 1) {
case 1:
preferenceManager.setHomepage("about:home");
mPreferenceManager.setHomepage("about:home");
home.setSummary(getResources().getString(R.string.action_homepage));
break;
case 2:
preferenceManager.setHomepage("about:blank");
mPreferenceManager.setHomepage("about:blank");
home.setSummary(getResources().getString(R.string.action_blank));
break;
case 3:
preferenceManager.setHomepage("about:bookmarks");
mPreferenceManager.setHomepage("about:bookmarks");
home.setSummary(getResources().getString(R.string.action_bookmarks));
break;
case 4:
@ -344,12 +333,7 @@ public class GeneralSettingsFragment extends LightningPreferenceFragment impleme @@ -344,12 +333,7 @@ public class GeneralSettingsFragment extends LightningPreferenceFragment impleme
}
}
});
picker.setNeutralButton(getResources().getString(R.string.action_ok),
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
}
});
picker.setNeutralButton(getResources().getString(R.string.action_ok), null);
picker.show();
}
@ -357,7 +341,7 @@ public class GeneralSettingsFragment extends LightningPreferenceFragment impleme @@ -357,7 +341,7 @@ public class GeneralSettingsFragment extends LightningPreferenceFragment impleme
final AlertDialog.Builder homePicker = new AlertDialog.Builder(mActivity);
homePicker.setTitle(getResources().getString(R.string.title_custom_homepage));
final EditText getHome = new EditText(mActivity);
mHomepage = preferenceManager.getHomepage();
mHomepage = mPreferenceManager.getHomepage();
if (!mHomepage.startsWith("about:")) {
getHome.setText(mHomepage);
} else {
@ -369,7 +353,7 @@ public class GeneralSettingsFragment extends LightningPreferenceFragment impleme @@ -369,7 +353,7 @@ public class GeneralSettingsFragment extends LightningPreferenceFragment impleme
@Override
public void onClick(DialogInterface dialog, int which) {
String text = getHome.getText().toString();
preferenceManager.setHomepage(text);
mPreferenceManager.setHomepage(text);
home.setSummary(text);
}
});
@ -379,48 +363,42 @@ public class GeneralSettingsFragment extends LightningPreferenceFragment impleme @@ -379,48 +363,42 @@ public class GeneralSettingsFragment extends LightningPreferenceFragment impleme
private void downloadLocDialog() {
AlertDialog.Builder picker = new AlertDialog.Builder(mActivity);
picker.setTitle(getResources().getString(R.string.title_download_location));
mDownloadLocation = preferenceManager.getDownloadDirectory();
mDownloadLocation = mPreferenceManager.getDownloadDirectory();
int n;
if (mDownloadLocation.contains(Environment.DIRECTORY_DOWNLOADS)) {
n = 1;
n = 0;
} else {
n = 2;
n = 1;
}
picker.setSingleChoiceItems(R.array.download_folder, n - 1,
picker.setSingleChoiceItems(R.array.download_folder, n,
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
switch (which + 1) {
case 1:
preferenceManager.setDownloadDirectory(Environment.DIRECTORY_DOWNLOADS);
downloadloc.setSummary(Constants.EXTERNAL_STORAGE + '/'
+ Environment.DIRECTORY_DOWNLOADS);
switch (which) {
case 0:
mPreferenceManager.setDownloadDirectory(DownloadHandler.DEFAULT_DOWNLOAD_PATH);
downloadloc.setSummary(DownloadHandler.DEFAULT_DOWNLOAD_PATH);
break;
case 2:
case 1:
downPicker();
break;
}
}
});
picker.setNeutralButton(getResources().getString(R.string.action_ok),
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
}
});
picker.setNeutralButton(getResources().getString(R.string.action_ok), null);
picker.show();
}
private void agentDialog() {
AlertDialog.Builder agentPicker = new AlertDialog.Builder(mActivity);
agentPicker.setTitle(getResources().getString(R.string.title_user_agent));
mAgentChoice = preferenceManager.getUserAgentChoice();
mAgentChoice = mPreferenceManager.getUserAgentChoice();
agentPicker.setSingleChoiceItems(R.array.user_agent, mAgentChoice - 1,
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
preferenceManager.setUserAgentChoice(which + 1);
mPreferenceManager.setUserAgentChoice(which + 1);
switch (which + 1) {
case 1:
useragent.setSummary(getResources().getString(R.string.agent_default));
@ -438,18 +416,7 @@ public class GeneralSettingsFragment extends LightningPreferenceFragment impleme @@ -438,18 +416,7 @@ public class GeneralSettingsFragment extends LightningPreferenceFragment impleme
}
}
});
agentPicker.setNeutralButton(getResources().getString(R.string.action_ok),
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
}
});
agentPicker.setOnCancelListener(new DialogInterface.OnCancelListener() {
@Override
public void onCancel(DialogInterface dialog) {
Log.i("Cancelled", "");
}
});
agentPicker.setNeutralButton(getResources().getString(R.string.action_ok), null);
agentPicker.show();
}
@ -463,7 +430,7 @@ public class GeneralSettingsFragment extends LightningPreferenceFragment impleme @@ -463,7 +430,7 @@ public class GeneralSettingsFragment extends LightningPreferenceFragment impleme
@Override
public void onClick(DialogInterface dialog, int which) {
String text = getAgent.getText().toString();
preferenceManager.setUserAgentString(text);
mPreferenceManager.setUserAgentString(text);
useragent.setSummary(getResources().getString(R.string.agent_custom));
}
});
@ -475,36 +442,25 @@ public class GeneralSettingsFragment extends LightningPreferenceFragment impleme @@ -475,36 +442,25 @@ public class GeneralSettingsFragment extends LightningPreferenceFragment impleme
LinearLayout layout = new LinearLayout(mActivity);
downLocationPicker.setTitle(getResources().getString(R.string.title_download_location));
final EditText getDownload = new EditText(mActivity);
getDownload.setText(preferenceManager.getDownloadDirectory());
getDownload.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT));
getDownload.setText(mPreferenceManager.getDownloadDirectory());
final int errorColor = ContextCompat.getColor(getActivity(), R.color.error_red);
final int regularColor = ThemeUtils.getTextColor(getActivity());
getDownload.setTextColor(regularColor);
getDownload.addTextChangedListener(new DownloadLocationTextWatcher(getDownload, errorColor, regularColor));
getDownload.setText(mPreferenceManager.getDownloadDirectory());
int padding = Utils.dpToPx(10);
TextView v = new TextView(mActivity);
v.setTextSize(TypedValue.COMPLEX_UNIT_SP, 18);
v.setTextColor(Color.DKGRAY);
v.setText(Constants.EXTERNAL_STORAGE + '/');
v.setPadding(padding, padding, 0, padding);
layout.addView(v);
layout.addView(getDownload);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
Drawable drawable;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
drawable = getResources().getDrawable(android.R.drawable.edit_text, getActivity().getTheme());
} else {
drawable = getResources().getDrawable(android.R.drawable.edit_text);
}
layout.setBackground(drawable);
} else {
layout.setBackgroundDrawable(getResources().getDrawable(android.R.drawable.edit_text));
}
downLocationPicker.setView(layout);
downLocationPicker.setPositiveButton(getResources().getString(R.string.action_ok),
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
String text = getDownload.getText().toString();
preferenceManager.setDownloadDirectory(text);
downloadloc.setSummary(Constants.EXTERNAL_STORAGE + '/' + text);
text = DownloadHandler.addNecessarySlashes(text);
mPreferenceManager.setDownloadDirectory(text);
downloadloc.setSummary(text);
}
});
downLocationPicker.show();
@ -578,40 +534,67 @@ public class GeneralSettingsFragment extends LightningPreferenceFragment impleme @@ -578,40 +534,67 @@ public class GeneralSettingsFragment extends LightningPreferenceFragment impleme
if (cbFlash.isChecked()) {
getFlashChoice();
} else {
preferenceManager.setFlashSupport(0);
mPreferenceManager.setFlashSupport(0);
}
if (!Utils.isFlashInstalled(mActivity) && cbFlash.isChecked()) {
Utils.createInformativeDialog(mActivity, R.string.title_warning, R.string.dialog_adobe_not_installed);
cbFlash.setEnabled(false);
preferenceManager.setFlashSupport(0);
mPreferenceManager.setFlashSupport(0);
}
cbFlash.setChecked((Boolean) newValue);
return true;
case SETTINGS_ADS:
preferenceManager.setAdBlockEnabled((Boolean) newValue);
mPreferenceManager.setAdBlockEnabled((Boolean) newValue);
cbAds.setChecked((Boolean) newValue);
return true;
case SETTINGS_IMAGES:
preferenceManager.setBlockImagesEnabled((Boolean) newValue);
mPreferenceManager.setBlockImagesEnabled((Boolean) newValue);
cbImages.setChecked((Boolean) newValue);
return true;
case SETTINGS_JAVASCRIPT:
preferenceManager.setJavaScriptEnabled((Boolean) newValue);
mPreferenceManager.setJavaScriptEnabled((Boolean) newValue);
cbJsScript.setChecked((Boolean) newValue);
return true;
case SETTINGS_COLORMODE:
preferenceManager.setColorModeEnabled((Boolean) newValue);
mPreferenceManager.setColorModeEnabled((Boolean) newValue);
cbColorMode.setChecked((Boolean) newValue);
return true;
case SETTINGS_GOOGLESUGGESTIONS:
preferenceManager.setGoogleSearchSuggestionsEnabled((Boolean) newValue);
mPreferenceManager.setGoogleSearchSuggestionsEnabled((Boolean) newValue);
cbgooglesuggest.setChecked((Boolean) newValue);
return true;
case SETTINGS_DRAWERTABS:
preferenceManager.setShowTabsInDrawer((Boolean) newValue);
mPreferenceManager.setShowTabsInDrawer((Boolean) newValue);
cbDrawerTabs.setChecked((Boolean) newValue);
default:
return false;
}
}
private static class DownloadLocationTextWatcher implements TextWatcher {
private final EditText getDownload;
private final int errorColor;
private final int regularColor;
public DownloadLocationTextWatcher(EditText getDownload, int errorColor, int regularColor) {
this.getDownload = getDownload;
this.errorColor = errorColor;
this.regularColor = regularColor;
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {}
@Override
public void afterTextChanged(Editable s) {
if (!DownloadHandler.isWriteAccessAvailable(s.toString())) {
this.getDownload.setTextColor(this.errorColor);
} else {
this.getDownload.setTextColor(this.regularColor);
}
}
}
}

2
app/src/main/java/acr/browser/lightning/fragment/LightningPreferenceFragment.java

@ -17,7 +17,7 @@ import acr.browser.lightning.preference.PreferenceManager; @@ -17,7 +17,7 @@ import acr.browser.lightning.preference.PreferenceManager;
public class LightningPreferenceFragment extends PreferenceFragment {
@Inject
PreferenceManager preferenceManager;
PreferenceManager mPreferenceManager;
@Override
public void onCreate(Bundle savedInstanceState) {

44
app/src/main/java/acr/browser/lightning/fragment/PrivacySettingsFragment.java

@ -11,12 +11,10 @@ import android.os.Handler; @@ -11,12 +11,10 @@ import android.os.Handler;
import android.os.Message;
import android.preference.CheckBoxPreference;
import android.preference.Preference;
import android.preference.PreferenceFragment;
import android.support.v7.app.AlertDialog;
import android.webkit.WebView;
import acr.browser.lightning.R;
import acr.browser.lightning.preference.PreferenceManager;
import acr.browser.lightning.utils.Utils;
import acr.browser.lightning.utils.WebUtils;
@ -77,13 +75,13 @@ public class PrivacySettingsFragment extends LightningPreferenceFragment impleme @@ -77,13 +75,13 @@ public class PrivacySettingsFragment extends LightningPreferenceFragment impleme
cbcookiesexit.setOnPreferenceChangeListener(this);
cbwebstorageexit.setOnPreferenceChangeListener(this);
cblocation.setChecked(preferenceManager.getLocationEnabled());
cbsavepasswords.setChecked(preferenceManager.getSavePasswordsEnabled());
cbcacheexit.setChecked(preferenceManager.getClearCacheExit());
cbhistoryexit.setChecked(preferenceManager.getClearHistoryExitEnabled());
cbcookiesexit.setChecked(preferenceManager.getClearCookiesExitEnabled());
cb3cookies.setChecked(preferenceManager.getBlockThirdPartyCookiesEnabled());
cbwebstorageexit.setChecked(preferenceManager.getClearWebStorageExitEnabled());
cblocation.setChecked(mPreferenceManager.getLocationEnabled());
cbsavepasswords.setChecked(mPreferenceManager.getSavePasswordsEnabled());
cbcacheexit.setChecked(mPreferenceManager.getClearCacheExit());
cbhistoryexit.setChecked(mPreferenceManager.getClearHistoryExitEnabled());
cbcookiesexit.setChecked(mPreferenceManager.getClearCookiesExitEnabled());
cb3cookies.setChecked(mPreferenceManager.getBlockThirdPartyCookiesEnabled());
cbwebstorageexit.setChecked(mPreferenceManager.getClearWebStorageExitEnabled());
cb3cookies.setEnabled(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP);
@ -149,12 +147,7 @@ public class PrivacySettingsFragment extends LightningPreferenceFragment impleme @@ -149,12 +147,7 @@ public class PrivacySettingsFragment extends LightningPreferenceFragment impleme
clear.start();
}
})
.setNegativeButton(getResources().getString(R.string.action_no),
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface arg0, int arg1) {
}
}).show();
.setNegativeButton(getResources().getString(R.string.action_no), null).show();
}
private void clearCookiesDialog() {
@ -174,12 +167,7 @@ public class PrivacySettingsFragment extends LightningPreferenceFragment impleme @@ -174,12 +167,7 @@ public class PrivacySettingsFragment extends LightningPreferenceFragment impleme
clear.start();
}
})
.setNegativeButton(getResources().getString(R.string.action_no),
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface arg0, int arg1) {
}
}).show();
.setNegativeButton(getResources().getString(R.string.action_no), null).show();
}
private void clearCache() {
@ -209,31 +197,31 @@ public class PrivacySettingsFragment extends LightningPreferenceFragment impleme @@ -209,31 +197,31 @@ public class PrivacySettingsFragment extends LightningPreferenceFragment impleme
// switch preferences
switch (preference.getKey()) {
case SETTINGS_LOCATION:
preferenceManager.setLocationEnabled((Boolean) newValue);
mPreferenceManager.setLocationEnabled((Boolean) newValue);
cblocation.setChecked((Boolean) newValue);
return true;
case SETTINGS_THIRDPCOOKIES:
preferenceManager.setBlockThirdPartyCookiesEnabled((Boolean) newValue);
mPreferenceManager.setBlockThirdPartyCookiesEnabled((Boolean) newValue);
cb3cookies.setChecked((Boolean) newValue);
return true;
case SETTINGS_SAVEPASSWORD:
preferenceManager.setSavePasswordsEnabled((Boolean) newValue);
mPreferenceManager.setSavePasswordsEnabled((Boolean) newValue);
cbsavepasswords.setChecked((Boolean) newValue);
return true;
case SETTINGS_CACHEEXIT:
preferenceManager.setClearCacheExit((Boolean) newValue);
mPreferenceManager.setClearCacheExit((Boolean) newValue);
cbcacheexit.setChecked((Boolean) newValue);
return true;
case SETTINGS_HISTORYEXIT:
preferenceManager.setClearHistoryExitEnabled((Boolean) newValue);
mPreferenceManager.setClearHistoryExitEnabled((Boolean) newValue);
cbhistoryexit.setChecked((Boolean) newValue);
return true;
case SETTINGS_COOKIEEXIT:
preferenceManager.setClearCookiesExitEnabled((Boolean) newValue);
mPreferenceManager.setClearCookiesExitEnabled((Boolean) newValue);
cbcookiesexit.setChecked((Boolean) newValue);
return true;
case SETTINGS_WEBSTORAGEEXIT:
preferenceManager.setClearWebStorageExitEnabled((Boolean) newValue);
mPreferenceManager.setClearWebStorageExitEnabled((Boolean) newValue);
cbwebstorageexit.setChecked((Boolean) newValue);
return true;
default:

69
app/src/main/java/acr/browser/lightning/object/SearchAdapter.java

@ -34,6 +34,7 @@ import java.util.Comparator; @@ -34,6 +34,7 @@ import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.regex.Pattern;
import javax.inject.Inject;
@ -48,11 +49,12 @@ import acr.browser.lightning.utils.Utils; @@ -48,11 +49,12 @@ import acr.browser.lightning.utils.Utils;
public class SearchAdapter extends BaseAdapter implements Filterable {
private final List<HistoryItem> mHistory = new ArrayList<>();
private final List<HistoryItem> mBookmarks = new ArrayList<>();
private final List<HistoryItem> mSuggestions = new ArrayList<>();
private final List<HistoryItem> mFilteredList = new ArrayList<>();
private final List<HistoryItem> mAllBookmarks = new ArrayList<>();
private static final Pattern SPACE_PATTERN = Pattern.compile(" ", Pattern.LITERAL);
private final List<HistoryItem> mHistory = new ArrayList<>(5);
private final List<HistoryItem> mBookmarks = new ArrayList<>(5);
private final List<HistoryItem> mSuggestions = new ArrayList<>(5);
private final List<HistoryItem> mFilteredList = new ArrayList<>(5);
private final List<HistoryItem> mAllBookmarks = new ArrayList<>(5);
private final Object mLock = new Object();
private final Context mContext;
private boolean mUseGoogle = true;
@ -87,14 +89,7 @@ public class SearchAdapter extends BaseAdapter implements Filterable { @@ -87,14 +89,7 @@ public class SearchAdapter extends BaseAdapter implements Filterable {
mSearchSubtitle = mContext.getString(R.string.suggestion);
mDarkTheme = dark || incognito;
mIncognito = incognito;
Thread delete = new Thread(new Runnable() {
@Override
public void run() {
deleteOldCacheFiles();
}
});
Thread delete = new Thread(new ClearCacheRunnable());
mSearchDrawable = ThemeUtils.getThemedDrawable(context, R.drawable.ic_search, mDarkTheme);
mBookmarkDrawable = ThemeUtils.getThemedDrawable(context, R.drawable.ic_bookmark, mDarkTheme);
mHistoryDrawable = ThemeUtils.getThemedDrawable(context, R.drawable.ic_history, mDarkTheme);
@ -102,7 +97,7 @@ public class SearchAdapter extends BaseAdapter implements Filterable { @@ -102,7 +97,7 @@ public class SearchAdapter extends BaseAdapter implements Filterable {
delete.start();
}
private void deleteOldCacheFiles() {
private static void deleteOldCacheFiles() {
File dir = new File(BrowserApp.getAppContext().getCacheDir().toString());
String[] fileList = dir.list(new NameFilter());
long earliestTimeAllowed = System.currentTimeMillis() - INTERVAL_DAY;
@ -114,7 +109,7 @@ public class SearchAdapter extends BaseAdapter implements Filterable { @@ -114,7 +109,7 @@ public class SearchAdapter extends BaseAdapter implements Filterable {
}
}
private class NameFilter implements FilenameFilter {
private static class NameFilter implements FilenameFilter {
@Override
public boolean accept(File dir, String filename) {
@ -215,6 +210,15 @@ public class SearchAdapter extends BaseAdapter implements Filterable { @@ -215,6 +210,15 @@ public class SearchAdapter extends BaseAdapter implements Filterable {
return mFilter;
}
private static class ClearCacheRunnable implements Runnable {
@Override
public void run() {
deleteOldCacheFiles();
}
}
private class SearchFilter extends Filter {
@Override
@ -225,7 +229,7 @@ public class SearchAdapter extends BaseAdapter implements Filterable { @@ -225,7 +229,7 @@ public class SearchAdapter extends BaseAdapter implements Filterable {
}
String query = constraint.toString().toLowerCase(Locale.getDefault());
if (mUseGoogle && !mIncognito && !mIsExecuting) {
new RetrieveSearchSuggestions().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, query);
new RetrieveSearchSuggestions().executeOnExecutor(AsyncTask.SERIAL_EXECUTOR, query);
}
int counter = 0;
@ -275,7 +279,7 @@ public class SearchAdapter extends BaseAdapter implements Filterable { @@ -275,7 +279,7 @@ public class SearchAdapter extends BaseAdapter implements Filterable {
}
private class SuggestionHolder {
private static class SuggestionHolder {
ImageView mImage;
TextView mTitle;
TextView mUrl;
@ -293,7 +297,7 @@ public class SearchAdapter extends BaseAdapter implements Filterable { @@ -293,7 +297,7 @@ public class SearchAdapter extends BaseAdapter implements Filterable {
List<HistoryItem> filter = new ArrayList<>();
String query = arg0[0];
try {
query = query.replace(" ", "+");
query = SPACE_PATTERN.matcher(query).replaceAll("+");
URLEncoder.encode(query, ENCODING);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
@ -337,6 +341,7 @@ public class SearchAdapter extends BaseAdapter implements Filterable { @@ -337,6 +341,7 @@ public class SearchAdapter extends BaseAdapter implements Filterable {
@Override
protected void onPostExecute(List<HistoryItem> result) {
mIsExecuting = false;
synchronized (mSuggestions) {
mSuggestions.clear();
mSuggestions.addAll(result);
@ -348,7 +353,6 @@ public class SearchAdapter extends BaseAdapter implements Filterable { @@ -348,7 +353,6 @@ public class SearchAdapter extends BaseAdapter implements Filterable {
mFilteredList.addAll(filtered);
notifyDataSetChanged();
}
mIsExecuting = false;
}
}
@ -356,6 +360,7 @@ public class SearchAdapter extends BaseAdapter implements Filterable { @@ -356,6 +360,7 @@ public class SearchAdapter extends BaseAdapter implements Filterable {
/**
* This method downloads the search suggestions for the specific query.
* NOTE: This is a blocking operation, do not run on the UI thread.
*
* @param query the query to get suggestions for
* @return the cache file containing the suggestions
*/
@ -409,32 +414,6 @@ public class SearchAdapter extends BaseAdapter implements Filterable { @@ -409,32 +414,6 @@ public class SearchAdapter extends BaseAdapter implements Filterable {
return connectivity.getActiveNetworkInfo();
}
// The old suggestions algorithm, leaving here just for reference
// private List<HistoryItem> getSuggestions() {
// List<HistoryItem> filteredList = new ArrayList<>();
//
// int suggestionsSize = mSuggestions.size();
// int historySize = mHistory.size();
// int bookmarkSize = mBookmarks.size();
//
// int maxSuggestions = (bookmarkSize + historySize < 3) ? (5 - bookmarkSize - historySize) : (bookmarkSize < 2) ? (4 - bookmarkSize) : (historySize < 1) ? 3 : 2;
// int maxHistory = (suggestionsSize + bookmarkSize < 4) ? (5 - suggestionsSize - bookmarkSize) : 1;
// int maxBookmarks = (suggestionsSize + historySize < 3) ? (5 - suggestionsSize - historySize) : 2;
//
// for (int n = 0; n < bookmarkSize && n < maxBookmarks; n++) {
// filteredList.add(mBookmarks.get(n));
// }
//
// for (int n = 0; n < historySize && n < maxHistory; n++) {
// filteredList.add(mHistory.get(n));
// }
//
// for (int n = 0; n < suggestionsSize && n < maxSuggestions; n++) {
// filteredList.add(mSuggestions.get(n));
// }
// return filteredList;
// }
private List<HistoryItem> getFilteredList() {
List<HistoryItem> list = new ArrayList<>(5);
synchronized (mBookmarks) {

10
app/src/main/java/acr/browser/lightning/preference/PreferenceManager.java

@ -2,13 +2,13 @@ package acr.browser.lightning.preference; @@ -2,13 +2,13 @@ package acr.browser.lightning.preference;
import android.content.Context;
import android.content.SharedPreferences;
import android.os.Environment;
import javax.inject.Inject;
import javax.inject.Singleton;
import acr.browser.lightning.app.BrowserApp;
import acr.browser.lightning.constant.Constants;
import acr.browser.lightning.download.DownloadHandler;
@Singleton
public class PreferenceManager {
@ -19,7 +19,7 @@ public class PreferenceManager { @@ -19,7 +19,7 @@ public class PreferenceManager {
public static final String BLOCK_IMAGES = "blockimages";
public static final String CLEAR_CACHE_EXIT = "cache";
public static final String COOKIES = "cookies";
public static final String DOWNLOAD_DIRECTORY = "download";
public static final String DOWNLOAD_DIRECTORY = "downloadLocation";
public static final String FULL_SCREEN = "fullscreen";
public static final String HIDE_STATUS_BAR = "hidestatus";
public static final String HOMEPAGE = "home";
@ -115,7 +115,7 @@ public class PreferenceManager { @@ -115,7 +115,7 @@ public class PreferenceManager {
}
public String getDownloadDirectory() {
return mPrefs.getString(Name.DOWNLOAD_DIRECTORY, Environment.DIRECTORY_DOWNLOADS);
return mPrefs.getString(Name.DOWNLOAD_DIRECTORY, DownloadHandler.DEFAULT_DOWNLOAD_PATH);
}
public int getFlashSupport() {
@ -242,7 +242,7 @@ public class PreferenceManager { @@ -242,7 +242,7 @@ public class PreferenceManager {
return mPrefs.getString(Name.TEXT_ENCODING, Constants.DEFAULT_ENCODING);
}
public boolean getShowTabsInDrawer(boolean defaultValue){
public boolean getShowTabsInDrawer(boolean defaultValue) {
return mPrefs.getBoolean(Name.SHOW_TABS_IN_DRAWER, defaultValue);
}
@ -258,7 +258,7 @@ public class PreferenceManager { @@ -258,7 +258,7 @@ public class PreferenceManager {
mPrefs.edit().putString(name, value).apply();
}
public void setShowTabsInDrawer(boolean show){
public void setShowTabsInDrawer(boolean show) {
putBoolean(Name.SHOW_TABS_IN_DRAWER, show);
}

30
app/src/main/java/acr/browser/lightning/reading/ArticleTextExtractor.java

@ -385,16 +385,16 @@ public class ArticleTextExtractor { @@ -385,16 +385,16 @@ public class ArticleTextExtractor {
// System.out.println("date modified element " + elem.toString());
}
if (dateStr != null && dateStr.isEmpty()) {
if (dateStr.isEmpty()) {
dateStr = SHelper.innerTrim(doc.select("meta[name=utime]").attr("content"));
}
if (dateStr != null && dateStr.isEmpty()) {
if (dateStr.isEmpty()) {
dateStr = SHelper.innerTrim(doc.select("meta[name=pdate]").attr("content"));
}
if (dateStr != null && dateStr.isEmpty()) {
if (dateStr.isEmpty()) {
dateStr = SHelper.innerTrim(doc.select("meta[property=article:published]").attr("content"));
}
if (dateStr != null && dateStr.isEmpty()) {
if (dateStr.isEmpty()) {
return parseDate(dateStr);
}
@ -492,9 +492,7 @@ public class ArticleTextExtractor { @@ -492,9 +492,7 @@ public class ArticleTextExtractor {
if (el.hasAttr("content")) {
dateStr = el.attr("content");
Date parsedDate = parseDate(dateStr);
if (parsedDate != null) {
return parsedDate;
}
return parsedDate;
}
}
@ -686,14 +684,12 @@ public class ArticleTextExtractor { @@ -686,14 +684,12 @@ public class ArticleTextExtractor {
private static Collection<String> extractKeywords(Document doc) {
String content = SHelper.innerTrim(doc.select("head meta[name=keywords]").attr("content"));
if (content != null) {
if (content.startsWith("[") && content.endsWith("]"))
content = content.substring(1, content.length() - 1);
if (content.startsWith("[") && content.endsWith("]"))
content = content.substring(1, content.length() - 1);
String[] split = content.split("\\s*,\\s*");
if (split.length > 1 || (split.length > 0 && split[0] != null && !split[0].isEmpty()))
return Arrays.asList(split);
}
String[] split = content.split("\\s*,\\s*");
if (split.length > 1 || (split.length > 0 && split[0] != null && !split[0].isEmpty()))
return Arrays.asList(split);
return Collections.emptyList();
}
@ -968,7 +964,7 @@ public class ArticleTextExtractor { @@ -968,7 +964,7 @@ public class ArticleTextExtractor {
return weight;
}
private Element determineImageSource(Element el, List<ImageResult> images) {
private static Element determineImageSource(Element el, List<ImageResult> images) {
int maxWeight = 0;
Element maxNode = null;
Elements els = el.select("img");
@ -1190,7 +1186,7 @@ public class ArticleTextExtractor { @@ -1190,7 +1186,7 @@ public class ArticleTextExtractor {
charlen = 4;
} else if (c <= 0xdfff) {
charlen = 0;
} else if (c <= 0xffff) {
} else {
charlen = 3;
}
if (resultlen + charlen > length) {
@ -1208,7 +1204,7 @@ public class ArticleTextExtractor { @@ -1208,7 +1204,7 @@ public class ArticleTextExtractor {
*
* @author Chris Alexander, chris@chris-alexander.co.uk
*/
private class ImageComparator implements Comparator<ImageResult> {
private static class ImageComparator implements Comparator<ImageResult> {
@Override
public int compare(ImageResult o1, ImageResult o2) {

22
app/src/main/java/acr/browser/lightning/reading/Converter.java

@ -35,9 +35,9 @@ import acr.browser.lightning.constant.Constants; @@ -35,9 +35,9 @@ import acr.browser.lightning.constant.Constants;
*/
public class Converter {
public final static String UTF8 = "UTF-8";
public final static String ISO = "ISO-8859-1";
public final static int K2 = 2048;
private final static String UTF8 = "UTF-8";
private final static String ISO = "ISO-8859-1";
private final static int K2 = 2048;
private int maxBytes = 1000000 / 2;
private String encoding;
private String url;
@ -99,7 +99,7 @@ public class Converter { @@ -99,7 +99,7 @@ public class Converter {
* The max bytes that we want to read from the input stream
* @return String
*/
public String streamToString(InputStream is, int maxBytes, String enc) {
private String streamToString(InputStream is, int maxBytes, String enc) {
encoding = enc;
// Http 1.1. standard is iso-8859-1 not utf8 :(
// but we force utf-8 as youtube assumes it ;)
@ -181,8 +181,8 @@ public class Converter { @@ -181,8 +181,8 @@ public class Converter {
*
* @throws IOException
*/
protected static String detectCharset(String key, ByteArrayOutputStream bos, BufferedInputStream in,
String enc) throws IOException {
private static String detectCharset(String key, ByteArrayOutputStream bos, BufferedInputStream in,
String enc) throws IOException {
// Grab better encoding from stream
byte[] arr = new byte[K2];
@ -204,24 +204,24 @@ public class Converter { @@ -204,24 +204,24 @@ public class Converter {
int lastEncIndex;
if (startChar == '\'')
// if we have charset='something'
lastEncIndex = str.indexOf("'", ++encIndex + clength);
lastEncIndex = str.indexOf('\'', ++encIndex + clength);
else if (startChar == '\"')
// if we have charset="something"
lastEncIndex = str.indexOf("\"", ++encIndex + clength);
lastEncIndex = str.indexOf('\"', ++encIndex + clength);
else {
// if we have "text/html; charset=utf-8"
int first = str.indexOf("\"", encIndex + clength);
int first = str.indexOf('\"', encIndex + clength);
if (first < 0)
first = Integer.MAX_VALUE;
// or "text/html; charset=utf-8 "
int sec = str.indexOf(" ", encIndex + clength);
int sec = str.indexOf(' ', encIndex + clength);
if (sec < 0)
sec = Integer.MAX_VALUE;
lastEncIndex = Math.min(first, sec);
// or "text/html; charset=utf-8 '
int third = str.indexOf("'", encIndex + clength);
int third = str.indexOf('\'', encIndex + clength);
if (third > 0)
lastEncIndex = Math.min(lastEncIndex, third);
}

33
app/src/main/java/acr/browser/lightning/reading/HtmlFetcher.java

@ -28,6 +28,7 @@ import java.net.URL; @@ -28,6 +28,7 @@ import java.net.URL;
import java.util.LinkedHashSet;
import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.regex.Pattern;
import java.util.zip.GZIPInputStream;
import java.util.zip.Inflater;
import java.util.zip.InflaterInputStream;
@ -39,6 +40,8 @@ import java.util.zip.InflaterInputStream; @@ -39,6 +40,8 @@ import java.util.zip.InflaterInputStream;
*/
public class HtmlFetcher {
private static final Pattern SPACE = Pattern.compile(" ");
static {
SHelper.enableCookieMgmt();
SHelper.enableUserAgentOverwrite();
@ -50,8 +53,8 @@ public class HtmlFetcher { @@ -50,8 +53,8 @@ public class HtmlFetcher {
String line;
Set<String> existing = new LinkedHashSet<>();
while ((line = reader.readLine()) != null) {
int index1 = line.indexOf("\"");
int index2 = line.indexOf("\"", index1 + 1);
int index1 = line.indexOf('\"');
int index2 = line.indexOf('\"', index1 + 1);
String url = line.substring(index1 + 1, index2);
String domainStr = SHelper.extractDomain(url, true);
String counterStr = "";
@ -204,8 +207,8 @@ public class HtmlFetcher { @@ -204,8 +207,8 @@ public class HtmlFetcher {
// main workhorse to call externally
@SuppressWarnings("SynchronizationOnLocalVariableOrMethodParameter")
public JResult fetchAndExtract(String url, int timeout, boolean resolve,
int maxContentSize, boolean forceReload) throws Exception {
private JResult fetchAndExtract(String url, int timeout, boolean resolve,
int maxContentSize, boolean forceReload) throws Exception {
String originalUrl = url;
url = SHelper.removeHashbang(url);
String gUrl = SHelper.getUrlFromUglyGoogleRedirect(url);
@ -298,7 +301,7 @@ public class HtmlFetcher { @@ -298,7 +301,7 @@ public class HtmlFetcher {
}
// Ugly hack to break free from any cached versions, a few URLs required this.
public static String getURLtoBreakCache(String url) {
private static String getURLtoBreakCache(String url) {
try {
URL aURL = new URL(url);
if (aURL.getQuery() != null && aURL.getQuery().isEmpty()) {
@ -311,7 +314,7 @@ public class HtmlFetcher { @@ -311,7 +314,7 @@ public class HtmlFetcher {
}
}
public String lessText(String text) {
private String lessText(String text) {
if (text == null)
return "";
@ -325,13 +328,13 @@ public class HtmlFetcher { @@ -325,13 +328,13 @@ public class HtmlFetcher {
return SHelper.useDomainOfFirstArg4Second(url, urlOrPath);
}
public String fetchAsString(String urlAsString, int timeout)
private String fetchAsString(String urlAsString, int timeout)
throws IOException {
return fetchAsString(urlAsString, timeout, true);
}
// main routine to get raw webpage content
public String fetchAsString(String urlAsString, int timeout, boolean includeSomeGooseOptions)
private String fetchAsString(String urlAsString, int timeout, boolean includeSomeGooseOptions)
throws IOException {
HttpURLConnection hConn = createUrlConnection(urlAsString, timeout, includeSomeGooseOptions);
hConn.setInstanceFollowRedirects(true);
@ -349,7 +352,7 @@ public class HtmlFetcher { @@ -349,7 +352,7 @@ public class HtmlFetcher {
return createConverter(urlAsString).streamToString(is, enc);
}
public static Converter createConverter(String url) {
private static Converter createConverter(String url) {
return new Converter(url);
}
@ -361,8 +364,8 @@ public class HtmlFetcher { @@ -361,8 +364,8 @@ public class HtmlFetcher {
* @return the resolved url if any. Or null if it couldn't resolve the url
* (within the specified time) or the same url if response code is OK
*/
public String getResolvedUrl(String urlAsString, int timeout,
int num_redirects) {
private String getResolvedUrl(String urlAsString, int timeout,
int num_redirects) {
String newUrl = null;
int responseCode = -1;
try {
@ -381,7 +384,7 @@ public class HtmlFetcher { @@ -381,7 +384,7 @@ public class HtmlFetcher {
newUrl = hConn.getHeaderField("Location");
// Note that the max recursion level is 5.
if (responseCode / 100 == 3 && newUrl != null && num_redirects < 5) {
newUrl = newUrl.replaceAll(" ", "+");
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"))
@ -413,7 +416,7 @@ public class HtmlFetcher { @@ -413,7 +416,7 @@ public class HtmlFetcher {
* to non-ASCII characters. Workaround for broken origin servers that send
* UTF-8 in the Location: header.
*/
static String encodeUriFromHeader(String badLocation) {
private static String encodeUriFromHeader(String badLocation) {
StringBuilder sb = new StringBuilder(badLocation.length());
for (char ch : badLocation.toCharArray()) {
@ -428,8 +431,8 @@ public class HtmlFetcher { @@ -428,8 +431,8 @@ public class HtmlFetcher {
return sb.toString();
}
protected HttpURLConnection createUrlConnection(String urlAsStr, int timeout,
boolean includeSomeGooseOptions) throws IOException {
private HttpURLConnection createUrlConnection(String urlAsStr, int timeout,
boolean includeSomeGooseOptions) throws IOException {
URL url = new URL(urlAsStr);
//using proxy may increase latency
HttpURLConnection hConn = (HttpURLConnection) url.openConnection(Proxy.NO_PROXY);

14
app/src/main/java/acr/browser/lightning/reading/ImageResult.java

@ -7,15 +7,15 @@ import org.jsoup.nodes.Element; @@ -7,15 +7,15 @@ import org.jsoup.nodes.Element;
*
* @author Chris Alexander, chris@chris-alexander.co.uk
*/
public class ImageResult {
class ImageResult {
public final String src;
private final String src;
public final Integer weight;
public final String title;
public final int height;
public final int width;
public final String alt;
public final boolean noFollow;
private final String title;
private final int height;
private final int width;
private final String alt;
private final boolean noFollow;
public Element element;
public ImageResult(String src, Integer weight, String title, int height, int width, String alt,

4
app/src/main/java/acr/browser/lightning/reading/JResult.java

@ -47,7 +47,7 @@ public class JResult implements Serializable { @@ -47,7 +47,7 @@ public class JResult implements Serializable {
private Date date;
private Collection<String> keywords;
private List<ImageResult> images = null;
private List<Map<String, String>> links = new ArrayList<>();
private final List<Map<String, String>> links = new ArrayList<>();
private String type;
private String sitename;
private String language;
@ -230,7 +230,7 @@ public class JResult implements Serializable { @@ -230,7 +230,7 @@ public class JResult implements Serializable {
}
public void addLink(String url, String text, Integer pos) {
Map link = new HashMap();
Map<String, String> link = new HashMap<>();
link.put("url", url);
link.put("text", text);
link.put("offset", String.valueOf(pos));

26
app/src/main/java/acr/browser/lightning/reading/OutputFormatter.java

@ -41,8 +41,8 @@ public class OutputFormatter { @@ -41,8 +41,8 @@ public class OutputFormatter {
this(minFirstParagraphText, minParagraphText, NODES_TO_REPLACE);
}
public OutputFormatter(int minFirstParagraphText, int minParagraphText,
List<String> nodesToReplace) {
private OutputFormatter(int minFirstParagraphText, int minParagraphText,
List<String> nodesToReplace) {
this.minFirstParagraphText = minFirstParagraphText;
this.minParagraphText = minParagraphText;
this.nodesToReplace = nodesToReplace;
@ -91,7 +91,7 @@ public class OutputFormatter { @@ -91,7 +91,7 @@ public class OutputFormatter {
* If there are elements inside our top node that have a negative gravity
* score remove them
*/
protected void removeNodesWithNegativeScores(Element topNode) {
private void removeNodesWithNegativeScores(Element topNode) {
Elements gravityItems = topNode.select("*[gravityScore]");
for (Element item : gravityItems) {
int score = getScore(item);
@ -102,7 +102,7 @@ public class OutputFormatter { @@ -102,7 +102,7 @@ public class OutputFormatter {
}
}
protected int append(Element node, StringBuilder sb, String tagName) {
private int append(Element node, StringBuilder sb, String tagName) {
int countOfP = 0; // Number of P elements in the article
int paragraphWithTextIndex = 0;
// is select more costly then getElementsByTag?
@ -134,14 +134,14 @@ public class OutputFormatter { @@ -134,14 +134,14 @@ public class OutputFormatter {
return countOfP;
}
protected static void setParagraphIndex(Element node, String tagName) {
private static void setParagraphIndex(Element node, String tagName) {
int paragraphIndex = 0;
for (Element e : node.select(tagName)) {
e.attr("paragraphIndex", Integer.toString(paragraphIndex++));
}
}
protected int getMinParagraph(int paragraphIndex) {
private int getMinParagraph(int paragraphIndex) {
if (paragraphIndex < 1) {
return minFirstParagraphText;
} else {
@ -149,7 +149,7 @@ public class OutputFormatter { @@ -149,7 +149,7 @@ public class OutputFormatter {
}
}
protected static int getParagraphIndex(Element el) {
private static int getParagraphIndex(Element el) {
try {
return Integer.parseInt(el.attr("paragraphIndex"));
} catch (NumberFormatException ex) {
@ -157,7 +157,7 @@ public class OutputFormatter { @@ -157,7 +157,7 @@ public class OutputFormatter {
}
}
protected static int getScore(Element el) {
private static int getScore(Element el) {
try {
return Integer.parseInt(el.attr("gravityScore"));
} catch (Exception ex) {
@ -165,7 +165,7 @@ public class OutputFormatter { @@ -165,7 +165,7 @@ public class OutputFormatter {
}
}
boolean unlikely(Node e) {
private boolean unlikely(Node e) {
if (e.attr("class") != null && e.attr("class").toLowerCase().contains("caption"))
return true;
@ -174,7 +174,7 @@ public class OutputFormatter { @@ -174,7 +174,7 @@ public class OutputFormatter {
return unlikelyPattern.matcher(style).find() || unlikelyPattern.matcher(clazz).find();
}
void appendTextSkipHidden(Element e, StringBuilder accum, int indent) {
private void appendTextSkipHidden(Element e, StringBuilder accum, int indent) {
for (Node child : e.childNodes()) {
if (unlikely(child)) {
continue;
@ -195,17 +195,17 @@ public class OutputFormatter { @@ -195,17 +195,17 @@ public class OutputFormatter {
}
}
static boolean lastCharIsWhitespace(StringBuilder accum) {
private static boolean lastCharIsWhitespace(StringBuilder accum) {
return accum.length() != 0 && Character.isWhitespace(accum.charAt(accum.length() - 1));
}
protected String node2Text(Element el) {
private String node2Text(Element el) {
StringBuilder sb = new StringBuilder(200);
appendTextSkipHidden(el, sb, 0);
return sb.toString();
}
public OutputFormatter setUnlikelyPattern(String unlikelyPattern) {
private OutputFormatter setUnlikelyPattern(String unlikelyPattern) {
this.unlikelyPattern = Pattern.compile(unlikelyPattern);
return this;
}

12
app/src/main/java/acr/browser/lightning/reading/SHelper.java

@ -39,9 +39,9 @@ import javax.net.ssl.X509TrustManager; @@ -39,9 +39,9 @@ import javax.net.ssl.X509TrustManager;
/**
* @author Peter Karich
*/
public class SHelper {
class SHelper {
public static final String UTF8 = "UTF-8";
private static final String UTF8 = "UTF-8";
private static final Pattern SPACE = Pattern.compile(" ");
public static String replaceSpaces(String url) {
@ -122,7 +122,7 @@ public class SHelper { @@ -122,7 +122,7 @@ public class SHelper {
return str1.substring(res[0], res[1]);
}
public static int[] longestSubstring(String str1, String str2) {
private static int[] longestSubstring(String str1, String str2) {
if (str1 == null || str1.isEmpty() || str2 == null || str2.isEmpty())
return null;
@ -193,7 +193,7 @@ public class SHelper { @@ -193,7 +193,7 @@ public class SHelper {
url = url.substring("m.".length());
}
int slashIndex = url.indexOf("/");
int slashIndex = url.indexOf('/');
if (slashIndex > 0)
url = url.substring(0, slashIndex);
@ -280,7 +280,7 @@ public class SHelper { @@ -280,7 +280,7 @@ public class SHelper {
}
}
public static String urlDecode(String str) {
private static String urlDecode(String str) {
try {
return URLDecoder.decode(str, UTF8);
} catch (UnsupportedEncodingException ex) {
@ -300,7 +300,7 @@ public class SHelper { @@ -300,7 +300,7 @@ public class SHelper {
return printNode(root, 0);
}
public static String printNode(Element root, int indentation) {
private static String printNode(Element root, int indentation) {
StringBuilder sb = new StringBuilder(indentation);
for (int i = 0; i < indentation; i++) {
sb.append(' ');

5
app/src/main/java/acr/browser/lightning/utils/AdBlock.java

@ -58,8 +58,9 @@ public class AdBlock { @@ -58,8 +58,9 @@ public class AdBlock {
@Override
public void run() {
AssetManager asset = context.getAssets();
BufferedReader reader = null;
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(
reader = new BufferedReader(new InputStreamReader(
asset.open(BLOCKED_DOMAINS_LIST_FILE_NAME)));
String line;
while ((line = reader.readLine()) != null) {
@ -68,6 +69,8 @@ public class AdBlock { @@ -68,6 +69,8 @@ public class AdBlock {
} catch (IOException e) {
Log.wtf(TAG, "Reading blocked domains list from file '"
+ BLOCKED_DOMAINS_LIST_FILE_NAME + "' failed.", e);
} finally {
Utils.close(reader);
}
}
});

6
app/src/main/java/acr/browser/lightning/utils/IntentUtils.java

@ -16,8 +16,6 @@ import java.util.List; @@ -16,8 +16,6 @@ import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import acr.browser.lightning.controller.BrowserController;
public class IntentUtils {
private final Context mActivity;
@ -29,8 +27,8 @@ public class IntentUtils { @@ -29,8 +27,8 @@ public class IntentUtils {
"(?:http|https|file):\\/\\/" + "|(?:inline|data|about|javascript):" + "|(?:.*:.*@)"
+ ')' + "(.*)");
public IntentUtils(Context context) {
mActivity = context.getApplicationContext();
public IntentUtils(Activity activity) {
mActivity = activity;
}
public boolean startActivityForUrl(WebView tab, String url) {

42
app/src/main/java/acr/browser/lightning/utils/ThemeUtils.java

@ -1,7 +1,6 @@ @@ -1,7 +1,6 @@
package acr.browser.lightning.utils;
import android.content.Context;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
@ -12,11 +11,11 @@ import android.graphics.PorterDuff; @@ -12,11 +11,11 @@ import android.graphics.PorterDuff;
import android.graphics.PorterDuffColorFilter;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.support.annotation.AttrRes;
import android.support.annotation.DrawableRes;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.content.ContextCompat;
import android.util.TypedValue;
import android.widget.ImageView;
@ -46,17 +45,11 @@ public class ThemeUtils { @@ -46,17 +45,11 @@ public class ThemeUtils {
}
public static int getIconLightThemeColor(@NonNull Context context) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
return context.getResources().getColor(R.color.icon_light_theme, context.getTheme());
}
return context.getResources().getColor(R.color.icon_light_theme);
return ContextCompat.getColor(context, R.color.icon_light_theme);
}
public static int getIconDarkThemeColor(@NonNull Context context) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
return context.getResources().getColor(R.color.icon_dark_theme, context.getTheme());
}
return context.getResources().getColor(R.color.icon_dark_theme);
return ContextCompat.getColor(context, R.color.icon_dark_theme);
}
public static void themeImageView(ImageView icon, Context context, boolean dark) {
@ -80,12 +73,7 @@ public class ThemeUtils { @@ -80,12 +73,7 @@ public class ThemeUtils {
@Nullable
public static Drawable getThemedDrawable(@NonNull Context context, @DrawableRes int res, boolean dark) {
int color = dark ? getIconDarkThemeColor(context) : getIconLightThemeColor(context);
final Drawable drawable;
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
drawable = context.getResources().getDrawable(res);
} else {
drawable = context.getDrawable(res);
}
final Drawable drawable = ContextCompat.getDrawable(context, res);
if (drawable == null)
return null;
drawable.mutate();
@ -95,12 +83,7 @@ public class ThemeUtils { @@ -95,12 +83,7 @@ public class ThemeUtils {
@Nullable
public static Drawable getLightThemedDrawable(@NonNull Context context, @DrawableRes int res) {
final Drawable drawable;
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
drawable = context.getResources().getDrawable(res);
} else {
drawable = context.getDrawable(res);
}
final Drawable drawable = ContextCompat.getDrawable(context, res);
if (drawable == null)
return null;
drawable.mutate();
@ -109,15 +92,12 @@ public class ThemeUtils { @@ -109,15 +92,12 @@ public class ThemeUtils {
}
public static ColorDrawable getSelectedBackground(@NonNull Context context, boolean dark) {
Resources res = context.getResources();
int color;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
color = (dark) ? res.getColor(R.color.selected_dark, context.getTheme()) :
res.getColor(R.color.selected_light, context.getTheme());
} else {
color = (dark) ? res.getColor(R.color.selected_dark) :
res.getColor(R.color.selected_light);
}
final int color = (dark) ? ContextCompat.getColor(context, R.color.selected_dark) :
ContextCompat.getColor(context, R.color.selected_light);
return new ColorDrawable(color);
}
public static int getTextColor(Context context) {
return getColor(context, android.R.attr.editTextColor);
}
}

2
app/src/main/java/acr/browser/lightning/utils/UrlUtils.java

@ -25,7 +25,7 @@ import java.util.regex.Pattern; @@ -25,7 +25,7 @@ import java.util.regex.Pattern;
* Utility methods for Url manipulation
*/
public class UrlUtils {
static final Pattern ACCEPTED_URI_SCHEMA = Pattern.compile(
private static final Pattern ACCEPTED_URI_SCHEMA = Pattern.compile(
"(?i)" + // switch on case insensitive matching
'(' + // begin group for schema
"(?:http|https|file):\\/\\/" +

13
app/src/main/java/acr/browser/lightning/utils/Utils.java

@ -18,10 +18,7 @@ import android.graphics.LinearGradient; @@ -18,10 +18,7 @@ import android.graphics.LinearGradient;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Shader;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.os.Environment;
import android.support.annotation.DrawableRes;
import android.support.annotation.NonNull;
import android.support.annotation.StringRes;
import android.support.design.widget.Snackbar;
@ -151,7 +148,7 @@ public final class Utils { @@ -151,7 +148,7 @@ public final class Utils {
}
}
public static boolean deleteDir(File dir) {
private static boolean deleteDir(File dir) {
if (dir != null && dir.isDirectory()) {
String[] children = dir.list();
for (String aChildren : children) {
@ -262,14 +259,6 @@ public final class Utils { @@ -262,14 +259,6 @@ public final class Utils {
}
}
public static Drawable getDrawable(Context context, @DrawableRes int res) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
return context.getDrawable(res);
} else {
return context.getResources().getDrawable(res);
}
}
/**
* Draws the trapezoid background for the horizontal tabs on a canvas object using
* the specified color.

4
app/src/main/java/acr/browser/lightning/utils/WebUtils.java

@ -23,7 +23,9 @@ public class WebUtils { @@ -23,7 +23,9 @@ public class WebUtils {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
c.removeAllCookies(null);
} else {
//noinspection deprecation
CookieSyncManager.createInstance(context);
//noinspection deprecation
c.removeAllCookie();
}
}
@ -38,7 +40,9 @@ public class WebUtils { @@ -38,7 +40,9 @@ public class WebUtils {
m.clearFormData();
m.clearHttpAuthUsernamePassword();
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR2) {
//noinspection deprecation
m.clearUsernamePassword();
//noinspection deprecation
WebIconDatabase.getInstance().removeAllIcons();
}
Utils.trimCache(context);

44
app/src/main/java/acr/browser/lightning/view/IconCacheTask.java

@ -0,0 +1,44 @@ @@ -0,0 +1,44 @@
package acr.browser.lightning.view;
import android.graphics.Bitmap;
import android.net.Uri;
import android.util.Log;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import acr.browser.lightning.app.BrowserApp;
import acr.browser.lightning.constant.Constants;
import acr.browser.lightning.utils.Utils;
/**
* @author Anthony C. Restaino
* @date 2015/09/29
*/
class IconCacheTask implements Runnable{
private final Uri uri;
private final Bitmap icon;
public IconCacheTask(Uri uri, Bitmap icon) {
this.uri = uri;
this.icon = icon;
}
@Override
public void run() {
String hash = String.valueOf(uri.getHost().hashCode());
Log.d(Constants.TAG, "Caching icon for " + uri.getHost());
FileOutputStream fos = null;
try {
File image = new File(BrowserApp.getAppContext().getCacheDir(), hash + ".png");
fos = new FileOutputStream(image);
icon.compress(Bitmap.CompressFormat.PNG, 100, fos);
fos.flush();
} catch (IOException e) {
e.printStackTrace();
} finally {
Utils.close(fos);
}
}
}

42
app/src/main/java/acr/browser/lightning/view/LightningView.java

@ -108,7 +108,9 @@ public class LightningView { @@ -108,7 +108,9 @@ public class LightningView {
mWebView.setDrawingCacheEnabled(false);
mWebView.setWillNotCacheDrawing(true);
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.LOLLIPOP_MR1) {
//noinspection deprecation
mWebView.setAnimationCacheEnabled(false);
//noinspection deprecation
mWebView.setAlwaysDrawnWithCacheEnabled(false);
}
mWebView.setBackgroundColor(Color.WHITE);
@ -206,12 +208,15 @@ public class LightningView { @@ -206,12 +208,15 @@ public class LightningView {
if (API < Build.VERSION_CODES.KITKAT) {
switch (mPreferences.getFlashSupport()) {
case 0:
//noinspection deprecation
settings.setPluginState(PluginState.OFF);
break;
case 1:
//noinspection deprecation
settings.setPluginState(PluginState.ON_DEMAND);
break;
case 2:
//noinspection deprecation
settings.setPluginState(PluginState.ON);
break;
default:
@ -222,12 +227,14 @@ public class LightningView { @@ -222,12 +227,14 @@ public class LightningView {
setUserAgent(context, mPreferences.getUserAgentChoice());
if (mPreferences.getSavePasswordsEnabled() && !mIsIncognitoTab) {
if (API < 18) {
if (API < Build.VERSION_CODES.JELLY_BEAN_MR2) {
//noinspection deprecation
settings.setSavePassword(true);
}
settings.setSaveFormData(true);
} else {
if (API < 18) {
if (API < Build.VERSION_CODES.JELLY_BEAN_MR2) {
//noinspection deprecation
settings.setSavePassword(false);
}
settings.setSaveFormData(false);
@ -300,9 +307,11 @@ public class LightningView { @@ -300,9 +307,11 @@ public class LightningView {
@SuppressLint("NewApi")
private void initializeSettings(WebSettings settings, Context context) {
if (API < Build.VERSION_CODES.JELLY_BEAN_MR2) {
//noinspection deprecation
settings.setAppCacheMaxSize(Long.MAX_VALUE);
}
if (API < Build.VERSION_CODES.JELLY_BEAN_MR1) {
//noinspection deprecation
settings.setEnableSmoothTransition(true);
}
if (API > Build.VERSION_CODES.JELLY_BEAN) {
@ -338,6 +347,7 @@ public class LightningView { @@ -338,6 +347,7 @@ public class LightningView {
settings.setAppCachePath(context.getDir("appcache", 0).getPath());
settings.setGeolocationDatabasePath(context.getDir("geolocation", 0).getPath());
if (API < Build.VERSION_CODES.KITKAT) {
//noinspection deprecation
settings.setDatabasePath(context.getDir("databases", 0).getPath());
}
}
@ -353,7 +363,7 @@ public class LightningView { @@ -353,7 +363,7 @@ public class LightningView {
}
@SuppressLint("NewApi")
public void setUserAgent(Context context, int choice) {
private void setUserAgent(Context context, int choice) {
if (mWebView == null) return;
WebSettings settings = mWebView.getSettings();
switch (choice) {
@ -395,9 +405,11 @@ public class LightningView { @@ -395,9 +405,11 @@ public class LightningView {
}
public synchronized void freeMemory() {
if (mWebView != null && Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT)
if (mWebView != null && Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
//noinspection deprecation
mWebView.freeMemory();
}
}
public void setForegroundTab(boolean isForeground) {
isForegroundTab = isForeground;
@ -514,12 +526,26 @@ public class LightningView { @@ -514,12 +526,26 @@ public class LightningView {
}
}
/**
* Naive caching of the favicon according to the domain name of the URL
* @param icon the icon to cache
*/
private void cacheFavicon(final Bitmap icon) {
if (icon == null) return;
final Uri uri = Uri.parse(getUrl());
if (uri.getHost() == null) {
return;
}
new Thread(new IconCacheTask(uri, icon)).start();
}
@SuppressLint("NewApi")
public synchronized void find(String text) {
if (mWebView != null) {
if (API >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
mWebView.findAllAsync(text);
} else {
//noinspection deprecation
mWebView.findAll(text);
}
}
@ -640,12 +666,6 @@ public class LightningView { @@ -640,12 +666,6 @@ public class LightningView {
}
}
public synchronized void invalidate() {
if (mWebView != null) {
mWebView.invalidate();
}
}
public String getTitle() {
return mTitle.getTitle();
}
@ -722,7 +742,7 @@ public class LightningView { @@ -722,7 +742,7 @@ public class LightningView {
msg.setTarget(webViewHandler);
mWebView.requestFocusNodeHref(msg);
}
}
}
}
/**

3
app/src/main/res/layout/two_line_autocomplete.xml

@ -21,7 +21,8 @@ @@ -21,7 +21,8 @@
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingLeft="5dp">
android:paddingLeft="5dp"
android:paddingRight="5dp">
<TextView
android:id="@+id/title"

2
app/src/main/res/values/colors.xml

@ -33,4 +33,6 @@ @@ -33,4 +33,6 @@
<color name="icon_light_theme">#8A000000</color>
<color name="icon_dark_theme">#FFFFFFFF</color>
<color name="error_red">#F44336</color>
</resources>

1
app/src/main/res/values/dimens.xml

@ -3,6 +3,5 @@ @@ -3,6 +3,5 @@
<!-- Default screen margins, per the Android Design guidelines. -->
<dimen name="navigation_width">260dp</dimen>
<dimen name="search_bar_height">48dp</dimen>
<dimen name="abc_action_button_min_width_overflow_material">48dp</dimen>
</resources>

2
app/src/main/res/values/strings.xml

@ -101,6 +101,8 @@ @@ -101,6 +101,8 @@
<string name="action_find">Find in Page</string>
<string name="download_pending">Starting download\u2026</string>
<string name="cannot_download">Can only download \"http\" or \"https\" URLs.</string>
<string name="problem_download">Invalid URL encountered, cannot download</string>
<string name="problem_location_download">Cannot download to the specified location</string>
<string name="download_no_sdcard_dlg_title" >No SD card</string>
<string name="download_no_sdcard_dlg_msg" >USB storage is required to download the file.</string>
<string name="download_sdcard_busy_dlg_title">USB storage unavailable</string>

1
app/src/main/res/xml/preference_about.xml

@ -1,4 +1,5 @@ @@ -1,4 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<!--suppress AndroidElementNotAllowed -->
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<PreferenceCategory android:title="@string/settings_about">

3
app/src/main/res/xml/preference_bookmarks.xml

@ -8,5 +8,8 @@ @@ -8,5 +8,8 @@
<Preference
android:key="import_bookmark"
android:title="@string/import_backup" />
<Preference
android:key="import_browser"
android:title="@string/importbookmarks" />
</PreferenceCategory>
</PreferenceScreen>
Loading…
Cancel
Save