Browse Source

Fixed bug with state restoration, fixed weird tab closing behavior, added some missing annotations

master
Anthony Restaino 9 years ago
parent
commit
f6c818fbb5
  1. 10
      app/src/main/java/acr/browser/lightning/activity/BrowserActivity.java
  2. 17
      app/src/main/java/acr/browser/lightning/activity/TabsManager.java
  3. 14
      app/src/main/java/acr/browser/lightning/browser/BrowserPresenter.java
  4. 2
      app/src/main/java/acr/browser/lightning/fragment/BookmarksFragment.java
  5. 8
      app/src/main/java/acr/browser/lightning/react/Observable.java
  6. 18
      app/src/main/java/acr/browser/lightning/react/Schedulers.java
  7. 94
      app/src/main/java/acr/browser/lightning/view/LightningView.java

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

@ -250,7 +250,7 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements
mTabsManager = new TabsManager(); mTabsManager = new TabsManager();
mPresenter = new BrowserPresenter(this, isIncognito()); mPresenter = new BrowserPresenter(this, isIncognito());
initialize(); initialize(savedInstanceState);
KeyboardHelper keyboardHelper = new KeyboardHelper(mRoot); KeyboardHelper keyboardHelper = new KeyboardHelper(mRoot);
keyboardHelper.registerKeyboardListener(new KeyboardHelper.KeyboardListener() { keyboardHelper.registerKeyboardListener(new KeyboardHelper.KeyboardListener() {
@ -265,7 +265,7 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements
}); });
} }
private synchronized void initialize() { private synchronized void initialize(Bundle savedInstanceState) {
mToolbar = (Toolbar) findViewById(R.id.toolbar); mToolbar = (Toolbar) findViewById(R.id.toolbar);
initializeToolbarHeight(getResources().getConfiguration()); initializeToolbarHeight(getResources().getConfiguration());
setSupportActionBar(mToolbar); setSupportActionBar(mToolbar);
@ -406,11 +406,13 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements
WebIconDatabase.getInstance().open(getDir("icons", MODE_PRIVATE).getPath()); WebIconDatabase.getInstance().open(getDir("icons", MODE_PRIVATE).getPath());
} }
if (isPanicTrigger(getIntent())) { Intent intent = savedInstanceState == null ? getIntent() : null;
if (isPanicTrigger(intent)) {
setIntent(null); setIntent(null);
panicClean(); panicClean();
} else { } else {
mPresenter.setupTabs(getIntent()); mPresenter.setupTabs(intent);
setIntent(null); setIntent(null);
mProxyUtils.checkForProxy(BrowserActivity.this); mProxyUtils.checkForProxy(BrowserActivity.this);
} }

17
app/src/main/java/acr/browser/lightning/activity/TabsManager.java

