FileDocCategorySizeDatePackage
BrowserActivity.javaAPI DocAndroid 1.5 API190850Wed May 06 22:42:42 BST 2009com.android.browser

BrowserActivity

public class BrowserActivity extends android.app.Activity implements View.OnCreateContextMenuListener, android.webkit.DownloadListener, KeyTracker.OnKeyTracker

Fields Summary
private com.google.android.googleapps.IGoogleLoginService
mGls
private android.content.ServiceConnection
mGlsConnection
private android.hardware.SensorManager
mSensorManager
private final android.hardware.SensorListener
mSensorListener
Looking for the pattern like this * * * *** * ******* * * * * *
private static final int
TAB_ANIMATION_DURATION
private static final int
TAB_OVERVIEW_DELAY
public static final int
LOAD_URL
public static final int
STOP_LOAD
private static final int
FOCUS_NODE_HREF
private static final int
CANCEL_CREDS_REQUEST
private static final int
ANIMATE_FROM_OVERVIEW
private static final int
ANIMATE_TO_OVERVIEW
private static final int
OPEN_TAB_AND_SHOW
private static final int
CHECK_MEMORY
private static final int
RELEASE_WAKELOCK
private android.os.Handler
mHandler
static final String
SCHEME_WTAI
static final String
SCHEME_WTAI_MC
static final String
SCHEME_WTAI_SD
static final String
SCHEME_WTAI_AP
private final android.webkit.WebViewClient
mWebViewClient
private final android.webkit.WebChromeClient
mWebChromeClient
static final Pattern
ACCEPTED_URI_SCHEMA
private static final int
LOCK_ICON_UNSECURE
private static final int
LOCK_ICON_SECURE
private static final int
LOCK_ICON_MIXED
private int
mLockIconType
private int
mPrevLockType
private BrowserSettings
mSettings
private TabControl
mTabControl
private android.content.ContentResolver
mResolver
private android.widget.FrameLayout
mContentView
private ImageGrid
mTabOverview
private int
mCurrentMenuState
private int
mMenuState
private static final int
EMPTY_MENU
private android.view.Menu
mMenu
private FindDialog
mFindDialog
boolean
mCanChord
private boolean
mInLoad
private boolean
mIsNetworkUp
private boolean
mPageStarted
private boolean
mActivityInPause
private boolean
mMenuIsDown
private final KeyTracker
mKeyTracker
private boolean
mTrackTrackball
private static boolean
mInTrace
private static final int[]
SYSTEM_CPU_FORMAT
private long
mStart
private long
mProcessStart
private long
mUserStart
private long
mSystemStart
private long
mIdleStart
private long
mIrqStart
private long
mUiStart
private android.graphics.drawable.Drawable
mMixLockIcon
private android.graphics.drawable.Drawable
mSecLockIcon
private android.graphics.drawable.Drawable
mGenericFavicon
private android.app.AlertDialog
mAlertDialog
private android.app.ProgressDialog
mCredsDlg
private String
mUrl
private String
mTitle
private android.app.AlertDialog
mPageInfoDialog
private TabControl.Tab
mPageInfoView
private Boolean
mPageInfoFromShowSSLCertificateOnError
private android.app.AlertDialog
mSSLCertificateOnErrorDialog
private android.webkit.WebView
mSSLCertificateOnErrorView
private android.webkit.SslErrorHandler
mSSLCertificateOnErrorHandler
private android.net.http.SslError
mSSLCertificateOnErrorError
private android.app.AlertDialog
mSSLCertificateDialog
private TabControl.Tab
mSSLCertificateView
private android.app.AlertDialog
mHttpAuthenticationDialog
private android.webkit.HttpAuthHandler
mHttpAuthHandler
static final FrameLayout.LayoutParams
COVER_SCREEN_PARAMS
static String
QuickSearch_G
static final String
QuickSearch_W
static final String
QuickSearch_D
static final String
QuickSearch_L
static final String
QUERY_PLACE_HOLDER
static final String
GOOGLE_SEARCH_SOURCE_SEARCHKEY
static final String
GOOGLE_SEARCH_SOURCE_GOTO
static final String
GOOGLE_SEARCH_SOURCE_TYPE
static final String
GOOGLE_SEARCH_SOURCE_SUGGEST
static final String
GOOGLE_SEARCH_SOURCE_UNKNOWN
private static final String
LOGTAG
private TabListener
mTabListener
private String
mLastEnteredUrl
private PowerManager.WakeLock
mWakeLock
private static final int
WAKELOCK_TIMEOUT
private android.widget.Toast
mStopToast
private int
mAnimationCount
private static final int[]
WINDOW_SHORTCUT_ID_ARRAY
private android.content.IntentFilter
mNetworkStateChangedFilter
private android.content.BroadcastReceiver
mNetworkStateIntentReceiver
static final int
COMBO_PAGE
static final int
DOWNLOAD_PAGE
static final int
PREFERENCES_PAGE
static final int
CHECK_MEMORY_INTERVAL
Constructors Summary
Methods Summary
private voidanimateFromTabOverview(com.android.browser.BrowserActivity$AnimatingView view, boolean newTab, android.os.Message msg)

        // firstVisible is the first visible tab on the screen.  This helps
        // to know which corner of the screen the selected tab is.
        int firstVisible = mTabOverview.getFirstVisiblePosition();
        // tabPosition is the 0-based index of of the tab being opened
        int tabPosition = mTabControl.getTabIndex(view.mTab);
        if (!((ImageAdapter) mTabOverview.getAdapter()).maxedOut()) {
            // Add one to make room for the "New Tab" cell.
            tabPosition++;
        }
        // If this is a new tab, animate from the "New Tab" cell.
        if (newTab) {
            tabPosition = 0;
        }
        // Location corresponds to the four corners of the screen.
        // A new tab or 0 is upper left, 0 for an old tab is upper
        // right, 1 is lower left, and 2 is lower right
        int location = tabPosition - firstVisible;

        // Find the view at this location.
        final View v = mTabOverview.getChildAt(location);

        // Wait until the animation completes to replace the AnimatingView.
        final Animation.AnimationListener l =
                new Animation.AnimationListener() {
                    public void onAnimationStart(Animation a) {}
                    public void onAnimationRepeat(Animation a) {}
                    public void onAnimationEnd(Animation a) {
                        mHandler.post(new Runnable() {
                            public void run() {
                                mContentView.removeView(view);
                                // Dismiss the tab overview. If the cell at the
                                // given location is null, set the fade
                                // parameter to true.
                                dismissTabOverview(v == null);
                                TabControl.Tab t =
                                        mTabControl.getCurrentTab();
                                mMenuState = R.id.MAIN_MENU;
                                // Resume regular updates.
                                t.getWebView().resumeTimers();
                                // Dispatch the message after the animation
                                // completes.
                                if (msg != null) {
                                    msg.sendToTarget();
                                }
                                // The animation is done and the tab overview is
                                // gone so allow key events and other animations
                                // to begin.
                                mAnimationCount--;
                                // Reset all the title bar info.
                                resetTitle();
                            }
                        });
                    }
                };

        if (v != null) {
            final Animation anim = createTabAnimation(view, v, false);
            // Set the listener and start animating
            anim.setAnimationListener(l);
            view.startAnimation(anim);
            // Make the view VISIBLE during the animation.
            view.setVisibility(View.VISIBLE);
        } else {
            // Go ahead and do all the cleanup.
            l.onAnimationEnd(null);
        }
    
private voidanimateToTabOverview(int newIndex, boolean remove, com.android.browser.BrowserActivity$AnimatingView view)

        // Find the view in the ImageGrid allowing for the "New Tab" cell.
        int position = mTabControl.getTabIndex(view.mTab);
        if (!((ImageAdapter) mTabOverview.getAdapter()).maxedOut()) {
            position++;
        }

        // Offset the tab position with the first visible position to get a
        // number between 0 and 3.
        position -= mTabOverview.getFirstVisiblePosition();

        // Grab the view that we are going to animate to.
        final View v = mTabOverview.getChildAt(position);

        final Animation.AnimationListener l =
                new Animation.AnimationListener() {
                    public void onAnimationStart(Animation a) {
                        mTabOverview.requestFocus();
                        // Clear the listener so we don't trigger a tab
                        // selection.
                        mTabOverview.setListener(null);
                    }
                    public void onAnimationRepeat(Animation a) {}
                    public void onAnimationEnd(Animation a) {
                        // We are no longer animating so decrement the count.
                        mAnimationCount--;
                        // Make the view GONE so that it will not draw between
                        // now and when the Runnable is handled.
                        view.setVisibility(View.GONE);
                        // Post a runnable since we can't modify the view
                        // hierarchy during this callback.
                        mHandler.post(new Runnable() {
                            public void run() {
                                // Remove the AnimatingView.
                                mContentView.removeView(view);
                                if (mTabOverview != null) {
                                    // Make newIndex visible.
                                    mTabOverview.setCurrentIndex(newIndex);
                                    // Restore the listener.
                                    mTabOverview.setListener(mTabListener);
                                    // Change the menu to TAB_MENU if the
                                    // ImageGrid is interactive.
                                    if (mTabOverview.isLive()) {
                                        mMenuState = R.id.TAB_MENU;
                                        mTabOverview.requestFocus();
                                    }
                                }
                                // If a remove was requested, remove the tab.
                                if (remove) {
                                    // During a remove, the current tab has
                                    // already changed. Remember the current one
                                    // here.
                                    final TabControl.Tab currentTab =
                                            mTabControl.getCurrentTab();
                                    // Remove the tab at newIndex from
                                    // TabControl and the tab overview.
                                    final TabControl.Tab tab =
                                            mTabControl.getTab(newIndex);
                                    mTabControl.removeTab(tab);
                                    // Restore the current tab.
                                    if (currentTab != tab) {
                                        mTabControl.setCurrentTab(currentTab);
                                    }
                                    if (mTabOverview != null) {
                                        mTabOverview.remove(newIndex);
                                        // Make the current tab visible.
                                        mTabOverview.setCurrentIndex(
                                                mTabControl.getCurrentIndex());
                                    }
                                }
                            }
                        });
                    }
                };

        // Do an animation if there is a view to animate to.
        if (v != null) {
            // Create our animation
            final Animation anim = createTabAnimation(view, v, true);
            anim.setAnimationListener(l);
            // Start animating
            view.startAnimation(anim);
        } else {
            // If something goes wrong and we didn't find a view to animate to,
            // just do everything here.
            l.onAnimationStart(null);
            l.onAnimationEnd(null);
        }
    
private voidattachSubWindow(TabControl.Tab t)

        // If a sub window exists, attach it to the content view.
        final WebView subView = t.getSubWebView();
        if (subView != null) {
            final View container = t.getSubWebViewContainer();
            mContentView.addView(container, COVER_SCREEN_PARAMS);
            subView.requestFocus();
        }
    
private voidattachTabToContentView(TabControl.Tab t)

        final WebView main = t.getWebView();
        // Attach the main WebView.
        mContentView.addView(main, COVER_SCREEN_PARAMS);
        // Attach the sub window if necessary
        attachSubWindow(t);
        // Request focus on the top window.
        t.getTopWindow().requestFocus();
    
private voidbookmarksOrHistoryPicker(boolean startWithHistory)

        WebView current = mTabControl.getCurrentWebView();
        if (current == null) {
            return;
        }
        Intent intent = new Intent(this,
                CombinedBookmarkHistoryActivity.class);
        String title = current.getTitle();
        String url = current.getUrl();
        // Just in case the user opens bookmarks before a page finishes loading
        // so the current history item, and therefore the page, is null.
        if (null == url) {
            url = mLastEnteredUrl;
            // This can happen.
            if (null == url) {
                url = mSettings.getHomePage();
            }
        }
        // In case the web page has not yet received its associated title.
        if (title == null) {
            title = url;
        }
        intent.putExtra("title", title);
        intent.putExtra("url", url);
        intent.putExtra("maxTabsOpen",
                mTabControl.getTabCount() >= TabControl.MAX_TABS);
        if (startWithHistory) {
            intent.putExtra(CombinedBookmarkHistoryActivity.STARTING_TAB,
                    CombinedBookmarkHistoryActivity.HISTORY_TAB);
        }
        startActivityForResult(intent, COMBO_PAGE);
    
private static java.lang.StringbuildTitleUrl(java.lang.String url)

