Browse Source

TabsManager created

master
Stefano Pacifici 9 years ago
parent
commit
74a75d4adb
  1. 103
      app/src/main/java/acr/browser/lightning/activity/BrowserActivity.java
  2. 172
      app/src/main/java/acr/browser/lightning/activity/TabsManager.java

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

@ -137,7 +137,6 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements
private RelativeLayout mSearchBar; private RelativeLayout mSearchBar;
// List // List
private final List<LightningView> mWebViewList = new ArrayList<>();
private LightningView mCurrentView; private LightningView mCurrentView;
private WebView mWebView; private WebView mWebView;
@ -189,6 +188,9 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements
@Inject @Inject
BookmarksDialogBuilder bookmarksDialogBuilder; BookmarksDialogBuilder bookmarksDialogBuilder;
@Inject
TabsManager tabsManager;
// Image // Image
private Bitmap mWebpageBitmap; private Bitmap mWebpageBitmap;
private final ColorDrawable mBackground = new ColorDrawable(); private final ColorDrawable mBackground = new ColorDrawable();
@ -237,7 +239,8 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements
mShowTabsInDrawer = mPreferences.getShowTabsInDrawer(!isTablet()); mShowTabsInDrawer = mPreferences.getShowTabsInDrawer(!isTablet());
mActivity = this; mActivity = this;
mWebViewList.clear(); // TODO Stefano, check this
// mWebViewList.clear();
mClickHandler = new ClickHandler(this); mClickHandler = new ClickHandler(this);
mBrowserFrame = (FrameLayout) findViewById(R.id.content_frame); mBrowserFrame = (FrameLayout) findViewById(R.id.content_frame);
@ -272,7 +275,7 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements
if (mShowTabsInDrawer) { if (mShowTabsInDrawer) {
mTabAdapter = new LightningViewAdapter(this, R.layout.tab_list_item, mWebViewList); mTabAdapter = new LightningViewAdapter(this, R.layout.tab_list_item, tabsManager.getTabsList());
mDrawerListLeft = (RecyclerView) findViewById(R.id.left_drawer_list); mDrawerListLeft = (RecyclerView) findViewById(R.id.left_drawer_list);
mDrawerListLeft.setOverScrollMode(View.OVER_SCROLL_IF_CONTENT_SCROLLS); mDrawerListLeft.setOverScrollMode(View.OVER_SCROLL_IF_CONTENT_SCROLLS);
RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false); RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false);
@ -280,7 +283,7 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements
mDrawerListLeft.setHasFixedSize(true); mDrawerListLeft.setHasFixedSize(true);
mToolbarLayout.removeView(horizontalListView); mToolbarLayout.removeView(horizontalListView);
} else { } else {
mTabAdapter = new LightningViewAdapter(this, R.layout.tab_list_item_horizontal, mWebViewList); mTabAdapter = new LightningViewAdapter(this, R.layout.tab_list_item_horizontal, tabsManager.getTabsList());
mDrawerListLeft = horizontalListView; mDrawerListLeft = horizontalListView;
mDrawerListLeft.setOverScrollMode(View.OVER_SCROLL_NEVER); mDrawerListLeft.setOverScrollMode(View.OVER_SCROLL_NEVER);
mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED, mDrawerLeft); mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED, mDrawerLeft);
@ -873,10 +876,11 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements
@Override @Override
public void onClick(View v) { public void onClick(View v) {
int position = mDrawerListLeft.getChildAdapterPosition(v); final int position = mDrawerListLeft.getChildAdapterPosition(v);
if (mCurrentView != mWebViewList.get(position)) { final LightningView tab = tabsManager.getTabAtPosition(position);
if (tab != null && mCurrentView != tab) {
mIsNewIntent = false; mIsNewIntent = false;
showTab(mWebViewList.get(position)); showTab(tab);
} }
} }
} }
@ -1018,25 +1022,22 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements
public void onTrimMemory(int level) { public void onTrimMemory(int level) {
if (level > TRIM_MEMORY_MODERATE && Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) { if (level > TRIM_MEMORY_MODERATE && Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
Log.d(Constants.TAG, "Low Memory, Free Memory"); Log.d(Constants.TAG, "Low Memory, Free Memory");
for (int n = 0, size = mWebViewList.size(); n < size; n++) { tabsManager.freeMemory();
mWebViewList.get(n).freeMemory();
}
} }
} }
synchronized boolean newTab(String url, boolean show) { synchronized boolean newTab(String url, boolean show) {
// Limit number of tabs for limited version of app // Limit number of tabs for limited version of app
if (!Constants.FULL_VERSION && mWebViewList.size() >= 10) { if (!Constants.FULL_VERSION && tabsManager.size() >= 10) {
Utils.showSnackbar(this, R.string.max_tabs); Utils.showSnackbar(this, R.string.max_tabs);
return false; return false;
} }
mIsNewIntent = false; mIsNewIntent = false;
LightningView startingTab = new LightningView(mActivity, url, mDarkTheme, isIncognito(), this); LightningView startingTab = tabsManager.newTab(mActivity, url, mDarkTheme, isIncognito(), this);
if (mIdGenerator == 0) { if (mIdGenerator == 0) {
startingTab.resumeTimers(); startingTab.resumeTimers();
} }
mIdGenerator++; mIdGenerator++;
mWebViewList.add(startingTab);
if (show) { if (show) {
showTab(startingTab); showTab(startingTab);
@ -1045,7 +1046,7 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements
new Handler().postDelayed(new Runnable() { new Handler().postDelayed(new Runnable() {
@Override @Override
public void run() { public void run() {
mDrawerListLeft.smoothScrollToPosition(mWebViewList.size() - 1); mDrawerListLeft.smoothScrollToPosition(tabsManager.size() - 1);
} }
}, 300); }, 300);
@ -1053,49 +1054,47 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements
} }
private synchronized void deleteTab(int position) { private synchronized void deleteTab(int position) {
if (position >= mWebViewList.size()) { final LightningView reference = tabsManager.getTabAtPosition(position);
if (reference == null) {
return; return;
} }
int current = mWebViewList.indexOf(mCurrentView); // What?
int current = tabsManager.getPositionForTab(mCurrentView);
if (current < 0) { if (current < 0) {
return; return;
} }
LightningView reference = mWebViewList.get(position);
if (reference == null) {
return;
}
if (!reference.getUrl().startsWith(Constants.FILE) && !isIncognito()) { if (!reference.getUrl().startsWith(Constants.FILE) && !isIncognito()) {
mPreferences.setSavedUrl(reference.getUrl()); mPreferences.setSavedUrl(reference.getUrl());
} }
boolean isShown = reference.isShown(); final boolean isShown = reference.isShown();
if (isShown) { if (isShown) {
mBrowserFrame.setBackgroundColor(mBackgroundColor); mBrowserFrame.setBackgroundColor(mBackgroundColor);
} }
if (current > position) { if (current > position) {
mWebViewList.remove(position); tabsManager.deleteTab(position);
showTab(mWebViewList.get(current - 1)); showTab(tabsManager.getTabAtPosition(current - 1));
updateTabs(); updateTabs();
reference.onDestroy(); reference.onDestroy();
} else if (mWebViewList.size() > position + 1) { } else if (tabsManager.size() > position + 1) {
if (current == position) { if (current == position) {
showTab(mWebViewList.get(position + 1)); showTab(tabsManager.getTabAtPosition(position + 1));
mWebViewList.remove(position); tabsManager.deleteTab(position);
showTab(mWebViewList.get(position)); showTab(tabsManager.getTabAtPosition(position));
updateTabs(); updateTabs();
} else { } else {
mWebViewList.remove(position); tabsManager.deleteTab(position);
} }
reference.onDestroy(); reference.onDestroy();
} else if (mWebViewList.size() > 1) { } else if (tabsManager.size() > 1) {
if (current == position) { if (current == position) {
showTab(mWebViewList.get(position - 1)); showTab(tabsManager.getTabAtPosition(position - 1));
mWebViewList.remove(position); tabsManager.deleteTab(position);
showTab(mWebViewList.get(position - 1)); showTab(tabsManager.getTabAtPosition(position - 1));
updateTabs(); updateTabs();
} else { } else {
mWebViewList.remove(position); tabsManager.deleteTab(position);
} }
reference.onDestroy(); reference.onDestroy();
@ -1103,7 +1102,7 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements
if (mCurrentView.getUrl().startsWith(Constants.FILE) || mCurrentView.getUrl().equals(mHomepage)) { if (mCurrentView.getUrl().startsWith(Constants.FILE) || mCurrentView.getUrl().equals(mHomepage)) {
closeActivity(); closeActivity();
} else { } else {
mWebViewList.remove(position); tabsManager.deleteTab(position);
performExitCleanUp(); performExitCleanUp();
reference.pauseTimers(); reference.pauseTimers();
reference.onDestroy(); reference.onDestroy();
@ -1150,7 +1149,7 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements
@Override @Override
public boolean onKeyLongPress(int keyCode, KeyEvent event) { public boolean onKeyLongPress(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) { if (keyCode == KeyEvent.KEYCODE_BACK) {
showCloseDialog(mWebViewList.indexOf(mCurrentView)); showCloseDialog(tabsManager.positionOf(mCurrentView));
} }
return true; return true;
} }
@ -1160,12 +1159,7 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements
performExitCleanUp(); performExitCleanUp();
mCurrentView = null; mCurrentView = null;
mWebView = null; mWebView = null;
for (int n = 0, size = mWebViewList.size(); n < size; n++) { tabsManager.shutdown();
if (mWebViewList.get(n) != null) {
mWebViewList.get(n).onDestroy();
}
}
mWebViewList.clear();
mTabAdapter.notifyDataSetChanged(); mTabAdapter.notifyDataSetChanged();
finish(); finish();
} }
@ -1189,7 +1183,7 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements
mCurrentView.goBack(); mCurrentView.goBack();
} }
} else { } else {
deleteTab(mWebViewList.indexOf(mCurrentView)); deleteTab(tabsManager.positionOf(mCurrentView));
} }
} else { } else {
Log.e(Constants.TAG, "This shouldn't happen ever"); Log.e(Constants.TAG, "This shouldn't happen ever");
@ -1220,12 +1214,7 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements
void saveOpenTabs() { void saveOpenTabs() {
if (mPreferences.getRestoreLostTabsEnabled()) { if (mPreferences.getRestoreLostTabsEnabled()) {
String s = ""; final String s = tabsManager.tabsString();
for (int n = 0, size = mWebViewList.size(); n < size; n++) {
if (!mWebViewList.get(n).getUrl().isEmpty()) {
s = s + mWebViewList.get(n).getUrl() + "|$|SEPARATOR|$|";
}
}
mPreferences.setMemoryUrl(s); mPreferences.setMemoryUrl(s);
} }
} }
@ -1266,13 +1255,7 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements
} }
mHistoryDatabase = HistoryDatabase.getInstance(); mHistoryDatabase = HistoryDatabase.getInstance();
initializePreferences(); initializePreferences();
for (int n = 0, size = mWebViewList.size(); n < size; n++) { tabsManager.resume(this);
if (mWebViewList.get(n) != null) {
mWebViewList.get(n).initializePreferences(null, this);
} else {
mWebViewList.remove(n);
}
}
supportInvalidateOptionsMenu(); supportInvalidateOptionsMenu();
@ -1984,7 +1967,7 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements
*/ */
@Override @Override
public void onCloseWindow(LightningView view) { public void onCloseWindow(LightningView view) {
deleteTab(mWebViewList.indexOf(view)); deleteTab(tabsManager.positionOf(view));
} }
/** /**
@ -2278,7 +2261,7 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements
if (mCurrentView.canGoBack()) { if (mCurrentView.canGoBack()) {
mCurrentView.goBack(); mCurrentView.goBack();
} else { } else {
deleteTab(mWebViewList.indexOf(mCurrentView)); deleteTab(tabsManager.positionOf(mCurrentView));
} }
} }
break; break;
@ -2353,11 +2336,7 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements
super.onReceive(context, intent); super.onReceive(context, intent);
boolean isConnected = isConnected(context); boolean isConnected = isConnected(context);
Log.d(Constants.TAG, "Network Connected: " + String.valueOf(isConnected)); Log.d(Constants.TAG, "Network Connected: " + String.valueOf(isConnected));
for (int n = 0, size = mWebViewList.size(); n < size; n++) { tabsManager.notifyConnectioneStatus(isConnected);
WebView view = mWebViewList.get(n).getWebView();
if (view != null)
view.setNetworkAvailable(isConnected);
}
} }
}; };

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

@ -0,0 +1,172 @@
package acr.browser.lightning.activity;
import android.app.Activity;
import android.content.Context;
import android.support.annotation.Nullable;
import android.webkit.WebView;
import java.util.ArrayList;
import java.util.List;
import javax.inject.Inject;
import acr.browser.lightning.controller.BrowserController;
import acr.browser.lightning.view.LightningView;
/**
* @author Stefano Pacifici
* @date 2015/09/14
*/
public class TabsManager {
private final List<LightningView> mWebViewList = new ArrayList<>();
@Inject
public TabsManager() {
}
/**
* Return a clone of the current tabs list. The list will not be updated, the user has to fetch
* a new copy when notified.
*
* @return a copy of the current tabs list
*/
public List<LightningView> getTabsList() {
return new ArrayList<>(mWebViewList);
}
/**
* Return the tab at the given position in tabs list, or null if position is not in tabs list
* range.
*
* @param position the index in tabs list
* @return the corespondent {@link LightningView}, or null if the index is invalid
*/
@Nullable
public LightningView getTabAtPosition(final int position) {
if (position < 0 || position >= mWebViewList.size()) {
return null;
}
return mWebViewList.get(position);
}
/**
* Try to low memory pressure
*/
public void freeMemory() {
for (LightningView tab: mWebViewList) {
tab.freeMemory();
}
}
/**
* Shutdown the manager
*/
public synchronized void shutdown() {
for (LightningView tab: mWebViewList) {
tab.onDestroy();
}
mWebViewList.clear();
}
/**
* Resume the tabs
*
* @param context
*/
public synchronized void resume(final Context context) {
for (LightningView tab: mWebViewList) {
tab.initializePreferences(null, context);
}
}
/**
* Forward network connection status to the webviews.
*
* @param isConnected
*/
public synchronized void notifyConnectioneStatus(final boolean isConnected) {
for (LightningView tab: mWebViewList) {
final WebView webView = tab.getWebView();
if (webView != null) {
webView.setNetworkAvailable(isConnected);
}
}
}
/**
* @return The number of currently opened tabs
*/
public int size() {
return mWebViewList.size();
}
/**
* Create and return a new tab. The tab is automatically added to the tabs list.
*
* @param activity
* @param url
* @param darkTheme
* @param isIncognito
* @param controller
* @return
*/
public synchronized LightningView newTab(final Activity activity,
final String url, final boolean darkTheme,
final boolean isIncognito,
final BrowserController controller) {
final LightningView tab = new LightningView(activity, url, darkTheme, isIncognito, controller);
mWebViewList.add(tab);
return tab;
}
/**
* Remove a tab and return its reference or null if the position is not in tabs range
*
* @param position The position of the tab to remove
* @return The removed tab reference or null
*/
@Nullable
public synchronized LightningView deleteTab(final int position) {
if (position >= mWebViewList.size()) {
return null;
}
final LightningView tab = mWebViewList.remove(position);
// TODO This should not be done outside this call
// tab.onDestroy();
return tab;
}
/**
* TODO I think it should be removed
* Return the position of the given tab
* @param tab
* @return
*/
public int positionOf(final LightningView tab) {
return mWebViewList.indexOf(tab);
}
/**
* @return A string representation of the currently opened tabs
*/
public String tabsString() {
final StringBuilder builder = new StringBuilder();
for (LightningView tab: mWebViewList) {
final String url = tab.getUrl();
if (url != null && !url.isEmpty()) {
builder.append(url).append("|$|SEPARATOR|$|");
}
}
return builder.toString();
}
/**
* TODO Remove this, temporary workaround
* @param tab
* @return
*/
public int getPositionForTab(final LightningView tab) {
return mWebViewList.indexOf(tab);
}
}
Loading…
Cancel
Save