287 lines
8.8 KiB
Java
287 lines
8.8 KiB
Java
package acr.browser.lightning.activity;
|
|
|
|
import android.app.Activity;
|
|
import android.content.Context;
|
|
import android.content.DialogInterface;
|
|
import android.content.Intent;
|
|
import android.support.annotation.Nullable;
|
|
import android.support.v7.app.AlertDialog;
|
|
import android.util.Log;
|
|
import android.webkit.WebView;
|
|
|
|
import com.squareup.otto.Bus;
|
|
|
|
import java.util.ArrayList;
|
|
import java.util.List;
|
|
|
|
import javax.inject.Inject;
|
|
import javax.inject.Singleton;
|
|
|
|
import acr.browser.lightning.R;
|
|
import acr.browser.lightning.constant.Constants;
|
|
import acr.browser.lightning.preference.PreferenceManager;
|
|
import acr.browser.lightning.utils.Utils;
|
|
import acr.browser.lightning.view.LightningView;
|
|
|
|
/**
|
|
* @author Stefano Pacifici
|
|
* @date 2015/09/14
|
|
*/
|
|
@Singleton
|
|
public class TabsManager {
|
|
|
|
private static final String TAG = TabsManager.class.getSimpleName();
|
|
private final List<LightningView> mWebViewList = new ArrayList<>();
|
|
private LightningView mCurrentTab;
|
|
|
|
@Inject PreferenceManager mPreferenceManager;
|
|
@Inject Bus mEventBus;
|
|
|
|
@Inject
|
|
public TabsManager() {}
|
|
|
|
/**
|
|
* Restores old tabs that were open before the browser
|
|
* was closed. Handles the intent used to open the browser.
|
|
*
|
|
* @param activity the activity needed to create tabs.
|
|
* @param intent the intent that started the browser activity.
|
|
* @param incognito whether or not we are in incognito mode.
|
|
*/
|
|
public synchronized void restoreTabsAndHandleIntent(final Activity activity,
|
|
final Intent intent,
|
|
final boolean incognito) {
|
|
// If incognito, only create one tab, do not handle intent
|
|
// in order to protect user privacy
|
|
if (incognito && mWebViewList.isEmpty()) {
|
|
newTab(activity, null, true);
|
|
return;
|
|
}
|
|
|
|
String url = null;
|
|
if (intent != null) {
|
|
url = intent.getDataString();
|
|
}
|
|
mWebViewList.clear();
|
|
mCurrentTab = null;
|
|
if (mPreferenceManager.getRestoreLostTabsEnabled()) {
|
|
final String mem = mPreferenceManager.getMemoryUrl();
|
|
mPreferenceManager.setMemoryUrl("");
|
|
String[] array = Utils.getArray(mem);
|
|
for (String urlString : array) {
|
|
if (!urlString.isEmpty()) {
|
|
newTab(activity, urlString, false);
|
|
}
|
|
}
|
|
}
|
|
if (url != null) {
|
|
if (url.startsWith(Constants.FILE)) {
|
|
final String urlToLoad = url;
|
|
AlertDialog.Builder builder = new AlertDialog.Builder(activity);
|
|
builder.setCancelable(true)
|
|
.setTitle(R.string.title_warning)
|
|
.setMessage(R.string.message_blocked_local)
|
|
.setNegativeButton(android.R.string.cancel, null)
|
|
.setPositiveButton(R.string.action_open, new DialogInterface.OnClickListener() {
|
|
@Override
|
|
public void onClick(DialogInterface dialog, int which) {
|
|
newTab(activity, urlToLoad, false);
|
|
}
|
|
})
|
|
.show();
|
|
} else {
|
|
newTab(activity, url, false);
|
|
}
|
|
}
|
|
if (mWebViewList.size() == 0) {
|
|
newTab(activity, null, false);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 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 synchronized LightningView getTabAtPosition(final int position) {
|
|
if (position < 0 || position >= mWebViewList.size()) {
|
|
return null;
|
|
}
|
|
|
|
return mWebViewList.get(position);
|
|
}
|
|
|
|
/**
|
|
* Try to low memory pressure
|
|
*/
|
|
public synchronized void freeMemory() {
|
|
for (LightningView tab : mWebViewList) {
|
|
tab.freeMemory();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Shutdown the manager
|
|
*/
|
|
public synchronized void shutdown() {
|
|
for (LightningView tab : mWebViewList) {
|
|
tab.onDestroy();
|
|
}
|
|
mWebViewList.clear();
|
|
mCurrentTab = null;
|
|
}
|
|
|
|
/**
|
|
* Resume the tabs
|
|
*
|
|
* @param context
|
|
*/
|
|
public synchronized void resume(final Context context) {
|
|
for (LightningView tab : mWebViewList) {
|
|
tab.initializePreferences(context);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Forward network connection status to the webviews.
|
|
*
|
|
* @param isConnected
|
|
*/
|
|
public synchronized void notifyConnectionStatus(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 synchronized 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 isIncognito
|
|
* @return
|
|
*/
|
|
public synchronized LightningView newTab(final Activity activity,
|
|
final String url,
|
|
final boolean isIncognito) {
|
|
final LightningView tab = new LightningView(activity, url, isIncognito);
|
|
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
|
|
*/
|
|
private synchronized void removeTab(final int position) {
|
|
if (position >= mWebViewList.size()) {
|
|
return;
|
|
}
|
|
final LightningView tab = mWebViewList.remove(position);
|
|
if (mCurrentTab == tab) {
|
|
mCurrentTab = null;
|
|
}
|
|
tab.onDestroy();
|
|
Log.d(Constants.TAG, tab.toString());
|
|
}
|
|
|
|
public synchronized void deleteTab(int position) {
|
|
final LightningView currentTab = getCurrentTab();
|
|
int current = positionOf(currentTab);
|
|
|
|
if (current == position) {
|
|
if (size() == 1) {
|
|
mCurrentTab = null;
|
|
} else if (current < size() - 1) {
|
|
// There is another tab after this one
|
|
mCurrentTab = getTabAtPosition(current + 1);
|
|
} else {
|
|
mCurrentTab = getTabAtPosition(current - 1);
|
|
}
|
|
removeTab(current);
|
|
} else {
|
|
removeTab(position);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Return the position of the given tab.
|
|
*
|
|
* @param tab the tab to look for
|
|
* @return the position of the tab or -1 if the tab is not in the list
|
|
*/
|
|
public synchronized 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(mWebViewList.size());
|
|
for (LightningView tab : mWebViewList) {
|
|
final String url = tab.getUrl();
|
|
if (!url.isEmpty()) {
|
|
builder.append(url).append("|$|SEPARATOR|$|");
|
|
}
|
|
}
|
|
return builder.toString();
|
|
}
|
|
|
|
/**
|
|
* Return the {@link WebView} associated to the current tab, or null if there is no current tab
|
|
*
|
|
* @return a {@link WebView} or null
|
|
*/
|
|
@Nullable
|
|
public synchronized WebView getCurrentWebView() {
|
|
return mCurrentTab != null ? mCurrentTab.getWebView() : null;
|
|
}
|
|
|
|
/**
|
|
* TODO We should remove also this, but probably not
|
|
*
|
|
* @return
|
|
*/
|
|
@Nullable
|
|
public synchronized LightningView getCurrentTab() {
|
|
return mCurrentTab;
|
|
}
|
|
|
|
/**
|
|
* Switch the current tab to the one at the given position. It returns the selected. After this
|
|
* call {@link TabsManager#getCurrentTab()} return the same reference returned by this method if
|
|
* position is valid.
|
|
*
|
|
* @return the selected tab or null if position is out of tabs range
|
|
*/
|
|
@Nullable
|
|
public synchronized LightningView switchToTab(final int position) {
|
|
if (position < 0 || position >= mWebViewList.size()) {
|
|
Log.e(TAG, "Returning a null LightningView requested for position: " + position);
|
|
return null;
|
|
} else {
|
|
final LightningView tab = mWebViewList.get(position);
|
|
if (tab != null) {
|
|
mCurrentTab = tab;
|
|
}
|
|
return tab;
|
|
}
|
|
}
|
|
|
|
}
|