param
url The URL to build a title version of the URL from.
return
The title version of the URL or null if fails. The title version of the URL can be either the URL hostname, or the hostname with an "https://" prefix (for secure URLs), or an empty string if, for example, the URL in question is a file:// URL with no hostname.

        String titleUrl = null;

        if (url != null) {
            try {
                // parse the url string
                URL urlObj = new URL(url);
                if (urlObj != null) {
                    titleUrl = "";

                    String protocol = urlObj.getProtocol();
                    String host = urlObj.getHost();

                    if (host != null && 0 < host.length()) {
                        titleUrl = host;
                        if (protocol != null) {
                            // if a secure site, add an "https://" prefix!
                            if (protocol.equalsIgnoreCase("https")) {
                                titleUrl = protocol + "://" + host;
                            }
                        }
                    }
                }
            } catch (MalformedURLException e) {}
        }

        return titleUrl;
    
private java.lang.StringbuildUrlTitle(java.lang.String url, java.lang.String title)
Builds and returns the page title, which is some combination of the page URL and title.

param
url The URL of the site being loaded.
param
title The title of the site being loaded.
return
The page title.

        String urlTitle = "";

        if (url != null) {
            String titleUrl = buildTitleUrl(url);

            if (title != null && 0 < title.length()) {
                if (titleUrl != null && 0 < titleUrl.length()) {
                    urlTitle = titleUrl + ": " + title;
                } else {
                    urlTitle = title;
                }
            } else {
                if (titleUrl != null) {
                    urlTitle = titleUrl;
                }
            }
        }

        return urlTitle;
    
private voidcancelStopToast()

        if (mStopToast != null) {
            mStopToast.cancel();
            mStopToast = null;
        }
    
private voidcheckMemory()

        ActivityManager.MemoryInfo mi = new ActivityManager.MemoryInfo();
        ((ActivityManager) getSystemService(ACTIVITY_SERVICE))
                .getMemoryInfo(mi);
        // FIXME: mi.lowMemory is too aggressive, use (mi.availMem <
        // mi.threshold) for now
        //        if (mi.lowMemory) {
        if (mi.availMem < mi.threshold) {
            Log.w(LOGTAG, "Browser is freeing memory now because: available="
                            + (mi.availMem / 1024) + "K threshold="
                            + (mi.threshold / 1024) + "K");
            mTabControl.freeMemory();
        }
    
public voidcloseFind()

        mMenuState = R.id.MAIN_MENU;
    
java.lang.StringcomposeSearchUrl(java.lang.String search)

        return URLUtil.composeSearchUrl(search, QuickSearch_G,
                QUERY_PLACE_HOLDER);
    
private voidcopy(java.lang.CharSequence text)

        try {
            IClipboard clip = IClipboard.Stub.asInterface(ServiceManager.getService("clipboard"));
            if (clip != null) {
                clip.setClipboardText(text);
            }
        } catch (android.os.RemoteException e) {
            Log.e(LOGTAG, "Copy failed", e);
        }
    
private voidcopyPlugins(boolean overwrite)
Copy the content of assets/plugins/ to the app_plugins directory in the data partition. This function is called every time the browser is started. We first check if the system image is newer than the one that copied the plugins (if there's plugins in the data partition). If this is the case, we then check if the versions are different. If they are different, we clean the plugins directory in the data partition, then start a thread to copy the plugins while the browser continue to load.

param
overwrite if true overwrite the files even if they are already present (to let the user "reset" the plugins if needed).

        CopyPlugins copyPluginsFromAssets = new CopyPlugins(overwrite, this);
        copyPluginsFromAssets.initPluginsPath();
        if (copyPluginsFromAssets.newSystemImage())  {
          if (copyPluginsFromAssets.checkIsDifferentVersions()) {
            copyPluginsFromAssets.cleanPluginsDirectory();
            Thread copyplugins = new Thread(copyPluginsFromAssets);
            copyplugins.setName("CopyPlugins");
            copyplugins.start();
          }
        }
    
private android.os.BundlecreateGoogleSearchSourceBundle(java.lang.String source)

        Bundle bundle = new Bundle();
        bundle.putString(SearchManager.SOURCE, source);
        return bundle;
    
private android.view.animation.AnimationcreateTabAnimation(com.android.browser.BrowserActivity$AnimatingView view, android.view.View cell, boolean scaleDown)

        final AnimationSet set = new AnimationSet(true);
        final float scaleX = (float) cell.getWidth() / view.getWidth();
        final float scaleY = (float) cell.getHeight() / view.getHeight();
        if (scaleDown) {
            set.addAnimation(new ScaleAnimation(1.0f, scaleX, 1.0f, scaleY));
            set.addAnimation(new TranslateAnimation(0, cell.getLeft(), 0,
                    cell.getTop()));
        } else {
            set.addAnimation(new ScaleAnimation(scaleX, 1.0f, scaleY, 1.0f));
            set.addAnimation(new TranslateAnimation(cell.getLeft(), 0,
                    cell.getTop(), 0));
        }
        set.setDuration(TAB_ANIMATION_DURATION);
        set.setInterpolator(new DecelerateInterpolator());
        return set;
    
voiddismissSubWindow(TabControl.Tab t)

        final WebView mainView = t.getWebView();
        if (t.getSubWebView() != null) {
            // Remove the container view and request focus on the main WebView.
            mContentView.removeView(t.getSubWebViewContainer());
            mainView.requestFocus();
            // Tell the TabControl to dismiss the subwindow. This will destroy
            // the WebView.
            mTabControl.dismissSubWindow(t);
        }
    
private voiddismissTabOverview(boolean fade)

        if (fade) {
            AlphaAnimation anim = new AlphaAnimation(1.0f, 0.0f);
            anim.setDuration(500);
            anim.startNow();
            mTabOverview.startAnimation(anim);
        }
        // Just in case there was a problem with animating away from the tab
        // overview
        WebView current = mTabControl.getCurrentWebView();
        if (current != null) {
            current.setVisibility(View.VISIBLE);
        } else {
            Log.e(LOGTAG, "No current WebView in dismissTabOverview");
        }
        // Make the sub window container visible.
        if (mTabControl.getCurrentSubWindow() != null) {
            mTabControl.getCurrentTab().getSubWebViewContainer()
                    .setVisibility(View.VISIBLE);
        }
        mContentView.removeView(mTabOverview);
        mTabOverview.clear();
        mTabOverview = null;
        mTabListener = null;
    
static java.lang.StringfixUrl(java.lang.String inUrl)

        if (inUrl.startsWith("http://") || inUrl.startsWith("https://"))
            return inUrl;
        if (inUrl.startsWith("http:") ||
                inUrl.startsWith("https:")) {
            if (inUrl.startsWith("http:/") || inUrl.startsWith("https:/")) {
                inUrl = inUrl.replaceFirst("/", "//");
            } else inUrl = inUrl.replaceFirst(":", "://");
        }
        return inUrl;
    
public intgetProgress()

        WebView w = mTabControl.getCurrentWebView();
        if (w != null) {
            return w.getProgress();
        } else {
            return 100;
        }
    
android.webkit.WebViewgetTopWindow()

        return mTabControl.getCurrentTopWebView();
    
private java.lang.StringgetUrlFromIntent(android.content.Intent intent)

        String url = null;
        if (intent != null) {
            final String action = intent.getAction();
            if (Intent.ACTION_VIEW.equals(action)) {
                url = smartUrlFilter(intent.getData());
                if (url != null && url.startsWith("content:")) {
                    /* Append mimetype so webview knows how to display */
                    String mimeType = intent.resolveType(getContentResolver());
                    if (mimeType != null) {
                        url += "?" + mimeType;
                    }
                }
            } else if (Intent.ACTION_SEARCH.equals(action)
                    || MediaStore.INTENT_ACTION_MEDIA_SEARCH.equals(action)
                    || Intent.ACTION_WEB_SEARCH.equals(action)) {
                url = intent.getStringExtra(SearchManager.QUERY);
                if (url != null) {
                    mLastEnteredUrl = url;
                    // Don't add Urls, just search terms.
                    // Urls will get added when the page is loaded.
                    if (!Regex.WEB_URL_PATTERN.matcher(url).matches()) {
                        Browser.updateVisitedHistory(mResolver, url, false);
                    }
                    // In general, we shouldn't modify URL from Intent.
                    // But currently, we get the user-typed URL from search box as well.
                    url = fixUrl(url);
                    url = smartUrlFilter(url);
                    String searchSource = "&source=android-" + GOOGLE_SEARCH_SOURCE_SUGGEST + "&";
                    if (url.contains(searchSource)) {
                        String source = null;
                        final Bundle appData = intent.getBundleExtra(SearchManager.APP_DATA);
                        if (appData != null) {
                            source = appData.getString(SearchManager.SOURCE);
                        }
                        if (TextUtils.isEmpty(source)) {
                            source = GOOGLE_SEARCH_SOURCE_UNKNOWN;
                        }
                        url = url.replace(searchSource, "&source=android-"+source+"&");
                    }
                }
            }
        }
        return url;
    
android.webkit.WebChromeClientgetWebChromeClient()


    //--------------------------------------------------------------------------
    // WebChromeClient implementation
    //--------------------------------------------------------------------------

    /* package */   
        return mWebChromeClient;
    
android.webkit.WebViewClientgetWebViewClient()


    /* package */   
        return mWebViewClient;
    
intgetWindowCount()

      if(mTabControl != null){
        return mTabControl.getTabCount();
      }
      return 0;
    
private voidgoBackOnePageOrQuit()

        TabControl.Tab current = mTabControl.getCurrentTab();
        if (current == null) {
            /*
             * Instead of finishing the activity, simply push this to the back
             * of the stack and let ActivityManager to choose the foreground
             * activity. As BrowserActivity is singleTask, it will be always the
             * root of the task. So we can use either true or false for
             * moveTaskToBack().
             */
            moveTaskToBack(true);
        }
        WebView w = current.getWebView();
        if (w.canGoBack()) {
            w.goBack();
        } else {
            // Check to see if we are closing a window that was created by
            // another window. If so, we switch back to that window.
            TabControl.Tab parent = current.getParentTab();
            if (parent != null) {
                switchTabs(mTabControl.getCurrentIndex(),
                        mTabControl.getTabIndex(parent), true);
            } else {
                if (current.closeOnExit()) {
                    if (mTabControl.getTabCount() == 1) {
                        finish();
                        return;
                    }
                    // call pauseWebView() now, we won't be able to call it in
                    // onPause() as the WebView won't be valid.
                    pauseWebView();
                    removeTabFromContentView(current);
                    mTabControl.removeTab(current);
                }
                /*
                 * Instead of finishing the activity, simply push this to the back
                 * of the stack and let ActivityManager to choose the foreground
                 * activity. As BrowserActivity is singleTask, it will be always the
                 * root of the task. So we can use either true or false for
                 * moveTaskToBack().
                 */
                moveTaskToBack(true);
            }
        }
    
private android.view.ViewinflateCertificateView(android.net.http.SslCertificate certificate)
Inflates the SSL certificate view (helper method).

param
certificate The SSL certificate.
return
The resultant certificate view with issued-to, issued-by, issued-on, expires-on, and possibly other fields set. If the input certificate is null, returns null.

        if (certificate == null) {
            return null;
        }

        LayoutInflater factory = LayoutInflater.from(this);

        View certificateView = factory.inflate(
            R.layout.ssl_certificate, null);

        // issued to:
        SslCertificate.DName issuedTo = certificate.getIssuedTo();
        if (issuedTo != null) {
            ((TextView) certificateView.findViewById(R.id.to_common))
                .setText(issuedTo.getCName());
            ((TextView) certificateView.findViewById(R.id.to_org))
                .setText(issuedTo.getOName());
            ((TextView) certificateView.findViewById(R.id.to_org_unit))
                .setText(issuedTo.getUName());
        }

        // issued by:
        SslCertificate.DName issuedBy = certificate.getIssuedBy();
        if (issuedBy != null) {
            ((TextView) certificateView.findViewById(R.id.by_common))
                .setText(issuedBy.getCName());
            ((TextView) certificateView.findViewById(R.id.by_org))
                .setText(issuedBy.getOName());
            ((TextView) certificateView.findViewById(R.id.by_org_unit))
                .setText(issuedBy.getUName());
        }

        // issued on:
        String issuedOn = reformatCertificateDate(
            certificate.getValidNotBefore());
        ((TextView) certificateView.findViewById(R.id.issued_on))
            .setText(issuedOn);

        // expires on:
        String expiresOn = reformatCertificateDate(
            certificate.getValidNotAfter());
        ((TextView) certificateView.findViewById(R.id.expires_on))
            .setText(expiresOn);

        return certificateView;
    
private voidloadURL(android.webkit.WebView view, java.lang.String url)

        // In case the user enters nothing.
        if (url != null && url.length() != 0 && view != null) {
            url = smartUrlFilter(url);
            if (!mWebViewClient.shouldOverrideUrlLoading(view, url)) {
                view.loadUrl(url);
            }
        }
    
protected voidonActivityResult(int requestCode, int resultCode, android.content.Intent intent)

        switch (requestCode) {
            case COMBO_PAGE:
                if (resultCode == RESULT_OK && intent != null) {
                    String data = intent.getAction();
                    Bundle extras = intent.getExtras();
                    if (extras != null && extras.getBoolean("new_window", false)) {
                        openTab(data);
                    } else {
                        final TabControl.Tab currentTab =
                                mTabControl.getCurrentTab();
                        // If the Window overview is up and we are not in the
                        // middle of an animation, animate away from it to the
                        // current tab.
                        if (mTabOverview != null && mAnimationCount == 0) {
                            sendAnimateFromOverview(currentTab, false, data,
                                    TAB_OVERVIEW_DELAY, null);
                        } else {
                            dismissSubWindow(currentTab);
                            if (data != null && data.length() != 0) {
                                getTopWindow().loadUrl(data);
                            }
                        }
                    }
                }
                break;
            default:
                break;
        }
        getTopWindow().requestFocus();
    
public voidonConfigurationChanged(android.content.res.Configuration newConfig)

        super.onConfigurationChanged(newConfig);

        if (mPageInfoDialog != null) {
            mPageInfoDialog.dismiss();
            showPageInfo(
                mPageInfoView,
                mPageInfoFromShowSSLCertificateOnError.booleanValue());
        }
        if (mSSLCertificateDialog != null) {
            mSSLCertificateDialog.dismiss();
            showSSLCertificate(
                mSSLCertificateView);
        }
        if (mSSLCertificateOnErrorDialog != null) {
            mSSLCertificateOnErrorDialog.dismiss();
            showSSLCertificateOnError(
                mSSLCertificateOnErrorView,
                mSSLCertificateOnErrorHandler,
                mSSLCertificateOnErrorError);
        }
        if (mHttpAuthenticationDialog != null) {
            String title = ((TextView) mHttpAuthenticationDialog
                    .findViewById(com.android.internal.R.id.alertTitle)).getText()
                    .toString();
            String name = ((TextView) mHttpAuthenticationDialog
                    .findViewById(R.id.username_edit)).getText().toString();
            String password = ((TextView) mHttpAuthenticationDialog
                    .findViewById(R.id.password_edit)).getText().toString();
            int focusId = mHttpAuthenticationDialog.getCurrentFocus()
                    .getId();
            mHttpAuthenticationDialog.dismiss();
            showHttpAuthentication(mHttpAuthHandler, null, null, title,
                    name, password, focusId);
        }
        if (mFindDialog != null && mFindDialog.isShowing()) {
            mFindDialog.onConfigurationChanged(newConfig);
        }
    
public booleanonContextItemSelected(android.view.MenuItem item)

        // chording is not an issue with context menus, but we use the same
        // options selector, so set mCanChord to true so we can access them.
        mCanChord = true;
        int id = item.getItemId();
        final WebView webView = getTopWindow();
        final HashMap hrefMap = new HashMap();
        hrefMap.put("webview", webView);
        final Message msg = mHandler.obtainMessage(
                FOCUS_NODE_HREF, id, 0, hrefMap);
        switch (id) {
            // -- Browser context menu
            case R.id.open_context_menu_id:
            case R.id.open_newtab_context_menu_id:
            case R.id.bookmark_context_menu_id:
            case R.id.save_link_context_menu_id:
            case R.id.share_link_context_menu_id:
            case R.id.copy_link_context_menu_id:
                webView.requestFocusNodeHref(msg);
                break;

            default:
                // For other context menus
                return onOptionsItemSelected(item);
        }
        mCanChord = false;
        return true;
    
public voidonCreate(android.os.Bundle icicle)

        if (Config.LOGV) {
            Log.v(LOGTAG, this + " onStart");
        }
        super.onCreate(icicle);
        this.requestWindowFeature(Window.FEATURE_LEFT_ICON);
        this.requestWindowFeature(Window.FEATURE_RIGHT_ICON);
        this.requestWindowFeature(Window.FEATURE_PROGRESS);
        this.requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);

        // test the browser in OpenGL
        // requestWindowFeature(Window.FEATURE_OPENGL);

        setDefaultKeyMode(DEFAULT_KEYS_SEARCH_LOCAL);

        mResolver = getContentResolver();

        setBaseSearchUrl(PreferenceManager.getDefaultSharedPreferences(this)
                .getString("search_url", ""));

        //
        // start MASF proxy service
        //
        //Intent proxyServiceIntent = new Intent();
        //proxyServiceIntent.setComponent
        //    (new ComponentName(
        //        "com.android.masfproxyservice",
        //        "com.android.masfproxyservice.MasfProxyService"));
        //startService(proxyServiceIntent, null);

        mSecLockIcon = Resources.getSystem().getDrawable(
                android.R.drawable.ic_secure);
        mMixLockIcon = Resources.getSystem().getDrawable(
                android.R.drawable.ic_partial_secure);
        mGenericFavicon = getResources().getDrawable(
                R.drawable.app_web_browser_sm);

        mContentView = (FrameLayout) getWindow().getDecorView().findViewById(
                com.android.internal.R.id.content);

        // Create the tab control and our initial tab
        mTabControl = new TabControl(this);

        // Open the icon database and retain all the bookmark urls for favicons
        retainIconsOnStartup();

        // Keep a settings instance handy.
        mSettings = BrowserSettings.getInstance();
        mSettings.setTabControl(mTabControl);
        mSettings.loadFromDb(this);

        PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
        mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "Browser");

        if (!mTabControl.restoreState(icicle)) {
            // clear up the thumbnail directory if we can't restore the state as
            // none of the files in the directory are referenced any more.
            new ClearThumbnails().execute(
                    mTabControl.getThumbnailDir().listFiles());
            final Intent intent = getIntent();
            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.
            String url = getUrlFromIntent(intent);
            final TabControl.Tab t = mTabControl.createNewTab(
                    Intent.ACTION_VIEW.equals(intent.getAction()) &&
                    intent.getData() != null,
                    intent.getStringExtra(Browser.EXTRA_APPLICATION_ID), url);
            mTabControl.setCurrentTab(t);
            // This is one of the only places we call attachTabToContentView
            // without animating from the tab picker.
            attachTabToContentView(t);
            WebView webView = t.getWebView();
            if (extra != null) {
                int scale = extra.getInt(Browser.INITIAL_ZOOM_LEVEL, 0);
                if (scale > 0 && scale <= 1000) {
                    webView.setInitialScale(scale);
                }
            }
            // If we are not restoring from an icicle, then there is a high
            // likely hood this is the first run. So, check to see if the
            // homepage needs to be configured and copy any plugins from our
            // asset directory to the data partition.
            if ((extra == null || !extra.getBoolean("testing"))
                    && !mSettings.isLoginInitialized()) {
                setupHomePage();
            }
            copyPlugins(true);

            if (url == null || url.length() == 0) {
                if (mSettings.isLoginInitialized()) {
                    webView.loadUrl(mSettings.getHomePage());
                } else {
                    waitForCredentials();
                }
            } else {
                webView.loadUrl(url);
            }
        } else {
            // TabControl.restoreState() will create a new tab even if
            // restoring the state fails. Attach it to the view here since we
            // are not animating from the tab picker.
            attachTabToContentView(mTabControl.getCurrentTab());
        }

        /* enables registration for changes in network status from
           http stack */
        mNetworkStateChangedFilter = new IntentFilter();
        mNetworkStateChangedFilter.addAction(
                ConnectivityManager.CONNECTIVITY_ACTION);
        mNetworkStateIntentReceiver = new BroadcastReceiver() {
                @Override
                public void onReceive(Context context, Intent intent) {
                    if (intent.getAction().equals(
                            ConnectivityManager.CONNECTIVITY_ACTION)) {
                        boolean down = intent.getBooleanExtra(
                                ConnectivityManager.EXTRA_NO_CONNECTIVITY, false);
                        onNetworkToggle(!down);
                    }
                }
            };
    
