summaryrefslogtreecommitdiffstats
path: root/src/com/android/browser/Controller.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/com/android/browser/Controller.java')
-rw-r--r--src/com/android/browser/Controller.java284
1 files changed, 137 insertions, 147 deletions
diff --git a/src/com/android/browser/Controller.java b/src/com/android/browser/Controller.java
index dcb62a6..2a7e8eb 100644
--- a/src/com/android/browser/Controller.java
+++ b/src/com/android/browser/Controller.java
@@ -56,7 +56,6 @@ import android.provider.BrowserContract.Images;
import android.provider.ContactsContract;
import android.provider.ContactsContract.Intents.Insert;
import android.speech.RecognizerIntent;
-import android.speech.RecognizerResultsIntent;
import android.text.TextUtils;
import android.util.Log;
import android.util.Patterns;
@@ -80,6 +79,7 @@ import android.webkit.WebIconDatabase;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.widget.Toast;
+
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.net.URLEncoder;
@@ -96,6 +96,7 @@ public class Controller
private static final String LOGTAG = "Controller";
private static final String SEND_APP_ID_EXTRA =
"android.speech.extras.SEND_APPLICATION_ID_EXTRA";
+ private static final String INCOGNITO_URI = "browser:incognito";
// public message ids
@@ -132,6 +133,9 @@ public class Controller
// "source" parameter for Google search through simplily type
final static String GOOGLE_SEARCH_SOURCE_TYPE = "browser-type";
+ // "no-crash-recovery" parameter in intetnt to suppress crash recovery
+ final static String NO_CRASH_RECOVERY = "no-crash-recovery";
+
private Activity mActivity;
private UI mUi;
private TabControl mTabControl;
@@ -197,6 +201,7 @@ public class Controller
// Tabs' notion of whether they represent bookmarked sites.
private ContentObserver mBookmarksObserver;
private DataController mDataController;
+ private CrashRecoveryHandler mCrashRecoveryHandler;
private static class ClearThumbnails extends AsyncTask<File, Void, Void> {
@Override
@@ -218,7 +223,7 @@ public class Controller
mDataController = DataController.getInstance(mActivity);
mTabControl = new TabControl(this);
mSettings.setController(this);
- mSettings.updateRlzValues(mActivity);
+ mCrashRecoveryHandler = new CrashRecoveryHandler(this);
mUrlHandler = new UrlHandler(this);
mIntentHandler = new IntentHandler(mActivity, this);
@@ -252,6 +257,16 @@ public class Controller
}
void start(final Bundle icicle, final Intent intent) {
+ boolean noCrashRecovery = intent.getBooleanExtra(NO_CRASH_RECOVERY, false);
+ if (icicle != null || noCrashRecovery) {
+ mCrashRecoveryHandler.clearState();
+ doStart(icicle, intent);
+ } else {
+ mCrashRecoveryHandler.startRecovery(intent);
+ }
+ }
+
+ void doStart(final Bundle icicle, final Intent intent) {
// Unless the last browser usage was within 24 hours, destroy any
// remaining incognito tabs.
@@ -266,10 +281,10 @@ public class Controller
|| lastActiveDate.after(today));
// Find out if we will restore any state and remember the tab.
- final int currentTab =
+ final long currentTabId =
mTabControl.canRestoreState(icicle, restoreIncognitoTabs);
- if (currentTab == -1) {
+ if (currentTabId == -1) {
// Not able to restore so we go ahead and clear session cookies. We
// must do this before trying to login the user as we don't want to
// clear any session cookies set during login.
@@ -279,31 +294,29 @@ public class Controller
GoogleAccountLogin.startLoginIfNeeded(mActivity,
new Runnable() {
@Override public void run() {
- start(icicle, intent, currentTab, restoreIncognitoTabs);
+ onPreloginFinished(icicle, intent, currentTabId, restoreIncognitoTabs);
}
});
}
- private void start(Bundle icicle, Intent intent, int currentTab,
+ private void onPreloginFinished(Bundle icicle, Intent intent, long currentTabId,
boolean restoreIncognitoTabs) {
- if (currentTab == -1) {
+ if (currentTabId == -1) {
final Bundle extra = intent.getExtras();
// Create an initial tab.
// If the intent is ACTION_VIEW and data is not null, the Browser is
// invoked to view the content by another application. In this case,
// the tab will be close when exit.
UrlData urlData = mIntentHandler.getUrlDataFromIntent(intent);
-
- String action = intent.getAction();
- final Tab t = mTabControl.createNewTab(
- (Intent.ACTION_VIEW.equals(action) &&
- intent.getData() != null)
- || RecognizerResultsIntent.ACTION_VOICE_SEARCH_RESULTS
- .equals(action),
- intent.getStringExtra(Browser.EXTRA_APPLICATION_ID),
- urlData.mUrl, false);
- addTab(t);
- setActiveTab(t);
+ Tab t = null;
+ if (urlData.isEmpty()) {
+ t = openTabToHomePage();
+ } else {
+ t = openTab(urlData);
+ }
+ if (t != null) {
+ t.setAppId(intent.getStringExtra(Browser.EXTRA_APPLICATION_ID));
+ }
WebView webView = t.getWebView();
if (extra != null) {
int scale = extra.getInt(Browser.INITIAL_ZOOM_LEVEL, 0);
@@ -311,17 +324,8 @@ public class Controller
webView.setInitialScale(scale);
}
}
-
- if (urlData.isEmpty()) {
- loadUrl(webView, mSettings.getHomePage());
- } else {
- // monkey protection against delayed start
- if (t != null) {
- loadUrlDataIn(t, urlData);
- }
- }
} else {
- mTabControl.restoreState(icicle, currentTab, restoreIncognitoTabs,
+ mTabControl.restoreState(icicle, currentTabId, restoreIncognitoTabs,
mUi.needsRestoreAllTabs());
mUi.updateTabs(mTabControl.getTabs());
// TabControl.restoreState() will create a new tab even if
@@ -334,7 +338,7 @@ public class Controller
new ClearThumbnails().execute(mTabControl.getThumbnailDir()
.listFiles());
// Read JavaScript flags if it exists.
- String jsFlags = getSettings().getJsFlags();
+ String jsFlags = getSettings().getJsEngineFlags();
if (jsFlags.trim().length() != 0) {
getCurrentWebView().setJsFlags(jsFlags);
}
@@ -475,7 +479,12 @@ public class Controller
break;
case R.id.open_newtab_context_menu_id:
final Tab parent = mTabControl.getCurrentTab();
- final Tab newTab = openTab(parent, url, false);
+ final Tab newTab =
+ openTab(url,
+ (parent != null)
+ && parent.isPrivateBrowsingEnabled(),
+ !mSettings.openInBackground(),
+ true);
if (newTab != null && newTab != parent) {
parent.addChildTab(newTab);
}
@@ -610,6 +619,7 @@ public class Controller
mNetworkHandler.onPause();
WebView.disablePlatformNotifications();
+ mCrashRecoveryHandler.clearState();
}
void onSaveInstanceState(Bundle outState) {
@@ -911,6 +921,11 @@ public class Controller
}
mDataController.updateVisitedHistory(url);
WebIconDatabase.getInstance().retainIconForPageUrl(url);
+ if (!mActivityPaused) {
+ // Since we clear the state in onPause, don't backup the current
+ // state if we are already paused
+ mCrashRecoveryHandler.backupState();
+ }
}
@Override
@@ -1056,14 +1071,20 @@ public class Controller
mActivity.startActivity(intent);
}
- public void activateVoiceSearchMode(String title) {
- mUi.showVoiceTitleBar(title);
+ @Override
+ public void activateVoiceSearchMode(String title, List<String> results) {
+ mUi.showVoiceTitleBar(title, results);
}
public void revertVoiceSearchMode(Tab tab) {
mUi.revertVoiceTitleBar(tab);
}
+ public boolean supportsVoiceSearch() {
+ SearchEngine searchEngine = getSettings().getSearchEngine();
+ return (searchEngine != null && searchEngine.supportsVoiceSearch());
+ }
+
public void showCustomView(Tab tab, View view,
WebChromeClient.CustomViewCallback callback) {
if (tab.inForeground()) {
@@ -1098,7 +1119,7 @@ public class Controller
case PREFERENCES_PAGE:
if (resultCode == Activity.RESULT_OK && intent != null) {
String action = intent.getStringExtra(Intent.EXTRA_TEXT);
- if (BrowserSettings.PREF_CLEAR_HISTORY.equals(action)) {
+ if (PreferenceKeys.PREF_PRIVACY_CLEAR_HISTORY.equals(action)) {
mTabControl.removeParentChildRelationShips();
}
}
@@ -1161,7 +1182,11 @@ public class Controller
removeComboView();
if (!TextUtils.isEmpty(url)) {
if (newTab) {
- openTab(mTabControl.getCurrentTab(), url, false);
+ final Tab parent = mTabControl.getCurrentTab();
+ openTab(url,
+ (parent != null) && parent.isPrivateBrowsingEnabled(),
+ !mSettings.openInBackground(),
+ true);
} else {
final Tab currentTab = mTabControl.getCurrentTab();
dismissSubWindow(currentTab);
@@ -1335,8 +1360,7 @@ public class Controller
boolean showNewTab = mTabControl.canCreateNewTab();
MenuItem newTabItem
= menu.findItem(R.id.open_newtab_context_menu_id);
- newTabItem.setTitle(
- BrowserSettings.getInstance().openInBackground()
+ newTabItem.setTitle(getSettings().openInBackground()
? R.string.contextmenu_openlink_newwindow_background
: R.string.contextmenu_openlink_newwindow);
newTabItem.setVisible(showNewTab);
@@ -1363,8 +1387,12 @@ public class Controller
@Override
public boolean onMenuItemClick(MenuItem item) {
final Tab parent = mTabControl.getCurrentTab();
- final Tab newTab = openTab(parent,
- extra, false);
+ final Tab newTab =
+ openTab(extra,
+ (parent != null)
+ && parent.isPrivateBrowsingEnabled(),
+ !mSettings.openInBackground(),
+ true);
if (newTab != parent) {
parent.addChildTab(newTab);
}
@@ -1465,12 +1493,12 @@ public class Controller
PackageManager.MATCH_DEFAULT_ONLY);
menu.findItem(R.id.share_page_menu_id).setVisible(ri != null);
- boolean isNavDump = mSettings.isNavDump();
+ boolean isNavDump = mSettings.enableNavDump();
final MenuItem nav = menu.findItem(R.id.dump_nav_menu_id);
nav.setVisible(isNavDump);
nav.setEnabled(isNavDump);
- boolean showDebugSettings = mSettings.showDebugSettings();
+ boolean showDebugSettings = mSettings.isDebugEnabled();
final MenuItem counter = menu.findItem(R.id.dump_counters_menu_id);
counter.setVisible(showDebugSettings);
counter.setEnabled(showDebugSettings);
@@ -1683,7 +1711,7 @@ public class Controller
Tab desiredTab = mTabControl.getTab(id);
if (desiredTab != null &&
desiredTab != mTabControl.getCurrentTab()) {
- switchToTab(id);
+ switchToTab(desiredTab);
}
break;
}
@@ -1774,7 +1802,6 @@ public class Controller
// title bar once again.
mExtendedMenuOpen = false;
mUi.onExtendedMenuClosed(mInLoad);
- mUi.onOptionsMenuOpened();
}
}
} else {
@@ -2103,7 +2130,8 @@ public class Controller
mTabControl.removeTab(tab);
}
- protected void setActiveTab(Tab tab) {
+ @Override
+ public void setActiveTab(Tab tab) {
// monkey protection against delayed start
if (tab != null) {
mTabControl.setCurrentTab(tab);
@@ -2116,9 +2144,9 @@ public class Controller
Tab current = mTabControl.getCurrentTab();
if (current != null
&& current.getWebView().copyBackForwardList().getSize() == 0) {
- Tab parent = current.getParentTab();
+ Tab parent = current.getParent();
if (parent != null) {
- switchToTab(mTabControl.getTabIndex(parent));
+ switchToTab(parent);
closeTab(current);
}
}
@@ -2135,7 +2163,7 @@ public class Controller
// TODO: analyze why the remove and add are necessary
mUi.attachTab(appTab);
if (mTabControl.getCurrentTab() != appTab) {
- switchToTab(mTabControl.getTabIndex(appTab));
+ switchToTab(appTab);
loadUrlDataIn(appTab, urlData);
} else {
// If the tab was the current tab, we have to attach
@@ -2169,92 +2197,74 @@ public class Controller
}
}
- @Override
- public Tab openTabToHomePage() {
- // check for max tabs
- if (mTabControl.canCreateNewTab()) {
- return openTabAndShow(null, new UrlData(mSettings.getHomePage()),
- false, null);
- } else {
- mUi.showMaxTabsWarning();
- return null;
+ // open a non inconito tab with the given url data
+ // and set as active tab
+ public Tab openTab(UrlData urlData) {
+ Tab tab = createNewTab(false, true, true);
+ if ((tab != null) && !urlData.isEmpty()) {
+ loadUrlDataIn(tab, urlData);
}
+ return tab;
}
- protected Tab openTab(Tab parent, String url, boolean forceForeground) {
- if (mSettings.openInBackground() && !forceForeground) {
- Tab tab = mTabControl.createNewTab(false, null, null,
- (parent != null) && parent.isPrivateBrowsingEnabled());
- if (tab != null) {
- addTab(tab);
- WebView view = tab.getWebView();
- loadUrl(view, url);
- }
- return tab;
- } else {
- return openTabAndShow(parent, new UrlData(url), false, null);
- }
+ @Override
+ public Tab openTabToHomePage() {
+ return openTab(mSettings.getHomePage(), false, true, false);
}
+ @Override
+ public Tab openIncognitoTab() {
+ return openTab(INCOGNITO_URI, true, true, false);
+ }
- // This method does a ton of stuff. It will attempt to create a new tab
- // if we haven't reached MAX_TABS. Otherwise it uses the current tab. If
- // url isn't null, it will load the given url.
- public Tab openTabAndShow(Tab parent, final UrlData urlData,
- boolean closeOnExit, String appId) {
- final Tab currentTab = mTabControl.getCurrentTab();
- if (mTabControl.canCreateNewTab()) {
- final Tab tab = mTabControl.createNewTab(closeOnExit, appId,
- urlData.mUrl,
- (parent != null) && parent.isPrivateBrowsingEnabled());
- WebView webview = tab.getWebView();
- // We must set the new tab as the current tab to reflect the old
- // animation behavior.
- addTab(tab);
- setActiveTab(tab);
- if (!urlData.isEmpty()) {
- loadUrlDataIn(tab, urlData);
- }
- return tab;
- } else {
- // Get rid of the subwindow if it exists
- dismissSubWindow(currentTab);
- if (!urlData.isEmpty()) {
- // Load the given url.
- loadUrlDataIn(currentTab, urlData);
+ @Override
+ public Tab openTab(String url, boolean incognito, boolean setActive,
+ boolean useCurrent) {
+ Tab tab = createNewTab(incognito, setActive, useCurrent);
+ if (tab != null) {
+ WebView w = tab.getWebView();
+ if (url != null) {
+ loadUrl(w, url);
}
- return currentTab;
}
+ return tab;
}
- @Override
- public Tab openIncognitoTab() {
+ // this method will attempt to create a new tab
+ // incognito: private browsing tab
+ // setActive: ste tab as current tab
+ // useCurrent: if no new tab can be created, return current tab
+ private Tab createNewTab(boolean incognito, boolean setActive,
+ boolean useCurrent) {
+ Tab tab = null;
if (mTabControl.canCreateNewTab()) {
- Tab currentTab = mTabControl.getCurrentTab();
- Tab tab = mTabControl.createNewTab(false, null,
- null, true);
+ tab = mTabControl.createNewTab(incognito);
addTab(tab);
- setActiveTab(tab);
- loadUrlDataIn(tab, new UrlData("browser:incognito"));
- return tab;
+ if (setActive) {
+ setActiveTab(tab);
+ }
} else {
- mUi.showMaxTabsWarning();
- return null;
+ if (useCurrent) {
+ tab = mTabControl.getCurrentTab();
+ // Get rid of the subwindow if it exists
+ dismissSubWindow(tab);
+ } else {
+ mUi.showMaxTabsWarning();
+ }
}
+ return tab;
}
/**
- * @param index Index of the tab to change to, as defined by
- * mTabControl.getTabIndex(Tab t).
+ * @param tab the tab to switch to
* @return boolean True if we successfully switched to a different tab. If
* the indexth tab is null, or if that tab is the same as
* the current one, return false.
*/
@Override
- public boolean switchToTab(int index) {
+ public boolean switchToTab(Tab tab) {
// hide combo view if open
removeComboView();
- Tab tab = mTabControl.getTab(index);
Tab currentTab = mTabControl.getCurrentTab();
if (tab == null || tab == currentTab) {
return false;
@@ -2267,25 +2277,20 @@ public class Controller
public void closeCurrentTab() {
// hide combo view if open
removeComboView();
- final Tab current = mTabControl.getCurrentTab();
if (mTabControl.getTabCount() == 1) {
mActivity.finish();
return;
}
- final Tab parent = current.getParentTab();
- int indexToShow = -1;
- if (parent != null) {
- indexToShow = mTabControl.getTabIndex(parent);
- } else {
- final int currentIndex = mTabControl.getCurrentIndex();
- // Try to move to the tab to the right
- indexToShow = currentIndex + 1;
- if (indexToShow > mTabControl.getTabCount() - 1) {
- // Try to move to the tab to the left
- indexToShow = currentIndex - 1;
+ final Tab current = mTabControl.getCurrentTab();
+ final int pos = mTabControl.getCurrentPosition();
+ Tab newTab = current.getParent();
+ if (newTab == null) {
+ newTab = mTabControl.getTab(pos + 1);
+ if (newTab == null) {
+ newTab = mTabControl.getTab(pos - 1);
}
}
- if (switchToTab(indexToShow)) {
+ if (switchToTab(newTab)) {
// Close window
closeTab(current);
}
@@ -2299,10 +2304,6 @@ public class Controller
public void closeTab(Tab tab) {
// hide combo view if open
removeComboView();
- int currentIndex = mTabControl.getCurrentIndex();
- int removeIndex = mTabControl.getTabIndex(tab);
- Tab newtab = mTabControl.getTab(currentIndex);
- setActiveTab(newtab);
removeTab(tab);
}
@@ -2370,18 +2371,12 @@ public class Controller
} else {
// Check to see if we are closing a window that was created by
// another window. If so, we switch back to that window.
- Tab parent = current.getParentTab();
+ Tab parent = current.getParent();
if (parent != null) {
- switchToTab(mTabControl.getTabIndex(parent));
+ switchToTab(parent);
// Now we close the other tab
closeTab(current);
} else {
- if (current.closeOnExit()) {
- // This will finish the activity if there is only one tab
- // open or it will switch to the next available tab if
- // available.
- closeCurrentTab();
- }
/*
* Instead of finishing the activity, simply push this to the back
* of the stack and let ActivityManager to choose the foreground
@@ -2414,12 +2409,6 @@ public class Controller
startSearch(result, false, bundle, false);
}
- @Override
- public void startSearch(String url) {
- startSearch(mSettings.getHomePage().equals(url) ? null : url, true,
- null, false);
- }
-
private void startSearch(String initialQuery, boolean selectInitialQuery,
Bundle appSearchData, boolean globalSearch) {
if (appSearchData == null) {
@@ -2441,21 +2430,22 @@ public class Controller
return bundle;
}
- /**
+ /**
* helper method for key handler
* returns the current tab if it can't advance
*/
- private int getNextTabIndex() {
- return Math.min(mTabControl.getTabCount() - 1,
- mTabControl.getCurrentIndex() + 1);
+ private Tab getNextTab() {
+ return mTabControl.getTab(Math.min(mTabControl.getTabCount() - 1,
+ mTabControl.getCurrentPosition() + 1));
}
/**
* helper method for key handler
* returns the current tab if it can't advance
*/
- private int getPrevTabIndex() {
- return Math.max(0, mTabControl.getCurrentIndex() - 1);
+ private Tab getPrevTab() {
+ return mTabControl.getTab(Math.max(0,
+ mTabControl.getCurrentPosition() - 1));
}
/**
@@ -2489,10 +2479,10 @@ public class Controller
if (event.isCtrlPressed()) {
if (event.isShiftPressed()) {
// prev tab
- switchToTab(getPrevTabIndex());
+ switchToTab(getPrevTab());
} else {
// next tab
- switchToTab(getNextTabIndex());
+ switchToTab(getNextTab());
}
return true;
}