diff options
Diffstat (limited to 'src/com/android/browser/Controller.java')
-rw-r--r-- | src/com/android/browser/Controller.java | 284 |
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; } |