public voidonCreateContextMenu(android.view.ContextMenu menu, android.view.View v, android.view.ContextMenu.ContextMenuInfo menuInfo)

        WebView webview = (WebView) v;
        WebView.HitTestResult result = webview.getHitTestResult();
        if (result == null) {
            return;
        }

        int type = result.getType();
        if (type == WebView.HitTestResult.UNKNOWN_TYPE) {
            Log.w(LOGTAG,
                    "We should not show context menu when nothing is touched");
            return;
        }
        if (type == WebView.HitTestResult.EDIT_TEXT_TYPE) {
            // let TextView handles context menu
            return;
        }

        // Note, http://b/issue?id=1106666 is requesting that
        // an inflated menu can be used again. This is not available
        // yet, so inflate each time (yuk!)
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.browsercontext, menu);

        // Show the correct menu group
        String extra = result.getExtra();
        menu.setGroupVisible(R.id.PHONE_MENU,
                type == WebView.HitTestResult.PHONE_TYPE);
        menu.setGroupVisible(R.id.EMAIL_MENU,
                type == WebView.HitTestResult.EMAIL_TYPE);
        menu.setGroupVisible(R.id.GEO_MENU,
                type == WebView.HitTestResult.GEO_TYPE);
        menu.setGroupVisible(R.id.IMAGE_MENU,
                type == WebView.HitTestResult.IMAGE_TYPE
                || type == WebView.HitTestResult.SRC_IMAGE_ANCHOR_TYPE);
        menu.setGroupVisible(R.id.ANCHOR_MENU,
                type == WebView.HitTestResult.SRC_ANCHOR_TYPE
                || type == WebView.HitTestResult.SRC_IMAGE_ANCHOR_TYPE);

        // Setup custom handling depending on the type
        switch (type) {
            case WebView.HitTestResult.PHONE_TYPE:
                menu.setHeaderTitle(Uri.decode(extra));
                menu.findItem(R.id.dial_context_menu_id).setIntent(
                        new Intent(Intent.ACTION_VIEW, Uri
                                .parse(WebView.SCHEME_TEL + extra)));
                Intent addIntent = new Intent(Intent.ACTION_INSERT_OR_EDIT);
                addIntent.putExtra(Insert.PHONE, Uri.decode(extra));
                addIntent.setType(Contacts.People.CONTENT_ITEM_TYPE);
                menu.findItem(R.id.add_contact_context_menu_id).setIntent(
                        addIntent);
                menu.findItem(R.id.copy_phone_context_menu_id).setOnMenuItemClickListener(
                        new Copy(extra));
                break;

            case WebView.HitTestResult.EMAIL_TYPE:
                menu.setHeaderTitle(extra);
                menu.findItem(R.id.email_context_menu_id).setIntent(
                        new Intent(Intent.ACTION_VIEW, Uri
                                .parse(WebView.SCHEME_MAILTO + extra)));
                menu.findItem(R.id.copy_mail_context_menu_id).setOnMenuItemClickListener(
                        new Copy(extra));
                break;

            case WebView.HitTestResult.GEO_TYPE:
                menu.setHeaderTitle(extra);
                menu.findItem(R.id.map_context_menu_id).setIntent(
                        new Intent(Intent.ACTION_VIEW, Uri
                                .parse(WebView.SCHEME_GEO
                                        + URLEncoder.encode(extra))));
                menu.findItem(R.id.copy_geo_context_menu_id).setOnMenuItemClickListener(
                        new Copy(extra));
                break;

            case WebView.HitTestResult.SRC_ANCHOR_TYPE:
            case WebView.HitTestResult.SRC_IMAGE_ANCHOR_TYPE:
                TextView titleView = (TextView) LayoutInflater.from(this)
                        .inflate(android.R.layout.browser_link_context_header,
                        null);
                titleView.setText(extra);
                menu.setHeaderView(titleView);
                // decide whether to show the open link in new tab option
                menu.findItem(R.id.open_newtab_context_menu_id).setVisible(
                        mTabControl.getTabCount() < TabControl.MAX_TABS);
                PackageManager pm = getPackageManager();
                Intent send = new Intent(Intent.ACTION_SEND);
                send.setType("text/plain");
                ResolveInfo ri = pm.resolveActivity(send, PackageManager.MATCH_DEFAULT_ONLY);
                menu.findItem(R.id.share_link_context_menu_id).setVisible(ri != null);
                if (type == WebView.HitTestResult.SRC_ANCHOR_TYPE) {
                    break;
                }
                // otherwise fall through to handle image part
            case WebView.HitTestResult.IMAGE_TYPE:
                if (type == WebView.HitTestResult.IMAGE_TYPE) {
                    menu.setHeaderTitle(extra);
                }
                menu.findItem(R.id.view_image_context_menu_id).setIntent(
                        new Intent(Intent.ACTION_VIEW, Uri.parse(extra)));
                menu.findItem(R.id.download_context_menu_id).
                        setOnMenuItemClickListener(new Download(extra));
                break;

            default:
                Log.w(LOGTAG, "We should not get here.");
                break;
        }
    