@ -143,7 +143,7 @@ public class TabsManager {
private void restoreLostTabs(@Nullable final String url, @NonNull final Activity activity, private void restoreLostTabs(@Nullable final String url, @NonNull final Activity activity,
@NonNull final Subscriber subscriber) { @NonNull final Subscriber subscriber) {
restoreState().subscribeOn(Schedulers.worker()) restoreState().subscribeOn(Schedulers.io())
.observeOn(Schedulers.main()).subscribe(new OnSubscribe<Bundle>() { .observeOn(Schedulers.main()).subscribe(new OnSubscribe<Bundle>() {
@Override @Override
public void onNext(Bundle item) { public void onNext(Bundle item) {
@ -282,6 +282,21 @@ public class TabsManager {
return mTabList.size() - 1; return mTabList.size() - 1;
} }
/**
* The last tab in the tab manager.
*
* @return the last tab, or null if
* there are no tabs.
*/
@Nullable
public synchronized LightningView lastTab() {
if (last() < 0) {
return null;
}
return mTabList.get(last());
}
/** /**
* Create and return a new tab. The tab is * Create and return a new tab. The tab is
* automatically added to the tabs list. * automatically added to the tabs list.

14
app/src/main/java/acr/browser/lightning/browser/BrowserPresenter.java

@ -38,7 +38,7 @@ public class BrowserPresenter {
@Nullable private LightningView mCurrentTab; @Nullable private LightningView mCurrentTab;
private final boolean mIsIncognito; private final boolean mIsIncognito;
private boolean mIsNewIntent; private boolean mShouldClose;
public BrowserPresenter(@NonNull BrowserView view, boolean isIncognito) { public BrowserPresenter(@NonNull BrowserView view, boolean isIncognito) {
BrowserApp.getAppComponent().inject(this); BrowserApp.getAppComponent().inject(this);
@ -152,8 +152,9 @@ public class BrowserPresenter {
if (!UrlUtils.isSpecialUrl(tabToDelete.getUrl()) && !mIsIncognito) { if (!UrlUtils.isSpecialUrl(tabToDelete.getUrl()) && !mIsIncognito) {
mPreferences.setSavedUrl(tabToDelete.getUrl()); mPreferences.setSavedUrl(tabToDelete.getUrl());
} }
final boolean isShown = tabToDelete.isShown(); final boolean isShown = tabToDelete.isShown();
boolean shouldClose = mIsNewIntent && isShown; boolean shouldClose = mShouldClose && isShown && Boolean.TRUE.equals(tabToDelete.getTag());
final LightningView currentTab = mTabsModel.getCurrentTab(); final LightningView currentTab = mTabsModel.getCurrentTab();
if (mTabsModel.size() == 1 && currentTab != null && if (mTabsModel.size() == 1 && currentTab != null &&
(UrlUtils.isSpecialUrl(currentTab.getUrl()) || (UrlUtils.isSpecialUrl(currentTab.getUrl()) ||
@ -186,7 +187,7 @@ public class BrowserPresenter {
} }
if (shouldClose) { if (shouldClose) {
mIsNewIntent = false; mShouldClose = false;
mView.closeActivity(); mView.closeActivity();
} }
@ -230,7 +231,11 @@ public class BrowserPresenter {
} else { } else {
newTab(url, true); newTab(url, true);
} }
mIsNewIntent = true; mShouldClose = true;
LightningView tab = mTabsModel.lastTab();
if (tab != null) {
tab.setTag(true);
}
} }
} }
}); });
@ -303,7 +308,6 @@ public class BrowserPresenter {
Log.d(TAG, "New tab, show: " + show); Log.d(TAG, "New tab, show: " + show);
mIsNewIntent = false;
LightningView startingTab = mTabsModel.newTab((Activity) mView, url, mIsIncognito); LightningView startingTab = mTabsModel.newTab((Activity) mView, url, mIsIncognito);
if (mTabsModel.size() == 1) { if (mTabsModel.size() == 1) {
startingTab.resumeTimers(); startingTab.resumeTimers();

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

@ -180,7 +180,7 @@ public class BookmarksFragment extends Fragment implements View.OnClickListener,
setupNavigationButton(view, R.id.action_reading, R.id.icon_reading); setupNavigationButton(view, R.id.action_reading, R.id.icon_reading);
setupNavigationButton(view, R.id.action_toggle_desktop, R.id.icon_desktop); setupNavigationButton(view, R.id.action_toggle_desktop, R.id.icon_desktop);
initBookmarkManager().subscribeOn(Schedulers.worker()) initBookmarkManager().subscribeOn(Schedulers.io())
.observeOn(Schedulers.main()) .observeOn(Schedulers.main())
.subscribe(new OnSubscribe<BookmarkViewAdapter>() { .subscribe(new OnSubscribe<BookmarkViewAdapter>() {
@Override @Override

8
app/src/main/java/acr/browser/lightning/react/Observable.java

@ -197,7 +197,7 @@ public class Observable<T> {
private static class OnCompleteRunnable<T> implements Runnable { private static class OnCompleteRunnable<T> implements Runnable {
private final OnSubscribe<T> onSubscribe; private final OnSubscribe<T> onSubscribe;
public OnCompleteRunnable(OnSubscribe<T> onSubscribe) {this.onSubscribe = onSubscribe;} public OnCompleteRunnable(@NonNull OnSubscribe<T> onSubscribe) {this.onSubscribe = onSubscribe;}
@Override @Override
public void run() { public void run() {
@ -209,7 +209,7 @@ public class Observable<T> {
private final OnSubscribe<T> onSubscribe; private final OnSubscribe<T> onSubscribe;
private final T item; private final T item;
public OnNextRunnable(OnSubscribe<T> onSubscribe, T item) { public OnNextRunnable(@NonNull OnSubscribe<T> onSubscribe, T item) {
this.onSubscribe = onSubscribe; this.onSubscribe = onSubscribe;
this.item = item; this.item = item;
} }
@ -224,7 +224,7 @@ public class Observable<T> {
private final OnSubscribe<T> onSubscribe; private final OnSubscribe<T> onSubscribe;
private final Throwable throwable; private final Throwable throwable;
public OnErrorRunnable(OnSubscribe<T> onSubscribe, Throwable throwable) { public OnErrorRunnable(@NonNull OnSubscribe<T> onSubscribe, @NonNull Throwable throwable) {
this.onSubscribe = onSubscribe; this.onSubscribe = onSubscribe;
this.throwable = throwable; this.throwable = throwable;
} }
@ -238,7 +238,7 @@ public class Observable<T> {
private static class OnStartRunnable<T> implements Runnable { private static class OnStartRunnable<T> implements Runnable {
private final OnSubscribe<T> onSubscribe; private final OnSubscribe<T> onSubscribe;
public OnStartRunnable(OnSubscribe<T> onSubscribe) {this.onSubscribe = onSubscribe;} public OnStartRunnable(@NonNull OnSubscribe<T> onSubscribe) {this.onSubscribe = onSubscribe;}
@Override @Override
public void run() { public void run() {

18
app/src/main/java/acr/browser/lightning/react/Schedulers.java

@ -7,11 +7,14 @@ import java.util.concurrent.Executor;
import java.util.concurrent.Executors; import java.util.concurrent.Executors;
public class Schedulers { public class Schedulers {
private static final Executor sWorker = Executors.newCachedThreadPool(); private static final Executor sWorker = Executors.newFixedThreadPool(4);
private static final Executor sIOWorker = Executors.newSingleThreadExecutor();
private static final Executor sMain = new ThreadExecutor(Looper.getMainLooper()); private static final Executor sMain = new ThreadExecutor(Looper.getMainLooper());
/** /**
* The worker thread. * The worker thread executor, will
* execute work on any one of multiple
* threads.
* *
* @return a non-null executor. * @return a non-null executor.
*/ */
@ -29,4 +32,15 @@ public class Schedulers {
public static Executor main() { public static Executor main() {
return sMain; return sMain;
} }
/**
* The io thread.
*
* @return a non-null executor that does
* work on a single thread off the main thread.
*/
@NonNull
public static Executor io() {
return sIOWorker;
}
} }

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

@ -67,39 +67,43 @@ import acr.browser.lightning.utils.Utils;
*/ */
public class LightningView { public class LightningView {
private static final String TAG = LightningView.class.getSimpleName();
public static final String HEADER_REQUESTED_WITH = "X-Requested-With"; public static final String HEADER_REQUESTED_WITH = "X-Requested-With";
public static final String HEADER_WAP_PROFILE = "X-Wap-Profile"; public static final String HEADER_WAP_PROFILE = "X-Wap-Profile";
private static final String HEADER_DNT = "DNT"; private static final String HEADER_DNT = "DNT";
@NonNull private final LightningViewTitle mTitle;
@Nullable private WebView mWebView;
private final boolean mIsIncognitoTab;
@NonNull private final UIController mUIController;
@NonNull private final GestureDetector mGestureDetector;
@NonNull private final Activity mActivity;
private static String mHomepage;
private static String mDefaultUserAgent;
private final Paint mPaint = new Paint();
private boolean isForegroundTab;
private boolean mInvertPage = false;
private boolean mToggleDesktop = false;
private static float mMaxFling;
private static final int API = android.os.Build.VERSION.SDK_INT; private static final int API = android.os.Build.VERSION.SDK_INT;
private static final int SCROLL_UP_THRESHOLD = Utils.dpToPx(10); private static final int SCROLL_UP_THRESHOLD = Utils.dpToPx(10);
private static final float[] mNegativeColorArray = {
private static String sHomepage;
private static String sDefaultUserAgent;
private static float mMaxFling;
private static final float[] sNegativeColorArray = {
-1.0f, 0, 0, 0, 255, // red -1.0f, 0, 0, 0, 255, // red
0, -1.0f, 0, 0, 255, // green 0, -1.0f, 0, 0, 255, // green
0, 0, -1.0f, 0, 255, // blue 0, 0, -1.0f, 0, 255, // blue
0, 0, 0, 1.0f, 0 // alpha 0, 0, 0, 1.0f, 0 // alpha
}; };
private static final float[] mIncreaseContrastColorArray = { private static final float[] sIncreaseContrastColorArray = {
2.0f, 0, 0, 0, -160.f, // red 2.0f, 0, 0, 0, -160.f, // red
0, 2.0f, 0, 0, -160.f, // green 0, 2.0f, 0, 0, -160.f, // green
0, 0, 2.0f, 0, -160.f, // blue 0, 0, 2.0f, 0, -160.f, // blue
0, 0, 0, 1.0f, 0 // alpha 0, 0, 0, 1.0f, 0 // alpha
}; };
private final WebViewHandler mWebViewHandler = new WebViewHandler(this);
private final Map<String, String> mRequestHeaders = new ArrayMap<>(); @NonNull private final LightningViewTitle mTitle;
@Nullable private WebView mWebView;
@NonNull private final UIController mUIController;
@NonNull private final GestureDetector mGestureDetector;
@NonNull private final Activity mActivity;
@NonNull private final Paint mPaint = new Paint();
@Nullable private Object mTag;
private final boolean mIsIncognitoTab;
private boolean isForegroundTab;
private boolean mInvertPage = false;
private boolean mToggleDesktop = false;
@NonNull private final WebViewHandler mWebViewHandler = new WebViewHandler(this);
@NonNull private final Map<String, String> mRequestHeaders = new ArrayMap<>();
@Inject Bus mEventBus; @Inject Bus mEventBus;
@Inject PreferenceManager mPreferences; @Inject PreferenceManager mPreferences;
@ -107,7 +111,6 @@ public class LightningView {
@Inject ProxyUtils mProxyUtils; @Inject ProxyUtils mProxyUtils;
@Inject BookmarkManager mBookmarkManager; @Inject BookmarkManager mBookmarkManager;
@SuppressLint("NewApi")
public LightningView(@NonNull Activity activity, @Nullable String url, boolean isIncognito) { public LightningView(@NonNull Activity activity, @Nullable String url, boolean isIncognito) {
BrowserApp.getAppComponent().inject(this); BrowserApp.getAppComponent().inject(this);
mActivity = activity; mActivity = activity;
@ -139,7 +142,7 @@ public class LightningView {
mWebView.setDownloadListener(new LightningDownloadListener(activity)); mWebView.setDownloadListener(new LightningDownloadListener(activity));
mGestureDetector = new GestureDetector(activity, new CustomGestureListener()); mGestureDetector = new GestureDetector(activity, new CustomGestureListener());
mWebView.setOnTouchListener(new TouchListener()); mWebView.setOnTouchListener(new TouchListener());
mDefaultUserAgent = mWebView.getSettings().getUserAgentString(); sDefaultUserAgent = mWebView.getSettings().getUserAgentString();
initializeSettings(); initializeSettings();
initializePreferences(activity); initializePreferences(activity);
@ -154,6 +157,28 @@ public class LightningView {
} }
} }
/**
* Sets the tag on the object,
* a reference to this object is held
* indefinitely.
*
* @param tag the tag to set, may be null.
*/
public void setTag(@Nullable Object tag) {
mTag = tag;
}
/**
* The tag set on the object.
*
* @return the tag set on the object,
* may be null.
*/
@Nullable
public Object getTag() {
return mTag;
}
/** /**
* This method loads the homepage for the browser. Either * This method loads the homepage for the browser. Either
* it loads the URL stored as the homepage, or loads the * it loads the URL stored as the homepage, or loads the
@ -164,7 +189,7 @@ public class LightningView {
if (mWebView == null) { if (mWebView == null) {
return; return;
} }
switch (mHomepage) { switch (sHomepage) {
case "about:home": case "about:home":
loadStartpage(); loadStartpage();
break; break;
@ -172,7 +197,7 @@ public class LightningView {
loadBookmarkpage(); loadBookmarkpage();
break; break;
default: default:
mWebView.loadUrl(mHomepage, mRequestHeaders); mWebView.loadUrl(sHomepage, mRequestHeaders);
break; break;
} }
} }
@ -227,7 +252,7 @@ public class LightningView {
} }
settings.setDefaultTextEncodingName(mPreferences.getTextEncoding()); settings.setDefaultTextEncodingName(mPreferences.getTextEncoding());
mHomepage = mPreferences.getHomepage(); sHomepage = mPreferences.getHomepage();
setColorMode(mPreferences.getRenderingMode()); setColorMode(mPreferences.getRenderingMode());
if (!mIsIncognitoTab) { if (!mIsIncognitoTab) {
@ -286,7 +311,7 @@ public class LightningView {
} catch (Exception e) { } catch (Exception e) {
// This shouldn't be necessary, but there are a number // This shouldn't be necessary, but there are a number
// of KitKat devices that crash trying to set this // of KitKat devices that crash trying to set this
Log.e(Constants.TAG, "Problem setting LayoutAlgorithm to TEXT_AUTOSIZING"); Log.e(TAG, "Problem setting LayoutAlgorithm to TEXT_AUTOSIZING");
} }
} }
} else { } else {
@ -376,7 +401,8 @@ public class LightningView {
} }
getPathObservable("appcache") getPathObservable("appcache")
.subscribeOn(Schedulers.worker()) .subscribeOn(Schedulers.io())
.observeOn(Schedulers.main())
.subscribe(new OnSubscribe<File>() { .subscribe(new OnSubscribe<File>() {
@Override @Override
public void onNext(File item) { public void onNext(File item) {
@ -388,7 +414,8 @@ public class LightningView {
}); });
getPathObservable("geolocation") getPathObservable("geolocation")
.subscribeOn(Schedulers.worker()) .subscribeOn(Schedulers.io())
.observeOn(Schedulers.main())
.subscribe(new OnSubscribe<File>() { .subscribe(new OnSubscribe<File>() {
@Override @Override
public void onNext(File item) { public void onNext(File item) {
@ -400,7 +427,8 @@ public class LightningView {
}); });
getPathObservable("databases") getPathObservable("databases")
.subscribeOn(Schedulers.worker()) .subscribeOn(Schedulers.io())
.observeOn(Schedulers.main())
.subscribe(new OnSubscribe<File>() { .subscribe(new OnSubscribe<File>() {
@Override @Override
public void onNext(File item) { public void onNext(File item) {
@ -488,7 +516,7 @@ public class LightningView {
if (API >= Build.VERSION_CODES.JELLY_BEAN_MR1) { if (API >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
settings.setUserAgentString(WebSettings.getDefaultUserAgent(context)); settings.setUserAgentString(WebSettings.getDefaultUserAgent(context));
} else { } else {
settings.setUserAgentString(mDefaultUserAgent); settings.setUserAgentString(sDefaultUserAgent);
} }
break; break;
case 2: case 2:
@ -498,7 +526,7 @@ public class LightningView {
settings.setUserAgentString(Constants.MOBILE_USER_AGENT); settings.setUserAgentString(Constants.MOBILE_USER_AGENT);
break; break;
case 4: case 4:
String ua = mPreferences.getUserAgentString(mDefaultUserAgent); String ua = mPreferences.getUserAgentString(sDefaultUserAgent);
if (ua == null || ua.isEmpty()) { if (ua == null || ua.isEmpty()) {
ua = " "; ua = " ";
} }
@ -663,7 +691,7 @@ public class LightningView {
break; break;
case 1: case 1:
ColorMatrixColorFilter filterInvert = new ColorMatrixColorFilter( ColorMatrixColorFilter filterInvert = new ColorMatrixColorFilter(
mNegativeColorArray); sNegativeColorArray);
mPaint.setColorFilter(filterInvert); mPaint.setColorFilter(filterInvert);
setHardwareRendering(); setHardwareRendering();
@ -678,7 +706,7 @@ public class LightningView {
break; break;
case 3: case 3:
ColorMatrix matrix = new ColorMatrix(); ColorMatrix matrix = new ColorMatrix();
matrix.set(mNegativeColorArray); matrix.set(sNegativeColorArray);
ColorMatrix matrixGray = new ColorMatrix(); ColorMatrix matrixGray = new ColorMatrix();
matrixGray.setSaturation(0); matrixGray.setSaturation(0);
ColorMatrix concat = new ColorMatrix(); ColorMatrix concat = new ColorMatrix();
@ -692,7 +720,7 @@ public class LightningView {
case 4: case 4:
ColorMatrixColorFilter IncreaseHighContrast = new ColorMatrixColorFilter( ColorMatrixColorFilter IncreaseHighContrast = new ColorMatrixColorFilter(
mIncreaseContrastColorArray); sIncreaseContrastColorArray);
mPaint.setColorFilter(IncreaseHighContrast); mPaint.setColorFilter(IncreaseHighContrast);
setHardwareRendering(); setHardwareRendering();
break; break;
@ -800,7 +828,7 @@ public class LightningView {
// before calling destroy() so that a memory leak is not created // before calling destroy() so that a memory leak is not created
ViewGroup parent = (ViewGroup) mWebView.getParent(); ViewGroup parent = (ViewGroup) mWebView.getParent();
if (parent != null) { if (parent != null) {
Log.e(Constants.TAG, "WebView was not detached from window before onDestroy"); Log.e(TAG, "WebView was not detached from window before onDestroy");
parent.removeView(mWebView); parent.removeView(mWebView);
} }
mWebView.stopLoading(); mWebView.stopLoading();

Loading…
Cancel
Save