public booleanonCreateOptionsMenu(android.view.Menu menu)

        super.onCreateOptionsMenu(menu);

        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.browser, menu);
        mMenu = menu;
        updateInLoadMenuItems();
        return true;
    
protected voidonDestroy()

        if (Config.LOGV) {
            Log.v(LOGTAG, "BrowserActivity.onDestroy: this=" + this);
        }
        super.onDestroy();
        // Remove the current tab and sub window
        TabControl.Tab t = mTabControl.getCurrentTab();
        dismissSubWindow(t);
        removeTabFromContentView(t);
        // Destroy all the tabs
        mTabControl.destroy();
        WebIconDatabase.getInstance().close();
        if (mGlsConnection != null) {
            unbindService(mGlsConnection);
            mGlsConnection = null;
        }

        //
        // stop MASF proxy service
        //
        //Intent proxyServiceIntent = new Intent();
        //proxyServiceIntent.setComponent
        //   (new ComponentName(
        //        "com.android.masfproxyservice",
        //        "com.android.masfproxyservice.MasfProxyService"));
        //stopService(proxyServiceIntent);
    
public voidonDownloadStart(java.lang.String url, java.lang.String userAgent, java.lang.String contentDisposition, java.lang.String mimetype, long contentLength)
Notify the host application a download should be done, or that the data should be streamed if a streaming viewer is available.

param
url The full url to the content that should be downloaded
param
contentDisposition Content-disposition http header, if present.
param
mimetype The mimetype of the content reported by the server
param
contentLength The file size reported by the server


                                                                                                
         
                  
        // if we're dealing wih A/V content that's not explicitly marked
        //     for download, check if it's streamable.
        if (contentDisposition == null
                        || !contentDisposition.regionMatches(true, 0, "attachment", 0, 10)) {
            // query the package manager to see if there's a registered handler
            //     that matches.
            Intent intent = new Intent(Intent.ACTION_VIEW);
            intent.setDataAndType(Uri.parse(url), mimetype);
            if (getPackageManager().resolveActivity(intent,
                        PackageManager.MATCH_DEFAULT_ONLY) != null) {
                // someone knows how to handle this mime type with this scheme, don't download.
                try {
                    startActivity(intent);
                    return;
                } catch (ActivityNotFoundException ex) {
                    if (Config.LOGD) {
                        Log.d(LOGTAG, "activity not found for " + mimetype
                                + " over " + Uri.parse(url).getScheme(), ex);
                    }
                    // Best behavior is to fall back to a download in this case
                }
            }
        }
        onDownloadStartNoStream(url, userAgent, contentDisposition, mimetype, contentLength);
    
voidonDownloadStartNoStream(java.lang.String url, java.lang.String userAgent, java.lang.String contentDisposition, java.lang.String mimetype, long contentLength)
Notify the host application a download should be done, even if there is a streaming viewer available for thise type.

param
url The full url to the content that should be downloaded
param
contentDisposition Content-disposition http header, if present.
param
mimetype The mimetype of the content reported by the server
param
contentLength The file size reported by the server


        String filename = URLUtil.guessFileName(url,
                contentDisposition, mimetype);

        // Check to see if we have an SDCard
        String status = Environment.getExternalStorageState();
        if (!status.equals(Environment.MEDIA_MOUNTED)) {
            int title;
            String msg;

            // Check to see if the SDCard is busy, same as the music app
            if (status.equals(Environment.MEDIA_SHARED)) {
                msg = getString(R.string.download_sdcard_busy_dlg_msg);
                title = R.string.download_sdcard_busy_dlg_title;
            } else {
                msg = getString(R.string.download_no_sdcard_dlg_msg, filename);
                title = R.string.download_no_sdcard_dlg_title;
            }

            new AlertDialog.Builder(this)
                .setTitle(title)
                .setIcon(android.R.drawable.ic_dialog_alert)
                .setMessage(msg)
                .setPositiveButton(R.string.ok, null)
                .show();
            return;
        }

        // java.net.URI is a lot stricter than KURL so we have to undo
        // KURL's percent-encoding and redo the encoding using java.net.URI.
        URI uri = null;
        try {
            // Undo the percent-encoding that KURL may have done.
            String newUrl = new String(URLUtil.decode(url.getBytes()));
            // Parse the url into pieces
            WebAddress w = new WebAddress(newUrl);
            String frag = null;
            String query = null;
            String path = w.mPath;
            // Break the path into path, query, and fragment
            if (path.length() > 0) {
                // Strip the fragment
                int idx = path.lastIndexOf('#");
                if (idx != -1) {
                    frag = path.substring(idx + 1);
                    path = path.substring(0, idx);
                }
                idx = path.lastIndexOf('?");
                if (idx != -1) {
                    query = path.substring(idx + 1);
                    path = path.substring(0, idx);
                }
            }
            uri = new URI(w.mScheme, w.mAuthInfo, w.mHost, w.mPort, path,
                    query, frag);
        } catch (Exception e) {
            Log.e(LOGTAG, "Could not parse url for download: " + url, e);
            return;
        }

        // XXX: Have to use the old url since the cookies were stored using the
        // old percent-encoded url.
        String cookies = CookieManager.getInstance().getCookie(url);

        ContentValues values = new ContentValues();
        values.put(Downloads.URI, uri.toString());
        values.put(Downloads.COOKIE_DATA, cookies);
        values.put(Downloads.USER_AGENT, userAgent);
        values.put(Downloads.NOTIFICATION_PACKAGE,
                getPackageName());
        values.put(Downloads.NOTIFICATION_CLASS,
                BrowserDownloadPage.class.getCanonicalName());
        values.put(Downloads.VISIBILITY, Downloads.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
        values.put(Downloads.MIMETYPE, mimetype);
        values.put(Downloads.FILENAME_HINT, filename);
        values.put(Downloads.DESCRIPTION, uri.getHost());
        if (contentLength > 0) {
            values.put(Downloads.TOTAL_BYTES, contentLength);
        }
        if (mimetype == null) {
            // We must have long pressed on a link or image to download it. We
            // are not sure of the mimetype in this case, so do a head request
            new FetchUrlMimeType(this).execute(values);
        } else {
            final Uri contentUri =
                    getContentResolver().insert(Downloads.CONTENT_URI, values);
            viewDownloads(contentUri);
        }

    
public booleanonKeyDown(int keyCode, android.view.KeyEvent event)

        if (keyCode == KeyEvent.KEYCODE_MENU) {
            mMenuIsDown = true;
        }
        boolean handled =  mKeyTracker.doKeyDown(keyCode, event);
        if (!handled) {
            switch (keyCode) {
                case KeyEvent.KEYCODE_SPACE:
                    if (event.isShiftPressed()) {
                        getTopWindow().pageUp(false);
                    } else {
                        getTopWindow().pageDown(false);
                    }
                    handled = true;
                    break;

                default:
                    break;
            }
        }
        return handled || super.onKeyDown(keyCode, event);
    
public KeyTracker.StateonKeyTracker(int keyCode, android.view.KeyEvent event, KeyTracker.Stage stage, int duration)

        // if onKeyTracker() is called after activity onStop()
        // because of accumulated key events,
        // we should ignore it as browser is not active any more.
        WebView topWindow = getTopWindow();
        if (topWindow == null)
            return KeyTracker.State.NOT_TRACKING;

        if (keyCode == KeyEvent.KEYCODE_BACK) {
            // During animations, block the back key so that other animations
            // are not triggered and so that we don't end up destroying all the
            // WebViews before finishing the animation.
            if (mAnimationCount > 0) {
                return KeyTracker.State.DONE_TRACKING;
            }
            if (stage == KeyTracker.Stage.LONG_REPEAT) {
                bookmarksOrHistoryPicker(true);
                return KeyTracker.State.DONE_TRACKING;
            } else if (stage == KeyTracker.Stage.UP) {
                // FIXME: Currently, we do not have a notion of the
                // history picker for the subwindow, but maybe we
                // should?
                WebView subwindow = mTabControl.getCurrentSubWindow();
                if (subwindow != null) {
                    if (subwindow.canGoBack()) {
                        subwindow.goBack();
                    } else {
                        dismissSubWindow(mTabControl.getCurrentTab());
                    }
                } else {
                    goBackOnePageOrQuit();
                }
                return KeyTracker.State.DONE_TRACKING;
            }
            return KeyTracker.State.KEEP_TRACKING;
        }
        return KeyTracker.State.NOT_TRACKING;
    
public booleanonKeyUp(int keyCode, android.view.KeyEvent event)

        if (keyCode == KeyEvent.KEYCODE_MENU) {
            mMenuIsDown = false;
        }
        return mKeyTracker.doKeyUp(keyCode, event) || super.onKeyUp(keyCode, event);
    
public voidonLowMemory()

        super.onLowMemory();
        mTabControl.freeMemory();
    
public voidonNetworkToggle(boolean up)
connectivity manager says net has come or gone... inform the user

param
up true if net has come up, false if net has gone down

        if (up == mIsNetworkUp) {
            return;
        } else if (up) {
            mIsNetworkUp = true;
            if (mAlertDialog != null) {
                mAlertDialog.cancel();
                mAlertDialog = null;
            }
        } else {
            mIsNetworkUp = false;
            if (mInLoad && mAlertDialog == null) {
                mAlertDialog = new AlertDialog.Builder(this)
                        .setTitle(R.string.loadSuspendedTitle)
                        .setMessage(R.string.loadSuspended)
                        .setPositiveButton(R.string.ok, null)
                        .show();
            }
        }
        WebView w = mTabControl.getCurrentWebView();
        if (w != null) {
            w.setNetworkAvailable(up);
        }
    
protected voidonNewIntent(android.content.Intent intent)

        TabControl.Tab current = mTabControl.getCurrentTab();
        // When a tab is closed on exit, the current tab index is set to -1.
        // Reset before proceed as Browser requires the current tab to be set.
        if (current == null) {
            // Try to reset the tab in case the index was incorrect.
            current = mTabControl.getTab(0);
            if (current == null) {
                // No tabs at all so just ignore this intent.
                return;
            }
            mTabControl.setCurrentTab(current);
            attachTabToContentView(current);
            resetTitleAndIcon(current.getWebView());
        }
        final String action = intent.getAction();
        final int flags = intent.getFlags();
        if (Intent.ACTION_MAIN.equals(action) ||
                (flags & Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY) != 0) {
            // just resume the browser
            return;
        }
        if (Intent.ACTION_VIEW.equals(action)
                || Intent.ACTION_SEARCH.equals(action)
                || MediaStore.INTENT_ACTION_MEDIA_SEARCH.equals(action)
                || Intent.ACTION_WEB_SEARCH.equals(action)) {
            String url = getUrlFromIntent(intent);
            if (url == null || url.length() == 0) {
                url = mSettings.getHomePage();
            }
            if (Intent.ACTION_VIEW.equals(action) &&
                    (flags & Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT) != 0) {
                final String appId =
                        intent.getStringExtra(Browser.EXTRA_APPLICATION_ID);
                final TabControl.Tab appTab = mTabControl.getTabFromId(appId);
                if (appTab != null) {
                    Log.i(LOGTAG, "Reusing tab for " + appId);
                    // Dismiss the subwindow if applicable.
                    dismissSubWindow(appTab);
                    // Since we might kill the WebView, remove it from the
                    // content view first.
                    removeTabFromContentView(appTab);
                    // Recreate the main WebView after destroying the old one.
                    // If the WebView has the same original url and is on that
                    // page, it can be reused.
                    boolean needsLoad =
                            mTabControl.recreateWebView(appTab, url);
                    if (current != appTab) {
                        showTab(appTab, needsLoad ? url : null);
                    } else {
                        if (mTabOverview != null && mAnimationCount == 0) {
                            sendAnimateFromOverview(appTab, false,
                                    needsLoad ? url : null, TAB_OVERVIEW_DELAY,
                                    null);
                        } else {
                            // If the tab was the current tab, we have to attach
                            // it to the view system again.
                            attachTabToContentView(appTab);
                            if (needsLoad) {
                                appTab.getWebView().loadUrl(url);
                            }
                        }
                    }
                    return;
                }
                // if FLAG_ACTIVITY_BROUGHT_TO_FRONT flag is on, the url will be
                // opened in a new tab unless we have reached MAX_TABS. Then the
                // url will be opened in the current tab. If a new tab is
                // created, it will have "true" for exit on close.
                openTabAndShow(url, null, true, appId);
            } else {
                if ("about:debug".equals(url)) {
                    mSettings.toggleDebugSettings();
                    return;
                }
                // If the Window overview is up and we are not in the midst of
                // an animation, animate away from the Window overview.
                if (mTabOverview != null && mAnimationCount == 0) {
                    sendAnimateFromOverview(current, false, url,
                            TAB_OVERVIEW_DELAY, null);
                } else {
                    // Get rid of the subwindow if it exists
                    dismissSubWindow(current);
                    current.getWebView().loadUrl(url);
                }
            }
        }
    
public booleanonOptionsItemSelected(android.view.MenuItem item)

        if (!mCanChord) {
            // The user has already fired a shortcut with this hold down of the
            // menu key.
            return false;
        }
        switch (item.getItemId()) {
            // -- Main menu
            case R.id.goto_menu_id: {
                String url = getTopWindow().getUrl();
                startSearch(mSettings.getHomePage().equals(url) ? null : url, true,
                        createGoogleSearchSourceBundle(GOOGLE_SEARCH_SOURCE_GOTO), false);
                }
                break;

            case R.id.bookmarks_menu_id:
                bookmarksOrHistoryPicker(false);
                break;

            case R.id.windows_menu_id:
                if (mTabControl.getTabCount() == 1) {
                    openTabAndShow(mSettings.getHomePage(), null, false, null);
                } else {
                    tabPicker(true, mTabControl.getCurrentIndex(), false);
                }
                break;

            case R.id.stop_reload_menu_id:
                if (mInLoad) {
                    stopLoading();
                } else {
                    getTopWindow().reload();
                }
                break;

            case R.id.back_menu_id:
                getTopWindow().goBack();
                break;

            case R.id.forward_menu_id:
                getTopWindow().goForward();
                break;

            case R.id.close_menu_id:
                // Close the subwindow if it exists.
                if (mTabControl.getCurrentSubWindow() != null) {
                    dismissSubWindow(mTabControl.getCurrentTab());
                    break;
                }
                final int currentIndex = mTabControl.getCurrentIndex();
                final TabControl.Tab parent =
                        mTabControl.getCurrentTab().getParentTab();
                int indexToShow = -1;
                if (parent != null) {
                    indexToShow = mTabControl.getTabIndex(parent);
                } else {
                    // Get the last tab in the list. If it is the current tab,
                    // subtract 1 more.
                    indexToShow = mTabControl.getTabCount() - 1;
                    if (currentIndex == indexToShow) {
                        indexToShow--;
                    }
                }
                switchTabs(currentIndex, indexToShow, true);
                break;

            case R.id.homepage_menu_id:
                TabControl.Tab current = mTabControl.getCurrentTab();
                if (current != null) {
                    dismissSubWindow(current);
                    current.getWebView().loadUrl(mSettings.getHomePage());
                }
                break;

            case R.id.preferences_menu_id:
                Intent intent = new Intent(this,
                        BrowserPreferencesPage.class);
                startActivityForResult(intent, PREFERENCES_PAGE);
                break;

            case R.id.find_menu_id:
                if (null == mFindDialog) {
                    mFindDialog = new FindDialog(this);
                }
                mFindDialog.setWebView(getTopWindow());
                mFindDialog.show();
                mMenuState = EMPTY_MENU;
                break;

            case R.id.select_text_id:
                getTopWindow().emulateShiftHeld();
                break;
            case R.id.page_info_menu_id:
                showPageInfo(mTabControl.getCurrentTab(), false);
                break;

            case R.id.classic_history_menu_id:
                bookmarksOrHistoryPicker(true);
                break;

            case R.id.share_page_menu_id:
                Browser.sendString(this, getTopWindow().getUrl());
                break;

            case R.id.dump_nav_menu_id:
                getTopWindow().debugDump();
                break;

            case R.id.zoom_in_menu_id:
                getTopWindow().zoomIn();
                break;

            case R.id.zoom_out_menu_id:
                getTopWindow().zoomOut();
                break;

            case R.id.view_downloads_menu_id:
                viewDownloads(null);
                break;

            // -- Tab menu
            case R.id.view_tab_menu_id:
                if (mTabListener != null && mTabOverview != null) {
                    int pos = mTabOverview.getContextMenuPosition(item);
                    mTabOverview.setCurrentIndex(pos);
                    mTabListener.onClick(pos);
                }
                break;

            case R.id.remove_tab_menu_id:
                if (mTabListener != null && mTabOverview != null) {
                    int pos = mTabOverview.getContextMenuPosition(item);
                    mTabListener.remove(pos);
                }
                break;

            case R.id.new_tab_menu_id:
                // No need to check for mTabOverview here since we are not
                // dependent on it for a position.
                if (mTabListener != null) {
                    // If the overview happens to be non-null, make the "New
                    // Tab" cell visible.
                    if (mTabOverview != null) {
                        mTabOverview.setCurrentIndex(ImageGrid.NEW_TAB);
                    }
                    mTabListener.onClick(ImageGrid.NEW_TAB);
                }
                break;

            case R.id.bookmark_tab_menu_id:
                if (mTabListener != null && mTabOverview != null) {
                    int pos = mTabOverview.getContextMenuPosition(item);
                    TabControl.Tab t = mTabControl.getTab(pos);
                    // Since we called populatePickerData for all of the
                    // tabs, getTitle and getUrl will return appropriate
                    // values.
                    Browser.saveBookmark(BrowserActivity.this, t.getTitle(),
                            t.getUrl());
                }
                break;

            case R.id.history_tab_menu_id:
                bookmarksOrHistoryPicker(true);
                break;

            case R.id.bookmarks_tab_menu_id:
                bookmarksOrHistoryPicker(false);
                break;

            case R.id.properties_tab_menu_id:
                if (mTabListener != null && mTabOverview != null) {
                    int pos = mTabOverview.getContextMenuPosition(item);
                    showPageInfo(mTabControl.getTab(pos), false);
                }
                break;

            case R.id.window_one_menu_id:
            case R.id.window_two_menu_id:
            case R.id.window_three_menu_id:
            case R.id.window_four_menu_id:
            case R.id.window_five_menu_id:
            case R.id.window_six_menu_id:
            case R.id.window_seven_menu_id:
            case R.id.window_eight_menu_id:
                {
                    int menuid = item.getItemId();
                    for (int id = 0; id < WINDOW_SHORTCUT_ID_ARRAY.length; id++) {
                        if (WINDOW_SHORTCUT_ID_ARRAY[id] == menuid) {
                            TabControl.Tab desiredTab = mTabControl.getTab(id);
                            if (desiredTab != null &&
                                    desiredTab != mTabControl.getCurrentTab()) {
                                switchTabs(mTabControl.getCurrentIndex(), id, false);
                            }
                            break;
                        }
                    }
                }
                break;

            default:
                if (!super.onOptionsItemSelected(item)) {
                    return false;
                }
                // Otherwise fall through.
        }
        mCanChord = false;
        return true;
    
protected voidonPause()

        super.onPause();

        if (mActivityInPause) {
            Log.e(LOGTAG, "BrowserActivity is already paused.");
            return;
        }

        mActivityInPause = true;
        if (mTabControl.getCurrentIndex() >= 0 && !pauseWebView()) {
            mWakeLock.acquire();
            mHandler.sendMessageDelayed(mHandler
                    .obtainMessage(RELEASE_WAKELOCK), WAKELOCK_TIMEOUT);
        }

        // Clear the credentials toast if it is up
        if (mCredsDlg != null && mCredsDlg.isShowing()) {
            mCredsDlg.dismiss();
        }
        mCredsDlg = null;

        cancelStopToast();

        // unregister network state listener
        unregisterReceiver(mNetworkStateIntentReceiver);
        WebView.disablePlatformNotifications();

        if (mSensorManager != null) {
            mSensorManager.unregisterListener(mSensorListener);
        }
    
public booleanonPrepareOptionsMenu(android.view.Menu menu)

        // This happens when the user begins to hold down the menu key, so
        // allow them to chord to get a shortcut.
        mCanChord = true;
        // Note: setVisible will decide whether an item is visible; while
        // setEnabled() will decide whether an item is enabled, which also means
        // whether the matching shortcut key will function.
        super.onPrepareOptionsMenu(menu);
        switch (mMenuState) {
            case R.id.TAB_MENU:
                if (mCurrentMenuState != mMenuState) {
                    menu.setGroupVisible(R.id.MAIN_MENU, false);
                    menu.setGroupEnabled(R.id.MAIN_MENU, false);
                    menu.setGroupEnabled(R.id.MAIN_SHORTCUT_MENU, false);
                    menu.setGroupVisible(R.id.TAB_MENU, true);
                    menu.setGroupEnabled(R.id.TAB_MENU, true);
                }
                boolean newT = mTabControl.getTabCount() < TabControl.MAX_TABS;
                final MenuItem tab = menu.findItem(R.id.new_tab_menu_id);
                tab.setVisible(newT);
                tab.setEnabled(newT);
                break;
            case EMPTY_MENU:
                if (mCurrentMenuState != mMenuState) {
                    menu.setGroupVisible(R.id.MAIN_MENU, false);
                    menu.setGroupEnabled(R.id.MAIN_MENU, false);
                    menu.setGroupEnabled(R.id.MAIN_SHORTCUT_MENU, false);
                    menu.setGroupVisible(R.id.TAB_MENU, false);
                    menu.setGroupEnabled(R.id.TAB_MENU, false);
                }
                break;
            default:
                if (mCurrentMenuState != mMenuState) {
                    menu.setGroupVisible(R.id.MAIN_MENU, true);
                    menu.setGroupEnabled(R.id.MAIN_MENU, true);
                    menu.setGroupEnabled(R.id.MAIN_SHORTCUT_MENU, true);
                    menu.setGroupVisible(R.id.TAB_MENU, false);
                    menu.setGroupEnabled(R.id.TAB_MENU, false);
                }
                final WebView w = getTopWindow();
                boolean canGoBack = false;
                boolean canGoForward = false;
                boolean isHome = false;
                if (w != null) {
                    canGoBack = w.canGoBack();
                    canGoForward = w.canGoForward();
                    isHome = mSettings.getHomePage().equals(w.getUrl());
                }
                final MenuItem back = menu.findItem(R.id.back_menu_id);
                back.setEnabled(canGoBack);

                final MenuItem home = menu.findItem(R.id.homepage_menu_id);
                home.setEnabled(!isHome);

                menu.findItem(R.id.forward_menu_id)
                        .setEnabled(canGoForward);

                // decide whether to show the share link option
                PackageManager pm = getPackageManager();
                Intent send = new Intent(Intent.ACTION_SEND);
                send.setType("text/plain");
                ResolveInfo ri = pm.resolveActivity(send, PackageManager.MATCH_DEFAULT_ONLY);
                menu.findItem(R.id.share_page_menu_id).setVisible(ri != null);

                // If there is only 1 window, the text will be "New window"
                final MenuItem windows = menu.findItem(R.id.windows_menu_id);
                windows.setTitleCondensed(mTabControl.getTabCount() > 1 ?
                        getString(R.string.view_tabs_condensed) :
                        getString(R.string.tab_picker_new_tab));

                boolean isNavDump = mSettings.isNavDump();
                final MenuItem nav = menu.findItem(R.id.dump_nav_menu_id);
                nav.setVisible(isNavDump);
                nav.setEnabled(isNavDump);
                break;
        }
        mCurrentMenuState = mMenuState;
        return true;
    
protected voidonResume()


        
        super.onResume();
        if (Config.LOGV) {
            Log.v(LOGTAG, "BrowserActivity.onResume: this=" + this);
        }

        if (!mActivityInPause) {
            Log.e(LOGTAG, "BrowserActivity is already resumed.");
            return;
        }

        mActivityInPause = false;
        resumeWebView();

        if (mWakeLock.isHeld()) {
            mHandler.removeMessages(RELEASE_WAKELOCK);
            mWakeLock.release();
        }

        if (mCredsDlg != null) {
            if (!mHandler.hasMessages(CANCEL_CREDS_REQUEST)) {
             // In case credential request never comes back
                mHandler.sendEmptyMessageDelayed(CANCEL_CREDS_REQUEST, 6000);
            }
        }

        registerReceiver(mNetworkStateIntentReceiver,
                         mNetworkStateChangedFilter);
        WebView.enablePlatformNotifications();

        if (mSettings.doFlick()) {
            if (mSensorManager == null) {
                mSensorManager = (SensorManager) getSystemService(
                        Context.SENSOR_SERVICE);
            }
            mSensorManager.registerListener(mSensorListener,
                    SensorManager.SENSOR_ACCELEROMETER,
                    SensorManager.SENSOR_DELAY_FASTEST);
        } else {
            mSensorManager = null;
        }
    
protected voidonSaveInstanceState(android.os.Bundle outState)
onSaveInstanceState(Bundle map) onSaveInstanceState is called right before onStop(). The map contains the saved state.

        if (Config.LOGV) {
            Log.v(LOGTAG, "BrowserActivity.onSaveInstanceState: this=" + this);
        }
        // the default implementation requires each view to have an id. As the
        // browser handles the state itself and it doesn't use id for the views,
        // don't call the default implementation. Otherwise it will trigger the
        // warning like this, "couldn't save which view has focus because the
        // focused view XXX has no id".

        // Save all the tabs
        mTabControl.saveState(outState);
    
public booleanonSearchRequested()
Overriding this to insert a local information bundle

        startSearch(null, false,
                createGoogleSearchSourceBundle(GOOGLE_SEARCH_SOURCE_SEARCHKEY), false);
        return true;
    
private voidopenTab(java.lang.String url)

        if (mSettings.openInBackground()) {
            TabControl.Tab t = mTabControl.createNewTab();
            if (t != null) {
                t.getWebView().loadUrl(url);
            }
        } else {
            openTabAndShow(url, null, false, null);
        }
    
private voidopenTabAndShow(java.lang.String url, android.os.Message msg, boolean closeOnExit, java.lang.String appId)

        final boolean newTab = mTabControl.getTabCount() != TabControl.MAX_TABS;
        final TabControl.Tab currentTab = mTabControl.getCurrentTab();
        if (newTab) {
            int delay = 0;
            // If the tab overview is up and there are animations, just load
            // the url.
            if (mTabOverview != null && mAnimationCount > 0) {
                if (url != null) {
                    // We should not have a msg here since onCreateWindow
                    // checks the animation count and every other caller passes
                    // null.
                    assert msg == null;
                    // just dismiss the subwindow and load the given url.
                    dismissSubWindow(currentTab);
                    currentTab.getWebView().loadUrl(url);
                }
            } else {
                // show mTabOverview if it is not there.
                if (mTabOverview == null) {
                    // We have to delay the animation from the tab picker by the
                    // length of the tab animation. Add a delay so the tab
                    // overview can be shown before the second animation begins.
                    delay = TAB_ANIMATION_DURATION + TAB_OVERVIEW_DELAY;
                    tabPicker(false, ImageGrid.NEW_TAB, false);
                }
                // Animate from the Tab overview after any animations have
                // finished.
                sendAnimateFromOverview(
                        mTabControl.createNewTab(closeOnExit, appId, url), true,
                        url, delay, msg);
            }
        } else if (url != null) {
            // We should not have a msg here.
            assert msg == null;
            if (mTabOverview != null && mAnimationCount == 0) {
                sendAnimateFromOverview(currentTab, false, url,
                        TAB_OVERVIEW_DELAY, null);
            } else {
                // Get rid of the subwindow if it exists
                dismissSubWindow(currentTab);
                // Load the given url.
                currentTab.getWebView().loadUrl(url);
            }
        }
    
private booleanpauseWebView()

        if (mActivityInPause && !mPageStarted) {
            CookieSyncManager.getInstance().stopSync();
            WebView w = mTabControl.getCurrentWebView();
            if (w != null) {
                w.pauseTimers();
            }
            return true;
        } else {
            return false;
        }
    
public voidpostMessage(int what, int arg1, int arg2, java.lang.Object obj)

        mHandler.sendMessage(mHandler.obtainMessage(what, arg1, arg2, obj));
    
private java.lang.StringreformatCertificateDate(java.lang.String certificateDate)
Re-formats the certificate date (Date.toString()) string to a properly localized date string.

return
Properly localized version of the certificate date string and the original certificate date string if fails to localize. If the original string is null, returns an empty string "".

      String reformattedDate = null;

      if (certificateDate != null) {
          Date date = null;
          try {
              date = java.text.DateFormat.getInstance().parse(certificateDate);
          } catch (ParseException e) {
              date = null;
          }

          if (date != null) {
              reformattedDate =
                  DateFormat.getDateFormat(this).format(date);
          }
      }

      return reformattedDate != null ? reformattedDate :
          (certificateDate != null ? certificateDate : "");
    
private voidremoveTabFromContentView(TabControl.Tab t)

        // Remove the main WebView.
        mContentView.removeView(t.getWebView());
        // Remove the sub window if it exists.
        if (t.getSubWebView() != null) {
            mContentView.removeView(t.getSubWebViewContainer());
        }
    
private voidresetLockIcon(java.lang.String url)
Resets the lock icon. This method is called when we start a new load and know the url to be loaded.

        // Save the lock-icon state (we revert to it if the load gets cancelled)
        saveLockIcon();

        mLockIconType = LOCK_ICON_UNSECURE;
        if (URLUtil.isHttpsUrl(url)) {
            mLockIconType = LOCK_ICON_SECURE;
            if (Config.LOGV) {
                Log.v(LOGTAG, "BrowserActivity.resetLockIcon:" +
                      " reset lock icon to " + mLockIconType);
            }
        }

        updateLockIconImage(LOCK_ICON_UNSECURE);
    
private voidresetLockIcon()
Resets the lock icon. This method is called when the icon needs to be reset but we do not know whether we are loading a secure or not secure page.

        // Save the lock-icon state (we revert to it if the load gets cancelled)
        saveLockIcon();

        mLockIconType = LOCK_ICON_UNSECURE;

        if (Config.LOGV) {
          Log.v(LOGTAG, "BrowserActivity.resetLockIcon:" +
                " reset lock icon to " + mLockIconType);
        }

        updateLockIconImage(LOCK_ICON_UNSECURE);
    
private voidresetTitle()
Resets the browser title-view to whatever it must be (for example, if we load a page from history).

        resetLockIcon();
        resetTitleIconAndProgress();
    
private voidresetTitleAndIcon(android.webkit.WebView view)

        WebHistoryItem item = view.copyBackForwardList().getCurrentItem();
        if (item != null) {
            setUrlTitle(item.getUrl(), item.getTitle());
            setFavicon(item.getFavicon());
        } else {
            setUrlTitle(null, null);
            setFavicon(null);
        }
    
voidresetTitleAndRevertLockIcon()
Resets the browser title-view to whatever it must be (for example, if we had a loading error) When we have a new page, we call resetTitle, when we have to reset the titlebar to whatever it used to be (for example, if the user chose to stop loading), we call resetTitleAndRevertLockIcon.

        revertLockIcon();
        resetTitleIconAndProgress();
    
private voidresetTitleIconAndProgress()
Reset the title, favicon, and progress.

        WebView current = mTabControl.getCurrentWebView();
        if (current == null) {
            return;
        }
        resetTitleAndIcon(current);
        int progress = current.getProgress();
        mWebChromeClient.onProgressChanged(current, progress);
    
private voidresumeAfterCredentials()

        if (mCredsDlg == null) {
            return;
        }

        // Clear the toast
        if (mCredsDlg.isShowing()) {
            mCredsDlg.dismiss();
        }
        mCredsDlg = null;

        // Clear any pending timeout
        mHandler.removeMessages(CANCEL_CREDS_REQUEST);

        // Load the page
        WebView w = mTabControl.getCurrentWebView();
        if (w != null) {
            w.loadUrl(mSettings.getHomePage());
        }

        // Update the settings, need to do this last as it can take a moment
        // to persist the settings. In the mean time we could be loading
        // content.
        mSettings.setLoginInitialized(this);
    
private booleanresumeWebView()

        if ((!mActivityInPause && !mPageStarted) ||
                (mActivityInPause && mPageStarted)) {
            CookieSyncManager.getInstance().startSync();
            WebView w = mTabControl.getCurrentWebView();
            if (w != null) {
                w.resumeTimers();
            }
            return true;
        } else {
            return false;
        }
    
private voidretainIconsOnStartup()

        final WebIconDatabase db = WebIconDatabase.getInstance();
        db.open(getDir("icons", 0).getPath());
        try {
            Cursor c = Browser.getAllBookmarks(mResolver);
            if (!c.moveToFirst()) {
                c.deactivate();
                return;
            }
            int urlIndex = c.getColumnIndex(Browser.BookmarkColumns.URL);
            do {
                String url = c.getString(urlIndex);
                db.retainIconForPageUrl(url);
            } while (c.moveToNext());
            c.deactivate();
        } catch (IllegalStateException e) {
            Log.e(LOGTAG, "retainIconsOnStartup", e);
        }
    
private voidrevertLockIcon()
Reverts the lock-icon state to the last saved state, for example, if we had an error, and need to cancel the load.

        mLockIconType = mPrevLockType;

        if (Config.LOGV) {
            Log.v(LOGTAG, "BrowserActivity.revertLockIcon:" +
                  " revert lock icon to " + mLockIconType);
        }

        updateLockIconImage(mLockIconType);
    
private voidsaveLockIcon()
Saves the current lock-icon state before resetting the lock icon. If we have an error, we may need to roll back to the previous state.

        mPrevLockType = mLockIconType;
    
private voidsendAnimateFromOverview(TabControl.Tab tab, boolean newTab, java.lang.String url, int delay, android.os.Message msg)

        // Set the current tab.
        mTabControl.setCurrentTab(tab);
        // Attach the WebView so it will layout.
        attachTabToContentView(tab);
        // Set the view to invisibile for now.
        tab.getWebView().setVisibility(View.INVISIBLE);
        // If there is a sub window, make it invisible too.
        if (tab.getSubWebView() != null) {
            tab.getSubWebViewContainer().setVisibility(View.INVISIBLE);
        }
        // Create our fake animating view.
        final AnimatingView view = new AnimatingView(this, tab);
        // Attach it to the view system and make in invisible so it will
        // layout but not flash white on the screen.
        mContentView.addView(view, COVER_SCREEN_PARAMS);
        view.setVisibility(View.INVISIBLE);
        // Send the animate message.
        final HashMap map = new HashMap();
        map.put("view", view);
        // Load the url after the AnimatingView has captured the picture. This
        // prevents any bad layout or bad scale from being used during
        // animation.
        if (url != null) {
            dismissSubWindow(tab);
            tab.getWebView().loadUrl(url);
        }
        map.put("msg", msg);
        mHandler.sendMessageDelayed(mHandler.obtainMessage(
                ANIMATE_FROM_OVERVIEW, newTab ? 1 : 0, 0, map), delay);
        // Increment the count to indicate that we are in an animation.
        mAnimationCount++;
        // Remove the listener so we don't get any more tab changes.
        mTabOverview.setListener(null);
        mTabListener = null;
        // Make the menu empty until the animation completes.
        mMenuState = EMPTY_MENU;

    
voidsetBaseSearchUrl(java.lang.String url)

        if (url == null || url.length() == 0) {
            /*
             * get the google search url based on the SIM. Default is US. NOTE:
             * This code uses resources to optionally select the search Uri,
             * based on the MCC value from the SIM. The default string will most
             * likely be fine. It is parameterized to accept info from the
             * Locale, the language code is the first parameter (%1$s) and the
             * country code is the second (%2$s). This code must function in the
             * same way as a similar lookup in
             * com.android.googlesearch.SuggestionProvider#onCreate(). If you
             * change either of these functions, change them both. (The same is
             * true for the underlying resource strings, which are stored in
             * mcc-specific xml files.)
             */
            Locale l = Locale.getDefault();
            QuickSearch_G = getResources().getString(
                    R.string.google_search_base, l.getLanguage(),
                    l.getCountry().toLowerCase())
                    + "client=ms-"
                    + Partner.getString(this.getContentResolver(), Partner.CLIENT_ID)
                    + "&source=android-" + GOOGLE_SEARCH_SOURCE_SUGGEST + "&q=%s";
        } else {
            QuickSearch_G = url;
        }
    
private voidsetFavicon(android.graphics.Bitmap icon)

        // While the tab overview is animating or being shown, block changes to
        // the favicon.
        if (mAnimationCount > 0 || mTabOverview != null) {
            return;
        }
        Drawable[] array = new Drawable[2];
        PaintDrawable p = new PaintDrawable(Color.WHITE);
        p.setCornerRadius(3f);
        array[0] = p;
        if (icon == null) {
            array[1] = mGenericFavicon;
        } else {
            array[1] = new BitmapDrawable(icon);
        }
        LayerDrawable d = new LayerDrawable(array);
        d.setLayerInset(1, 2, 2, 2, 2);
        getWindow().setFeatureDrawable(Window.FEATURE_LEFT_ICON, d);
    
public voidsetHttpAuthUsernamePassword(java.lang.String host, java.lang.String realm, java.lang.String username, java.lang.String password)
Set HTTP authentication password.

param
host The host for the password
param
realm The realm for the password
param
username The username for the password. If it is null, it means password can't be saved.
param
password The password

        WebView w = mTabControl.getCurrentWebView();
        if (w != null) {
            w.setHttpAuthUsernamePassword(host, realm, username, password);
        }
    
private voidsetUrlTitle(java.lang.String url, java.lang.String title)
Sets a title composed of the URL and the title string.

param
url The URL of the site being loaded.
param
title The title of the site being loaded.

        mUrl = url;
        mTitle = title;

        // While the tab overview is animating or being shown, block changes
        // to the title.
        if (mAnimationCount == 0 && mTabOverview == null) {
            setTitle(buildUrlTitle(url, title));
        }
    
private voidsetupHomePage()


    /* Whitelisted webpages
    private static HashSet<String> sWhiteList;

    static {
        sWhiteList = new HashSet<String>();
        sWhiteList.add("cnn.com/");
        sWhiteList.add("espn.go.com/");
        sWhiteList.add("nytimes.com/");
        sWhiteList.add("engadget.com/");
        sWhiteList.add("yahoo.com/");
        sWhiteList.add("msn.com/");
        sWhiteList.add("amazon.com/");
        sWhiteList.add("consumerist.com/");
        sWhiteList.add("google.com/m/news");
    }
    */

       
        final Runnable getAccount = new Runnable() {
            public void run() {
                // Lower priority
                Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
                // get the default home page
                String homepage = mSettings.getHomePage();

                try {
                    if (mGls == null) return;

                    String hostedUser = mGls.getAccount(GoogleLoginServiceConstants.PREFER_HOSTED);
                    String googleUser = mGls.getAccount(GoogleLoginServiceConstants.REQUIRE_GOOGLE);

                    // three cases:
                    //
                    //   hostedUser == googleUser
                    //      The device has only a google account
                    //
                    //   hostedUser != googleUser
                    //      The device has a hosted account and a google account
                    //
                    //   hostedUser != null, googleUser == null
                    //      The device has only a hosted account (so far)

                    // developers might have no accounts at all
                    if (hostedUser == null) return;

                    if (googleUser == null || !hostedUser.equals(googleUser)) {
                        String domain = hostedUser.substring(hostedUser.lastIndexOf('@")+1);
                        homepage = "http://www.google.com/m/a/" + domain + "?client=ms-" +
                            Partner.getString(BrowserActivity.this.getContentResolver(), Partner.CLIENT_ID);
                    }
                } catch (RemoteException ignore) {
                    // Login service died; carry on
                } catch (RuntimeException ignore) {
                    // Login service died; carry on
                } finally {
                    finish(homepage);
                }
            }

            private void finish(final String homepage) {
                mHandler.post(new Runnable() {
                    public void run() {
                        mSettings.setHomePage(BrowserActivity.this, homepage);
                        resumeAfterCredentials();

                        // as this is running in a separate thread,
                        // BrowserActivity's onDestroy() may have been called,
                        // which also calls unbindService().
                        if (mGlsConnection != null) {
                            // we no longer need to keep GLS open
                            unbindService(mGlsConnection);
                            mGlsConnection = null;
                        }
                    } });
            } };

        final boolean[] done = { false };

        // Open a connection to the Google Login Service.  The first
        // time the connection is established, set up the homepage depending on
        // the account in a background thread.
        mGlsConnection = new ServiceConnection() {
            public void onServiceConnected(ComponentName className, IBinder service) {
                mGls = IGoogleLoginService.Stub.asInterface(service);
                if (done[0] == false) {
                    done[0] = true;
                    Thread account = new Thread(getAccount);
                    account.setName("GLSAccount");
                    account.start();
                }
            }
            public void onServiceDisconnected(ComponentName className) {
                mGls = null;
            }
        };

        bindService(GoogleLoginServiceConstants.SERVICE_INTENT,
                    mGlsConnection, Context.BIND_AUTO_CREATE);
    
private voidshowHttpAuthentication(android.webkit.HttpAuthHandler handler, java.lang.String host, java.lang.String realm, java.lang.String title, java.lang.String name, java.lang.String password, int focusId)
Displays an http-authentication dialog.

        LayoutInflater factory = LayoutInflater.from(this);
        final View v = factory
                .inflate(R.layout.http_authentication, null);
        if (name != null) {
            ((EditText) v.findViewById(R.id.username_edit)).setText(name);
        }
        if (password != null) {
            ((EditText) v.findViewById(R.id.password_edit)).setText(password);
        }

        String titleText = title;
        if (titleText == null) {
            titleText = getText(R.string.sign_in_to).toString().replace(
                    "%s1", host).replace("%s2", realm);
        }

        mHttpAuthHandler = handler;
        AlertDialog dialog = new AlertDialog.Builder(this)
                .setTitle(titleText)
                .setIcon(android.R.drawable.ic_dialog_alert)
                .setView(v)
                .setPositiveButton(R.string.action,
                        new DialogInterface.OnClickListener() {
                             public void onClick(DialogInterface dialog,
                                     int whichButton) {
                                String nm = ((EditText) v
                                        .findViewById(R.id.username_edit))
                                        .getText().toString();
                                String pw = ((EditText) v
                                        .findViewById(R.id.password_edit))
                                        .getText().toString();
                                BrowserActivity.this.setHttpAuthUsernamePassword
                                        (host, realm, nm, pw);
                                handler.proceed(nm, pw);
                                mHttpAuthenticationDialog = null;
                                mHttpAuthHandler = null;
                            }})
                .setNegativeButton(R.string.cancel,
                        new DialogInterface.OnClickListener() {
                            public void onClick(DialogInterface dialog,
                                    int whichButton) {
                                handler.cancel();
                                BrowserActivity.this.resetTitleAndRevertLockIcon();
                                mHttpAuthenticationDialog = null;
                                mHttpAuthHandler = null;
                            }})
                .setOnCancelListener(new DialogInterface.OnCancelListener() {
                        public void onCancel(DialogInterface dialog) {
                            handler.cancel();
                            BrowserActivity.this.resetTitleAndRevertLockIcon();
                            mHttpAuthenticationDialog = null;
                            mHttpAuthHandler = null;
                        }})
                .create();
        // Make the IME appear when the dialog is displayed if applicable.
        dialog.getWindow().setSoftInputMode(
                WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);
        dialog.show();
        if (focusId != 0) {
            dialog.findViewById(focusId).requestFocus();
        } else {
            v.findViewById(R.id.username_edit).requestFocus();
        }
        mHttpAuthenticationDialog = dialog;
    
private voidshowPageInfo(TabControl.Tab tab, boolean fromShowSSLCertificateOnError)
Displays a page-info dialog.

param
tab The tab to show info about
param
fromShowSSLCertificateOnError The flag that indicates whether this dialog was opened from the SSL-certificate-on-error dialog or not. This is important, since we need to know whether to return to the parent dialog or simply dismiss.

        final LayoutInflater factory = LayoutInflater
                .from(this);

        final View pageInfoView = factory.inflate(R.layout.page_info, null);

        final WebView view = tab.getWebView();

        String url = null;
        String title = null;

        if (view == null) {
            url = tab.getUrl();
            title = tab.getTitle();
        } else if (view == mTabControl.getCurrentWebView()) {
             // Use the cached title and url if this is the current WebView
            url = mUrl;
            title = mTitle;
        } else {
            url = view.getUrl();
            title = view.getTitle();
        }

        if (url == null) {
            url = "";
        }
        if (title == null) {
            title = "";
        }

        ((TextView) pageInfoView.findViewById(R.id.address)).setText(url);
        ((TextView) pageInfoView.findViewById(R.id.title)).setText(title);

        mPageInfoView = tab;
        mPageInfoFromShowSSLCertificateOnError = new Boolean(fromShowSSLCertificateOnError);

        AlertDialog.Builder alertDialogBuilder =
            new AlertDialog.Builder(this)
            .setTitle(R.string.page_info).setIcon(android.R.drawable.ic_dialog_info)
            .setView(pageInfoView)
            .setPositiveButton(
                R.string.ok,
                new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog,
                                        int whichButton) {
                        mPageInfoDialog = null;
                        mPageInfoView = null;
                        mPageInfoFromShowSSLCertificateOnError = null;

                        // if we came here from the SSL error dialog
                        if (fromShowSSLCertificateOnError) {
                            // go back to the SSL error dialog
                            showSSLCertificateOnError(
                                mSSLCertificateOnErrorView,
                                mSSLCertificateOnErrorHandler,
                                mSSLCertificateOnErrorError);
                        }
                    }
                })
            .setOnCancelListener(
                new DialogInterface.OnCancelListener() {
                    public void onCancel(DialogInterface dialog) {
                        mPageInfoDialog = null;
                        mPageInfoView = null;
                        mPageInfoFromShowSSLCertificateOnError = null;

                        // if we came here from the SSL error dialog
                        if (fromShowSSLCertificateOnError) {
                            // go back to the SSL error dialog
                            showSSLCertificateOnError(
                                mSSLCertificateOnErrorView,
                                mSSLCertificateOnErrorHandler,
                                mSSLCertificateOnErrorError);
                        }
                    }
                });

        // if we have a main top-level page SSL certificate set or a certificate
        // error
        if (fromShowSSLCertificateOnError ||
                (view != null && view.getCertificate() != null)) {
            // add a 'View Certificate' button
            alertDialogBuilder.setNeutralButton(
                R.string.view_certificate,
                new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog,
                                        int whichButton) {
                        mPageInfoDialog = null;
                        mPageInfoView = null;
                        mPageInfoFromShowSSLCertificateOnError = null;

                        // if we came here from the SSL error dialog
                        if (fromShowSSLCertificateOnError) {
                            // go back to the SSL error dialog
                            showSSLCertificateOnError(
                                mSSLCertificateOnErrorView,
                                mSSLCertificateOnErrorHandler,
                                mSSLCertificateOnErrorError);
                        } else {
                            // otherwise, display the top-most certificate from
                            // the chain
                            if (view.getCertificate() != null) {
                                showSSLCertificate(tab);
                            }
                        }
                    }
                });
        }

        mPageInfoDialog = alertDialogBuilder.show();
    
private voidshowSSLCertificate(TabControl.Tab tab)
Displays the main top-level page SSL certificate dialog (accessible from the Page-Info dialog).

param
tab The tab to show certificate for.

        final View certificateView =
                inflateCertificateView(tab.getWebView().getCertificate());
        if (certificateView == null) {
            return;
        }

        LayoutInflater factory = LayoutInflater.from(this);

        final LinearLayout placeholder =
                (LinearLayout)certificateView.findViewById(R.id.placeholder);

        LinearLayout ll = (LinearLayout) factory.inflate(
            R.layout.ssl_success, placeholder);
        ((TextView)ll.findViewById(R.id.success))
            .setText(R.string.ssl_certificate_is_valid);

        mSSLCertificateView = tab;
        mSSLCertificateDialog =
            new AlertDialog.Builder(this)
                .setTitle(R.string.ssl_certificate).setIcon(
                    R.drawable.ic_dialog_browser_certificate_secure)
                .setView(certificateView)
                .setPositiveButton(R.string.ok,
                        new DialogInterface.OnClickListener() {
                            public void onClick(DialogInterface dialog,
                                    int whichButton) {
                                mSSLCertificateDialog = null;
                                mSSLCertificateView = null;

                                showPageInfo(tab, false);
                            }
                        })
                .setOnCancelListener(
                        new DialogInterface.OnCancelListener() {
                            public void onCancel(DialogInterface dialog) {
                                mSSLCertificateDialog = null;
                                mSSLCertificateView = null;

                                showPageInfo(tab, false);
                            }
                        })
                .show();
    
private voidshowSSLCertificateOnError(android.webkit.WebView view, android.webkit.SslErrorHandler handler, android.net.http.SslError error)
Displays the SSL error certificate dialog.

param
view The target web-view.
param
handler The SSL error handler responsible for cancelling the connection that resulted in an SSL error or proceeding per user request.
param
error The SSL error object.


        final View certificateView =
            inflateCertificateView(error.getCertificate());
        if (certificateView == null) {
            return;
        }

        LayoutInflater factory = LayoutInflater.from(this);

        final LinearLayout placeholder =
                (LinearLayout)certificateView.findViewById(R.id.placeholder);

        if (error.hasError(SslError.SSL_UNTRUSTED)) {
            LinearLayout ll = (LinearLayout)factory
                .inflate(R.layout.ssl_warning, placeholder);
            ((TextView)ll.findViewById(R.id.warning))
                .setText(R.string.ssl_untrusted);
        }

        if (error.hasError(SslError.SSL_IDMISMATCH)) {
            LinearLayout ll = (LinearLayout)factory
                .inflate(R.layout.ssl_warning, placeholder);
            ((TextView)ll.findViewById(R.id.warning))
                .setText(R.string.ssl_mismatch);
        }

        if (error.hasError(SslError.SSL_EXPIRED)) {
            LinearLayout ll = (LinearLayout)factory
                .inflate(R.layout.ssl_warning, placeholder);
            ((TextView)ll.findViewById(R.id.warning))
                .setText(R.string.ssl_expired);
        }

        if (error.hasError(SslError.SSL_NOTYETVALID)) {
            LinearLayout ll = (LinearLayout)factory
                .inflate(R.layout.ssl_warning, placeholder);
            ((TextView)ll.findViewById(R.id.warning))
                .setText(R.string.ssl_not_yet_valid);
        }

        mSSLCertificateOnErrorHandler = handler;
        mSSLCertificateOnErrorView = view;
        mSSLCertificateOnErrorError = error;
        mSSLCertificateOnErrorDialog =
            new AlertDialog.Builder(this)
                .setTitle(R.string.ssl_certificate).setIcon(
                    R.drawable.ic_dialog_browser_certificate_partially_secure)
                .setView(certificateView)
                .setPositiveButton(R.string.ok,
                        new DialogInterface.OnClickListener() {
                            public void onClick(DialogInterface dialog,
                                    int whichButton) {
                                mSSLCertificateOnErrorDialog = null;
                                mSSLCertificateOnErrorView = null;
                                mSSLCertificateOnErrorHandler = null;
                                mSSLCertificateOnErrorError = null;

                                mWebViewClient.onReceivedSslError(
                                    view, handler, error);
                            }
                        })
                 .setNeutralButton(R.string.page_info_view,
                        new DialogInterface.OnClickListener() {
                            public void onClick(DialogInterface dialog,
                                    int whichButton) {
                                mSSLCertificateOnErrorDialog = null;

                                // do not clear the dialog state: we will
                                // need to show the dialog again once the
                                // user is done exploring the page-info details

                                showPageInfo(mTabControl.getTabFromView(view),
                                        true);
                            }
                        })
                .setOnCancelListener(
                        new DialogInterface.OnCancelListener() {
                            public void onCancel(DialogInterface dialog) {
                                mSSLCertificateOnErrorDialog = null;
                                mSSLCertificateOnErrorView = null;
                                mSSLCertificateOnErrorHandler = null;
                                mSSLCertificateOnErrorError = null;

                                mWebViewClient.onReceivedSslError(
                                    view, handler, error);
                            }
                        })
                .show();
    
voidshowTab(TabControl.Tab t)


    // Called by TabControl when a tab is requesting focus
    /* package */    
        showTab(t, null);
    
private voidshowTab(TabControl.Tab t, java.lang.String url)

        // Disallow focus change during a tab animation.
        if (mAnimationCount > 0) {
            return;
        }
        int delay = 0;
        if (mTabOverview == null) {
            // Add a delay so the tab overview can be shown before the second
            // animation begins.
            delay = TAB_ANIMATION_DURATION + TAB_OVERVIEW_DELAY;
            tabPicker(false, mTabControl.getTabIndex(t), false);
        }
        sendAnimateFromOverview(t, false, url, delay, null);
    
private java.lang.StringsmartUrlFilter(android.net.Uri inUri)

        if (inUri != null) {
            return smartUrlFilter(inUri.toString());
        }
        return null;
    
java.lang.StringsmartUrlFilter(java.lang.String url)
Attempts to determine whether user input is a URL or search terms. Anything with a space is passed to search. Converts to lowercase any mistakenly uppercased schema (i.e., "Http://" converts to "http://"

return
Original or modified URL


                                               
       

        String inUrl = url.trim();
        boolean hasSpace = inUrl.indexOf(' ") != -1;

        Matcher matcher = ACCEPTED_URI_SCHEMA.matcher(inUrl);
        if (matcher.matches()) {
            if (hasSpace) {
                inUrl = inUrl.replace(" ", "%20");
            }
            // force scheme to lowercase
            String scheme = matcher.group(1);
            String lcScheme = scheme.toLowerCase();
            if (!lcScheme.equals(scheme)) {
                return lcScheme + matcher.group(2);
            }
            return inUrl;
        }
        if (hasSpace) {
            // FIXME: quick search, need to be customized by setting
            if (inUrl.length() > 2 && inUrl.charAt(1) == ' ") {
                // FIXME: Is this the correct place to add to searches?
                // what if someone else calls this function?
                char char0 = inUrl.charAt(0);

                if (char0 == 'g") {
                    Browser.addSearchUrl(mResolver, inUrl);
                    return composeSearchUrl(inUrl.substring(2));

                } else if (char0 == 'w") {
                    Browser.addSearchUrl(mResolver, inUrl);
                    return URLUtil.composeSearchUrl(inUrl.substring(2),
                            QuickSearch_W,
                            QUERY_PLACE_HOLDER);

                } else if (char0 == 'd") {
                    Browser.addSearchUrl(mResolver, inUrl);
                    return URLUtil.composeSearchUrl(inUrl.substring(2),
                            QuickSearch_D,
                            QUERY_PLACE_HOLDER);

                } else if (char0 == 'l") {
                    Browser.addSearchUrl(mResolver, inUrl);
                    // FIXME: we need location in this case
                    return URLUtil.composeSearchUrl(inUrl.substring(2),
                            QuickSearch_L,
                            QUERY_PLACE_HOLDER);
                }
            }
        } else {
            if (Regex.WEB_URL_PATTERN.matcher(inUrl).matches()) {
                return URLUtil.guessUrl(inUrl);
            }
        }

        Browser.addSearchUrl(mResolver, inUrl);
        return composeSearchUrl(inUrl);
    
public voidstartSearch(java.lang.String initialQuery, boolean selectInitialQuery, android.os.Bundle appSearchData, boolean globalSearch)

        if (appSearchData == null) {
            appSearchData = createGoogleSearchSourceBundle(GOOGLE_SEARCH_SOURCE_TYPE);
        }
        super.startSearch(initialQuery, selectInitialQuery, appSearchData, globalSearch);
    
private voidstopLoading()

        resetTitleAndRevertLockIcon();
        WebView w = getTopWindow();
        w.stopLoading();
        mWebViewClient.onPageFinished(w, w.getUrl());

        cancelStopToast();
        mStopToast = Toast
                .makeText(this, R.string.stopping, Toast.LENGTH_SHORT);
        mStopToast.show();
    
private voidswitchTabs(int indexFrom, int indexToShow, boolean remove)

        int delay = TAB_ANIMATION_DURATION + TAB_OVERVIEW_DELAY;
        // Animate to the tab picker, remove the current tab, then
        // animate away from the tab picker to the parent WebView.
        tabPicker(false, indexFrom, remove);
        // Change to the parent tab
        final TabControl.Tab tab = mTabControl.getTab(indexToShow);
        if (tab != null) {
            sendAnimateFromOverview(tab, false, null, delay, null);
        } else {
            // Increment this here so that no other animations can happen in
            // between the end of the tab picker transition and the beginning
            // of openTabAndShow. This has a matching decrement in the handler
            // of OPEN_TAB_AND_SHOW.
            mAnimationCount++;
            // Send a message to open a new tab.
            mHandler.sendMessageDelayed(
                    mHandler.obtainMessage(OPEN_TAB_AND_SHOW,
                        mSettings.getHomePage()), delay);
        }
    
private voidtabPicker(boolean stay, int index, boolean remove)
Open the tab picker. This function will always use the current tab in its animation.

param
stay boolean stating whether the tab picker is to remain open (in which case it needs a listener and its menu) or not.
param
index The index of the tab to show as the selection in the tab overview.
param
remove If true, the tab at index will be removed after the animation completes.

        if (mTabOverview != null) {
            return;
        }

        int size = mTabControl.getTabCount();

        TabListener l = null;
        if (stay) {
            l = mTabListener = new TabListener();
        }
        mTabOverview = new ImageGrid(this, stay, l);

        for (int i = 0; i < size; i++) {
            final TabControl.Tab t = mTabControl.getTab(i);
            mTabControl.populatePickerData(t);
            mTabOverview.add(t);
        }

        // Tell the tab overview to show the current tab, the tab overview will
        // handle the "New Tab" case.
        int currentIndex = mTabControl.getCurrentIndex();
        mTabOverview.setCurrentIndex(currentIndex);

        // Attach the tab overview.
        mContentView.addView(mTabOverview, COVER_SCREEN_PARAMS);

        // Create a fake AnimatingView to animate the WebView's picture.
        final TabControl.Tab current = mTabControl.getCurrentTab();
        final AnimatingView v = new AnimatingView(this, current);
        mContentView.addView(v, COVER_SCREEN_PARAMS);
        removeTabFromContentView(current);
        // Pause timers to get the animation smoother.
        current.getWebView().pauseTimers();

        // Send a message so the tab picker has a chance to layout and get
        // positions for all the cells.
        mHandler.sendMessage(mHandler.obtainMessage(ANIMATE_TO_OVERVIEW,
                index, remove ? 1 : 0, v));
        // Setting this will indicate that we are animating to the overview. We
        // set it here to prevent another request to animate from coming in
        // between now and when ANIMATE_TO_OVERVIEW is handled.
        mAnimationCount++;
        // Always change the title bar to the window overview title while
        // animating.
        getWindow().setFeatureDrawable(Window.FEATURE_LEFT_ICON, null);
        getWindow().setFeatureDrawable(Window.FEATURE_RIGHT_ICON, null);
        getWindow().setFeatureInt(Window.FEATURE_PROGRESS,
                Window.PROGRESS_VISIBILITY_OFF);
        setTitle(R.string.tab_picker_title);
        // Make the menu empty until the animation completes.
        mMenuState = EMPTY_MENU;
    
private voidupdateIcon(java.lang.String url, android.graphics.Bitmap icon)

        if (icon != null) {
            BrowserBookmarksAdapter.updateBookmarkFavicon(mResolver,
                    url, icon);
        }
        setFavicon(icon);
    
private voidupdateInLoadMenuItems()
As the menu can be open when loading state changes we must manually update the state of the stop/reload menu item

        if (mMenu == null) {
            return;
        }
        MenuItem src = mInLoad ?
                mMenu.findItem(R.id.stop_menu_id):
                    mMenu.findItem(R.id.reload_menu_id);
        MenuItem dest = mMenu.findItem(R.id.stop_reload_menu_id);
        dest.setIcon(src.getIcon());
        dest.setTitle(src.getTitle());
    
private voidupdateLockIconImage(int lockIconType)
Updates the lock-icon image in the title-bar.

        Drawable d = null;
        if (lockIconType == LOCK_ICON_SECURE) {
            d = mSecLockIcon;
        } else if (lockIconType == LOCK_ICON_MIXED) {
            d = mMixLockIcon;
        }
        // If the tab overview is animating or being shown, do not update the
        // lock icon.
        if (mAnimationCount == 0 && mTabOverview == null) {
            getWindow().setFeatureDrawable(Window.FEATURE_RIGHT_ICON, d);
        }
    
voidviewDownloads(android.net.Uri downloadRecord)

        Intent intent = new Intent(this,
                BrowserDownloadPage.class);
        intent.setData(downloadRecord);
        startActivityForResult(intent, this.DOWNLOAD_PAGE);

    
private voidwaitForCredentials()

        // Show a toast
        mCredsDlg = new ProgressDialog(this);
        mCredsDlg.setIndeterminate(true);
        mCredsDlg.setMessage(getText(R.string.retrieving_creds_dlg_msg));
        // If the user cancels the operation, then cancel the Google
        // Credentials request.
        mCredsDlg.setCancelMessage(mHandler.obtainMessage(CANCEL_CREDS_REQUEST));
        mCredsDlg.show();

        // We set a timeout for the retrieval of credentials in onResume()
        // as that is when we have freed up some CPU time to get
        // the login credentials.