Controller.java revision e1dbb956d762c3f07033f247c05270a9882a79a7
18233facddcc51865d612a919d450db6954aa48e3Michael Kolb/*
28233facddcc51865d612a919d450db6954aa48e3Michael Kolb * Copyright (C) 2010 The Android Open Source Project
38233facddcc51865d612a919d450db6954aa48e3Michael Kolb *
48233facddcc51865d612a919d450db6954aa48e3Michael Kolb * Licensed under the Apache License, Version 2.0 (the "License");
58233facddcc51865d612a919d450db6954aa48e3Michael Kolb * you may not use this file except in compliance with the License.
68233facddcc51865d612a919d450db6954aa48e3Michael Kolb * You may obtain a copy of the License at
78233facddcc51865d612a919d450db6954aa48e3Michael Kolb *
88233facddcc51865d612a919d450db6954aa48e3Michael Kolb *      http://www.apache.org/licenses/LICENSE-2.0
98233facddcc51865d612a919d450db6954aa48e3Michael Kolb *
108233facddcc51865d612a919d450db6954aa48e3Michael Kolb * Unless required by applicable law or agreed to in writing, software
118233facddcc51865d612a919d450db6954aa48e3Michael Kolb * distributed under the License is distributed on an "AS IS" BASIS,
128233facddcc51865d612a919d450db6954aa48e3Michael Kolb * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
138233facddcc51865d612a919d450db6954aa48e3Michael Kolb * See the License for the specific language governing permissions and
148233facddcc51865d612a919d450db6954aa48e3Michael Kolb * limitations under the License.
158233facddcc51865d612a919d450db6954aa48e3Michael Kolb */
168233facddcc51865d612a919d450db6954aa48e3Michael Kolb
178233facddcc51865d612a919d450db6954aa48e3Michael Kolbpackage com.android.browser;
188233facddcc51865d612a919d450db6954aa48e3Michael Kolb
198233facddcc51865d612a919d450db6954aa48e3Michael Kolbimport android.app.Activity;
208233facddcc51865d612a919d450db6954aa48e3Michael Kolbimport android.app.DownloadManager;
218233facddcc51865d612a919d450db6954aa48e3Michael Kolbimport android.app.SearchManager;
228233facddcc51865d612a919d450db6954aa48e3Michael Kolbimport android.content.ClipboardManager;
238233facddcc51865d612a919d450db6954aa48e3Michael Kolbimport android.content.ContentProvider;
248233facddcc51865d612a919d450db6954aa48e3Michael Kolbimport android.content.ContentProviderClient;
258233facddcc51865d612a919d450db6954aa48e3Michael Kolbimport android.content.ContentResolver;
26d8c7452a7d8975a2d60414c5a33842b4a743e631John Reckimport android.content.ContentUris;
278233facddcc51865d612a919d450db6954aa48e3Michael Kolbimport android.content.ContentValues;
288233facddcc51865d612a919d450db6954aa48e3Michael Kolbimport android.content.Context;
298233facddcc51865d612a919d450db6954aa48e3Michael Kolbimport android.content.Intent;
308233facddcc51865d612a919d450db6954aa48e3Michael Kolbimport android.content.pm.PackageManager;
318233facddcc51865d612a919d450db6954aa48e3Michael Kolbimport android.content.pm.ResolveInfo;
328233facddcc51865d612a919d450db6954aa48e3Michael Kolbimport android.content.res.Configuration;
331961ed2f2856ca0993c8c4d15924bbb4e4ef98c0Leon Scrogginsimport android.database.ContentObserver;
348233facddcc51865d612a919d450db6954aa48e3Michael Kolbimport android.database.Cursor;
358233facddcc51865d612a919d450db6954aa48e3Michael Kolbimport android.database.sqlite.SQLiteDatabase;
368233facddcc51865d612a919d450db6954aa48e3Michael Kolbimport android.graphics.Bitmap;
378233facddcc51865d612a919d450db6954aa48e3Michael Kolbimport android.graphics.Canvas;
388233facddcc51865d612a919d450db6954aa48e3Michael Kolbimport android.graphics.Picture;
398233facddcc51865d612a919d450db6954aa48e3Michael Kolbimport android.net.Uri;
408233facddcc51865d612a919d450db6954aa48e3Michael Kolbimport android.net.http.SslError;
418233facddcc51865d612a919d450db6954aa48e3Michael Kolbimport android.os.AsyncTask;
428233facddcc51865d612a919d450db6954aa48e3Michael Kolbimport android.os.Bundle;
438233facddcc51865d612a919d450db6954aa48e3Michael Kolbimport android.os.Handler;
448233facddcc51865d612a919d450db6954aa48e3Michael Kolbimport android.os.Message;
458233facddcc51865d612a919d450db6954aa48e3Michael Kolbimport android.os.PowerManager;
468233facddcc51865d612a919d450db6954aa48e3Michael Kolbimport android.os.PowerManager.WakeLock;
478029a777106fa6fb911ee1d58402b0de768a583aBen Murdochimport android.preference.PreferenceActivity;
488233facddcc51865d612a919d450db6954aa48e3Michael Kolbimport android.provider.Browser;
498233facddcc51865d612a919d450db6954aa48e3Michael Kolbimport android.provider.BrowserContract;
508233facddcc51865d612a919d450db6954aa48e3Michael Kolbimport android.provider.BrowserContract.Images;
518233facddcc51865d612a919d450db6954aa48e3Michael Kolbimport android.provider.ContactsContract;
528233facddcc51865d612a919d450db6954aa48e3Michael Kolbimport android.provider.ContactsContract.Intents.Insert;
53cfa3af5c59abb38c895416a80ef16da0ec1b5287Michael Kolbimport android.speech.RecognizerIntent;
548233facddcc51865d612a919d450db6954aa48e3Michael Kolbimport android.text.TextUtils;
558233facddcc51865d612a919d450db6954aa48e3Michael Kolbimport android.util.Log;
56a00cbbde0b77a3e1eef5691a7adb17edd5d8ab9eJohn Reckimport android.util.Patterns;
578233facddcc51865d612a919d450db6954aa48e3Michael Kolbimport android.view.ActionMode;
588233facddcc51865d612a919d450db6954aa48e3Michael Kolbimport android.view.ContextMenu;
598233facddcc51865d612a919d450db6954aa48e3Michael Kolbimport android.view.ContextMenu.ContextMenuInfo;
608233facddcc51865d612a919d450db6954aa48e3Michael Kolbimport android.view.Gravity;
618233facddcc51865d612a919d450db6954aa48e3Michael Kolbimport android.view.KeyEvent;
628233facddcc51865d612a919d450db6954aa48e3Michael Kolbimport android.view.Menu;
638233facddcc51865d612a919d450db6954aa48e3Michael Kolbimport android.view.MenuInflater;
648233facddcc51865d612a919d450db6954aa48e3Michael Kolbimport android.view.MenuItem;
658233facddcc51865d612a919d450db6954aa48e3Michael Kolbimport android.view.MenuItem.OnMenuItemClickListener;
668233facddcc51865d612a919d450db6954aa48e3Michael Kolbimport android.view.View;
678233facddcc51865d612a919d450db6954aa48e3Michael Kolbimport android.webkit.CookieManager;
688233facddcc51865d612a919d450db6954aa48e3Michael Kolbimport android.webkit.CookieSyncManager;
698233facddcc51865d612a919d450db6954aa48e3Michael Kolbimport android.webkit.HttpAuthHandler;
7029721c2c6cc7f79a52962556c4431b71bb3ce46eMathew Inwoodimport android.webkit.SearchBox;
718233facddcc51865d612a919d450db6954aa48e3Michael Kolbimport android.webkit.SslErrorHandler;
728233facddcc51865d612a919d450db6954aa48e3Michael Kolbimport android.webkit.ValueCallback;
738233facddcc51865d612a919d450db6954aa48e3Michael Kolbimport android.webkit.WebChromeClient;
748233facddcc51865d612a919d450db6954aa48e3Michael Kolbimport android.webkit.WebIconDatabase;
758233facddcc51865d612a919d450db6954aa48e3Michael Kolbimport android.webkit.WebSettings;
768233facddcc51865d612a919d450db6954aa48e3Michael Kolbimport android.webkit.WebView;
77ac993841b3f810dd55a985141c574d4dfebd8c1aLeon Scrogginsimport android.widget.Toast;
788233facddcc51865d612a919d450db6954aa48e3Michael Kolb
794bd767d2f4ce166a44687170c6af18e242447205Michael Kolbimport com.android.browser.IntentHandler.UrlData;
802bc8042224be51966d748b870768ec1b376a1621John Reckimport com.android.browser.UI.ComboViews;
814bd767d2f4ce166a44687170c6af18e242447205Michael Kolbimport com.android.browser.UI.DropdownChangeListener;
824bd767d2f4ce166a44687170c6af18e242447205Michael Kolbimport com.android.browser.provider.BrowserProvider;
838cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reckimport com.android.browser.provider.SnapshotProvider.Snapshots;
844bd767d2f4ce166a44687170c6af18e242447205Michael Kolbimport com.android.browser.search.SearchEngine;
854bd767d2f4ce166a44687170c6af18e242447205Michael Kolbimport com.android.common.Search;
864bd767d2f4ce166a44687170c6af18e242447205Michael Kolb
878233facddcc51865d612a919d450db6954aa48e3Michael Kolbimport java.io.ByteArrayOutputStream;
888233facddcc51865d612a919d450db6954aa48e3Michael Kolbimport java.io.File;
898233facddcc51865d612a919d450db6954aa48e3Michael Kolbimport java.net.URLEncoder;
908233facddcc51865d612a919d450db6954aa48e3Michael Kolbimport java.util.Calendar;
918233facddcc51865d612a919d450db6954aa48e3Michael Kolbimport java.util.HashMap;
921bf231334fd4bda8dbde5b9a0345c756a213b3a2Michael Kolbimport java.util.List;
9326b183292dc087b16af10f482744c3bb30e1f163John Reckimport java.util.Map;
948233facddcc51865d612a919d450db6954aa48e3Michael Kolb
958233facddcc51865d612a919d450db6954aa48e3Michael Kolb/**
968233facddcc51865d612a919d450db6954aa48e3Michael Kolb * Controller for browser
978233facddcc51865d612a919d450db6954aa48e3Michael Kolb */
988233facddcc51865d612a919d450db6954aa48e3Michael Kolbpublic class Controller
998233facddcc51865d612a919d450db6954aa48e3Michael Kolb        implements WebViewController, UiController {
1008233facddcc51865d612a919d450db6954aa48e3Michael Kolb
1018233facddcc51865d612a919d450db6954aa48e3Michael Kolb    private static final String LOGTAG = "Controller";
102cfa3af5c59abb38c895416a80ef16da0ec1b5287Michael Kolb    private static final String SEND_APP_ID_EXTRA =
103cfa3af5c59abb38c895416a80ef16da0ec1b5287Michael Kolb        "android.speech.extras.SEND_APPLICATION_ID_EXTRA";
104a4261fd53fef2b311e733fcfee4be3a9967ad967Michael Kolb    private static final String INCOGNITO_URI = "browser:incognito";
105cfa3af5c59abb38c895416a80ef16da0ec1b5287Michael Kolb
1068233facddcc51865d612a919d450db6954aa48e3Michael Kolb
1078233facddcc51865d612a919d450db6954aa48e3Michael Kolb    // public message ids
1088233facddcc51865d612a919d450db6954aa48e3Michael Kolb    public final static int LOAD_URL = 1001;
1098233facddcc51865d612a919d450db6954aa48e3Michael Kolb    public final static int STOP_LOAD = 1002;
1108233facddcc51865d612a919d450db6954aa48e3Michael Kolb
1118233facddcc51865d612a919d450db6954aa48e3Michael Kolb    // Message Ids
1128233facddcc51865d612a919d450db6954aa48e3Michael Kolb    private static final int FOCUS_NODE_HREF = 102;
1138233facddcc51865d612a919d450db6954aa48e3Michael Kolb    private static final int RELEASE_WAKELOCK = 107;
1148233facddcc51865d612a919d450db6954aa48e3Michael Kolb
1158233facddcc51865d612a919d450db6954aa48e3Michael Kolb    static final int UPDATE_BOOKMARK_THUMBNAIL = 108;
1168233facddcc51865d612a919d450db6954aa48e3Michael Kolb
1178233facddcc51865d612a919d450db6954aa48e3Michael Kolb    private static final int OPEN_BOOKMARKS = 201;
1188233facddcc51865d612a919d450db6954aa48e3Michael Kolb
1198233facddcc51865d612a919d450db6954aa48e3Michael Kolb    private static final int EMPTY_MENU = -1;
1208233facddcc51865d612a919d450db6954aa48e3Michael Kolb
1218233facddcc51865d612a919d450db6954aa48e3Michael Kolb    // activity requestCode
1228233facddcc51865d612a919d450db6954aa48e3Michael Kolb    final static int PREFERENCES_PAGE = 3;
1238233facddcc51865d612a919d450db6954aa48e3Michael Kolb    final static int FILE_SELECTED = 4;
1248029a777106fa6fb911ee1d58402b0de768a583aBen Murdoch    final static int AUTOFILL_SETUP = 5;
1258029a777106fa6fb911ee1d58402b0de768a583aBen Murdoch
1268233facddcc51865d612a919d450db6954aa48e3Michael Kolb    private final static int WAKELOCK_TIMEOUT = 5 * 60 * 1000; // 5 minutes
1278233facddcc51865d612a919d450db6954aa48e3Michael Kolb
1288233facddcc51865d612a919d450db6954aa48e3Michael Kolb    // As the ids are dynamically created, we can't guarantee that they will
1298233facddcc51865d612a919d450db6954aa48e3Michael Kolb    // be in sequence, so this static array maps ids to a window number.
1308233facddcc51865d612a919d450db6954aa48e3Michael Kolb    final static private int[] WINDOW_SHORTCUT_ID_ARRAY =
1318233facddcc51865d612a919d450db6954aa48e3Michael Kolb    { R.id.window_one_menu_id, R.id.window_two_menu_id,
1328233facddcc51865d612a919d450db6954aa48e3Michael Kolb      R.id.window_three_menu_id, R.id.window_four_menu_id,
1338233facddcc51865d612a919d450db6954aa48e3Michael Kolb      R.id.window_five_menu_id, R.id.window_six_menu_id,
1348233facddcc51865d612a919d450db6954aa48e3Michael Kolb      R.id.window_seven_menu_id, R.id.window_eight_menu_id };
1358233facddcc51865d612a919d450db6954aa48e3Michael Kolb
1368233facddcc51865d612a919d450db6954aa48e3Michael Kolb    // "source" parameter for Google search through search key
1378233facddcc51865d612a919d450db6954aa48e3Michael Kolb    final static String GOOGLE_SEARCH_SOURCE_SEARCHKEY = "browser-key";
1388233facddcc51865d612a919d450db6954aa48e3Michael Kolb    // "source" parameter for Google search through simplily type
1398233facddcc51865d612a919d450db6954aa48e3Michael Kolb    final static String GOOGLE_SEARCH_SOURCE_TYPE = "browser-type";
1408233facddcc51865d612a919d450db6954aa48e3Michael Kolb
1419e78f51d14b9a16d645b754e073f549a5891db26Guang Zhu    // "no-crash-recovery" parameter in intetnt to suppress crash recovery
1429e78f51d14b9a16d645b754e073f549a5891db26Guang Zhu    final static String NO_CRASH_RECOVERY = "no-crash-recovery";
1439e78f51d14b9a16d645b754e073f549a5891db26Guang Zhu
1448233facddcc51865d612a919d450db6954aa48e3Michael Kolb    private Activity mActivity;
1458233facddcc51865d612a919d450db6954aa48e3Michael Kolb    private UI mUi;
1468233facddcc51865d612a919d450db6954aa48e3Michael Kolb    private TabControl mTabControl;
1478233facddcc51865d612a919d450db6954aa48e3Michael Kolb    private BrowserSettings mSettings;
1488233facddcc51865d612a919d450db6954aa48e3Michael Kolb    private WebViewFactory mFactory;
149b3417f0a68a1efc64604ea354ae7f856ce79cb16John Reck    private OptionsMenuHandler mOptionsMenuHandler = null;
1508233facddcc51865d612a919d450db6954aa48e3Michael Kolb
1518233facddcc51865d612a919d450db6954aa48e3Michael Kolb    private WakeLock mWakeLock;
1528233facddcc51865d612a919d450db6954aa48e3Michael Kolb
1538233facddcc51865d612a919d450db6954aa48e3Michael Kolb    private UrlHandler mUrlHandler;
1548233facddcc51865d612a919d450db6954aa48e3Michael Kolb    private UploadHandler mUploadHandler;
1558233facddcc51865d612a919d450db6954aa48e3Michael Kolb    private IntentHandler mIntentHandler;
1568233facddcc51865d612a919d450db6954aa48e3Michael Kolb    private PageDialogsHandler mPageDialogsHandler;
1578233facddcc51865d612a919d450db6954aa48e3Michael Kolb    private NetworkStateHandler mNetworkHandler;
158b2f93556ac91fe06eb8f6acab05b6a6d1b2fdbe1Martijn Coenen    private NfcHandler mNfcHandler;
1598233facddcc51865d612a919d450db6954aa48e3Michael Kolb
1608029a777106fa6fb911ee1d58402b0de768a583aBen Murdoch    private Message mAutoFillSetupMessage;
1618029a777106fa6fb911ee1d58402b0de768a583aBen Murdoch
1628233facddcc51865d612a919d450db6954aa48e3Michael Kolb    private boolean mShouldShowErrorConsole;
1638233facddcc51865d612a919d450db6954aa48e3Michael Kolb
1648233facddcc51865d612a919d450db6954aa48e3Michael Kolb    private SystemAllowGeolocationOrigins mSystemAllowGeolocationOrigins;
1658233facddcc51865d612a919d450db6954aa48e3Michael Kolb
1668233facddcc51865d612a919d450db6954aa48e3Michael Kolb    // FIXME, temp address onPrepareMenu performance problem.
1678233facddcc51865d612a919d450db6954aa48e3Michael Kolb    // When we move everything out of view, we should rewrite this.
1688233facddcc51865d612a919d450db6954aa48e3Michael Kolb    private int mCurrentMenuState = 0;
1698233facddcc51865d612a919d450db6954aa48e3Michael Kolb    private int mMenuState = R.id.MAIN_MENU;
1708233facddcc51865d612a919d450db6954aa48e3Michael Kolb    private int mOldMenuState = EMPTY_MENU;
1718233facddcc51865d612a919d450db6954aa48e3Michael Kolb    private Menu mCachedMenu;
1728233facddcc51865d612a919d450db6954aa48e3Michael Kolb
1738233facddcc51865d612a919d450db6954aa48e3Michael Kolb    private boolean mMenuIsDown;
1748233facddcc51865d612a919d450db6954aa48e3Michael Kolb
1758233facddcc51865d612a919d450db6954aa48e3Michael Kolb    // For select and find, we keep track of the ActionMode so that
1768233facddcc51865d612a919d450db6954aa48e3Michael Kolb    // finish() can be called as desired.
1778233facddcc51865d612a919d450db6954aa48e3Michael Kolb    private ActionMode mActionMode;
1788233facddcc51865d612a919d450db6954aa48e3Michael Kolb
1798233facddcc51865d612a919d450db6954aa48e3Michael Kolb    /**
1808233facddcc51865d612a919d450db6954aa48e3Michael Kolb     * Only meaningful when mOptionsMenuOpen is true.  This variable keeps track
1818233facddcc51865d612a919d450db6954aa48e3Michael Kolb     * of whether the configuration has changed.  The first onMenuOpened call
1828233facddcc51865d612a919d450db6954aa48e3Michael Kolb     * after a configuration change is simply a reopening of the same menu
1838233facddcc51865d612a919d450db6954aa48e3Michael Kolb     * (i.e. mIconView did not change).
1848233facddcc51865d612a919d450db6954aa48e3Michael Kolb     */
1858233facddcc51865d612a919d450db6954aa48e3Michael Kolb    private boolean mConfigChanged;
1868233facddcc51865d612a919d450db6954aa48e3Michael Kolb
1878233facddcc51865d612a919d450db6954aa48e3Michael Kolb    /**
1888233facddcc51865d612a919d450db6954aa48e3Michael Kolb     * Keeps track of whether the options menu is open. This is important in
1898233facddcc51865d612a919d450db6954aa48e3Michael Kolb     * determining whether to show or hide the title bar overlay
1908233facddcc51865d612a919d450db6954aa48e3Michael Kolb     */
1918233facddcc51865d612a919d450db6954aa48e3Michael Kolb    private boolean mOptionsMenuOpen;
1928233facddcc51865d612a919d450db6954aa48e3Michael Kolb
1938233facddcc51865d612a919d450db6954aa48e3Michael Kolb    /**
1948233facddcc51865d612a919d450db6954aa48e3Michael Kolb     * Whether or not the options menu is in its bigger, popup menu form. When
1958233facddcc51865d612a919d450db6954aa48e3Michael Kolb     * true, we want the title bar overlay to be gone. When false, we do not.
1968233facddcc51865d612a919d450db6954aa48e3Michael Kolb     * Only meaningful if mOptionsMenuOpen is true.
1978233facddcc51865d612a919d450db6954aa48e3Michael Kolb     */
1988233facddcc51865d612a919d450db6954aa48e3Michael Kolb    private boolean mExtendedMenuOpen;
1998233facddcc51865d612a919d450db6954aa48e3Michael Kolb
2008233facddcc51865d612a919d450db6954aa48e3Michael Kolb    private boolean mInLoad;
2018233facddcc51865d612a919d450db6954aa48e3Michael Kolb
2028233facddcc51865d612a919d450db6954aa48e3Michael Kolb    private boolean mActivityPaused = true;
2038233facddcc51865d612a919d450db6954aa48e3Michael Kolb    private boolean mLoadStopped;
2048233facddcc51865d612a919d450db6954aa48e3Michael Kolb
2058233facddcc51865d612a919d450db6954aa48e3Michael Kolb    private Handler mHandler;
2061961ed2f2856ca0993c8c4d15924bbb4e4ef98c0Leon Scroggins    // Checks to see when the bookmarks database has changed, and updates the
2071961ed2f2856ca0993c8c4d15924bbb4e4ef98c0Leon Scroggins    // Tabs' notion of whether they represent bookmarked sites.
2081961ed2f2856ca0993c8c4d15924bbb4e4ef98c0Leon Scroggins    private ContentObserver mBookmarksObserver;
2090ebd3ac69a76ec76d9caab65a1947f971242994eJohn Reck    private DataController mDataController;
210847b532045e3cb117a847ebb956c9919401f332dJohn Reck    private CrashRecoveryHandler mCrashRecoveryHandler;
2118233facddcc51865d612a919d450db6954aa48e3Michael Kolb
2128233facddcc51865d612a919d450db6954aa48e3Michael Kolb    private static class ClearThumbnails extends AsyncTask<File, Void, Void> {
2138233facddcc51865d612a919d450db6954aa48e3Michael Kolb        @Override
2148233facddcc51865d612a919d450db6954aa48e3Michael Kolb        public Void doInBackground(File... files) {
2158233facddcc51865d612a919d450db6954aa48e3Michael Kolb            if (files != null) {
2168233facddcc51865d612a919d450db6954aa48e3Michael Kolb                for (File f : files) {
2178233facddcc51865d612a919d450db6954aa48e3Michael Kolb                    if (!f.delete()) {
2188233facddcc51865d612a919d450db6954aa48e3Michael Kolb                        Log.e(LOGTAG, f.getPath() + " was not deleted");
2198233facddcc51865d612a919d450db6954aa48e3Michael Kolb                    }
2208233facddcc51865d612a919d450db6954aa48e3Michael Kolb                }
2218233facddcc51865d612a919d450db6954aa48e3Michael Kolb            }
2228233facddcc51865d612a919d450db6954aa48e3Michael Kolb            return null;
2238233facddcc51865d612a919d450db6954aa48e3Michael Kolb        }
2248233facddcc51865d612a919d450db6954aa48e3Michael Kolb    }
2258233facddcc51865d612a919d450db6954aa48e3Michael Kolb
2268233facddcc51865d612a919d450db6954aa48e3Michael Kolb    public Controller(Activity browser) {
2278233facddcc51865d612a919d450db6954aa48e3Michael Kolb        mActivity = browser;
2288233facddcc51865d612a919d450db6954aa48e3Michael Kolb        mSettings = BrowserSettings.getInstance();
2290ebd3ac69a76ec76d9caab65a1947f971242994eJohn Reck        mDataController = DataController.getInstance(mActivity);
2308233facddcc51865d612a919d450db6954aa48e3Michael Kolb        mTabControl = new TabControl(this);
2318233facddcc51865d612a919d450db6954aa48e3Michael Kolb        mSettings.setController(this);
232378a41055fab6c521cdc1d9b2cfeefff2af19e7cJohn Reck        mCrashRecoveryHandler = CrashRecoveryHandler.initialize(this);
2331461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb        mFactory = new BrowserWebViewFactory(browser);
2348233facddcc51865d612a919d450db6954aa48e3Michael Kolb
2358233facddcc51865d612a919d450db6954aa48e3Michael Kolb        mUrlHandler = new UrlHandler(this);
2368233facddcc51865d612a919d450db6954aa48e3Michael Kolb        mIntentHandler = new IntentHandler(mActivity, this);
2378233facddcc51865d612a919d450db6954aa48e3Michael Kolb        mPageDialogsHandler = new PageDialogsHandler(mActivity, this);
238b2f93556ac91fe06eb8f6acab05b6a6d1b2fdbe1Martijn Coenen        mNfcHandler = new NfcHandler(mActivity, this);
2398233facddcc51865d612a919d450db6954aa48e3Michael Kolb
2408233facddcc51865d612a919d450db6954aa48e3Michael Kolb        PowerManager pm = (PowerManager) mActivity
2418233facddcc51865d612a919d450db6954aa48e3Michael Kolb                .getSystemService(Context.POWER_SERVICE);
2428233facddcc51865d612a919d450db6954aa48e3Michael Kolb        mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "Browser");
2438233facddcc51865d612a919d450db6954aa48e3Michael Kolb
2448233facddcc51865d612a919d450db6954aa48e3Michael Kolb        startHandler();
2451961ed2f2856ca0993c8c4d15924bbb4e4ef98c0Leon Scroggins        mBookmarksObserver = new ContentObserver(mHandler) {
2461961ed2f2856ca0993c8c4d15924bbb4e4ef98c0Leon Scroggins            @Override
2471961ed2f2856ca0993c8c4d15924bbb4e4ef98c0Leon Scroggins            public void onChange(boolean selfChange) {
2481961ed2f2856ca0993c8c4d15924bbb4e4ef98c0Leon Scroggins                int size = mTabControl.getTabCount();
2491961ed2f2856ca0993c8c4d15924bbb4e4ef98c0Leon Scroggins                for (int i = 0; i < size; i++) {
2501961ed2f2856ca0993c8c4d15924bbb4e4ef98c0Leon Scroggins                    mTabControl.getTab(i).updateBookmarkedStatus();
2511961ed2f2856ca0993c8c4d15924bbb4e4ef98c0Leon Scroggins                }
2521961ed2f2856ca0993c8c4d15924bbb4e4ef98c0Leon Scroggins            }
2531961ed2f2856ca0993c8c4d15924bbb4e4ef98c0Leon Scroggins
2541961ed2f2856ca0993c8c4d15924bbb4e4ef98c0Leon Scroggins        };
2551961ed2f2856ca0993c8c4d15924bbb4e4ef98c0Leon Scroggins        browser.getContentResolver().registerContentObserver(
2561961ed2f2856ca0993c8c4d15924bbb4e4ef98c0Leon Scroggins                BrowserContract.Bookmarks.CONTENT_URI, true, mBookmarksObserver);
2578233facddcc51865d612a919d450db6954aa48e3Michael Kolb
2588233facddcc51865d612a919d450db6954aa48e3Michael Kolb        mNetworkHandler = new NetworkStateHandler(mActivity, this);
2598233facddcc51865d612a919d450db6954aa48e3Michael Kolb        // Start watching the default geolocation permissions
2608233facddcc51865d612a919d450db6954aa48e3Michael Kolb        mSystemAllowGeolocationOrigins =
2618233facddcc51865d612a919d450db6954aa48e3Michael Kolb                new SystemAllowGeolocationOrigins(mActivity.getApplicationContext());
2628233facddcc51865d612a919d450db6954aa48e3Michael Kolb        mSystemAllowGeolocationOrigins.start();
2638233facddcc51865d612a919d450db6954aa48e3Michael Kolb
2648233facddcc51865d612a919d450db6954aa48e3Michael Kolb        retainIconsOnStartup();
2658233facddcc51865d612a919d450db6954aa48e3Michael Kolb    }
2668233facddcc51865d612a919d450db6954aa48e3Michael Kolb
2677d50a9364107c21e3358e1dbc51a06359a5287fbPatrick Scott    void start(final Bundle icicle, final Intent intent) {
2689e78f51d14b9a16d645b754e073f549a5891db26Guang Zhu        boolean noCrashRecovery = intent.getBooleanExtra(NO_CRASH_RECOVERY, false);
2699e78f51d14b9a16d645b754e073f549a5891db26Guang Zhu        if (icicle != null || noCrashRecovery) {
270847b532045e3cb117a847ebb956c9919401f332dJohn Reck            doStart(icicle, intent);
271847b532045e3cb117a847ebb956c9919401f332dJohn Reck        } else {
272847b532045e3cb117a847ebb956c9919401f332dJohn Reck            mCrashRecoveryHandler.startRecovery(intent);
273847b532045e3cb117a847ebb956c9919401f332dJohn Reck        }
274847b532045e3cb117a847ebb956c9919401f332dJohn Reck    }
275847b532045e3cb117a847ebb956c9919401f332dJohn Reck
276847b532045e3cb117a847ebb956c9919401f332dJohn Reck    void doStart(final Bundle icicle, final Intent intent) {
2778233facddcc51865d612a919d450db6954aa48e3Michael Kolb        // Unless the last browser usage was within 24 hours, destroy any
2788233facddcc51865d612a919d450db6954aa48e3Michael Kolb        // remaining incognito tabs.
2798233facddcc51865d612a919d450db6954aa48e3Michael Kolb
2808233facddcc51865d612a919d450db6954aa48e3Michael Kolb        Calendar lastActiveDate = icicle != null ?
2818233facddcc51865d612a919d450db6954aa48e3Michael Kolb                (Calendar) icicle.getSerializable("lastActiveDate") : null;
2828233facddcc51865d612a919d450db6954aa48e3Michael Kolb        Calendar today = Calendar.getInstance();
2838233facddcc51865d612a919d450db6954aa48e3Michael Kolb        Calendar yesterday = Calendar.getInstance();
2848233facddcc51865d612a919d450db6954aa48e3Michael Kolb        yesterday.add(Calendar.DATE, -1);
2858233facddcc51865d612a919d450db6954aa48e3Michael Kolb
2867d50a9364107c21e3358e1dbc51a06359a5287fbPatrick Scott        final boolean restoreIncognitoTabs = !(lastActiveDate == null
2878233facddcc51865d612a919d450db6954aa48e3Michael Kolb            || lastActiveDate.before(yesterday)
2881bf231334fd4bda8dbde5b9a0345c756a213b3a2Michael Kolb            || lastActiveDate.after(today));
2898233facddcc51865d612a919d450db6954aa48e3Michael Kolb
2907d50a9364107c21e3358e1dbc51a06359a5287fbPatrick Scott        // Find out if we will restore any state and remember the tab.
291c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb        final long currentTabId =
2927d50a9364107c21e3358e1dbc51a06359a5287fbPatrick Scott                mTabControl.canRestoreState(icicle, restoreIncognitoTabs);
2937d50a9364107c21e3358e1dbc51a06359a5287fbPatrick Scott
294c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb        if (currentTabId == -1) {
2957d50a9364107c21e3358e1dbc51a06359a5287fbPatrick Scott            // Not able to restore so we go ahead and clear session cookies.  We
2967d50a9364107c21e3358e1dbc51a06359a5287fbPatrick Scott            // must do this before trying to login the user as we don't want to
2977d50a9364107c21e3358e1dbc51a06359a5287fbPatrick Scott            // clear any session cookies set during login.
2983a4e8091e246e42ebd0add6342eb4eaed88012a3Kristian Monsen            CookieManager.getInstance().removeSessionCookie();
2997d50a9364107c21e3358e1dbc51a06359a5287fbPatrick Scott        }
3007d50a9364107c21e3358e1dbc51a06359a5287fbPatrick Scott
301d43e75adea6f394730828cbf830438e2bddaed4bPatrick Scott        GoogleAccountLogin.startLoginIfNeeded(mActivity,
3027d50a9364107c21e3358e1dbc51a06359a5287fbPatrick Scott                new Runnable() {
3037d50a9364107c21e3358e1dbc51a06359a5287fbPatrick Scott                    @Override public void run() {
304c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb                        onPreloginFinished(icicle, intent, currentTabId, restoreIncognitoTabs);
3057d50a9364107c21e3358e1dbc51a06359a5287fbPatrick Scott                    }
3067d50a9364107c21e3358e1dbc51a06359a5287fbPatrick Scott                });
3077d50a9364107c21e3358e1dbc51a06359a5287fbPatrick Scott    }
3082cd9701de79c8e4e37971498b91ff2530bc58694Kristian Monsen
309c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb    private void onPreloginFinished(Bundle icicle, Intent intent, long currentTabId,
3107d50a9364107c21e3358e1dbc51a06359a5287fbPatrick Scott            boolean restoreIncognitoTabs) {
311c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb        if (currentTabId == -1) {
3128233facddcc51865d612a919d450db6954aa48e3Michael Kolb            final Bundle extra = intent.getExtras();
3138233facddcc51865d612a919d450db6954aa48e3Michael Kolb            // Create an initial tab.
3148233facddcc51865d612a919d450db6954aa48e3Michael Kolb            // If the intent is ACTION_VIEW and data is not null, the Browser is
3158233facddcc51865d612a919d450db6954aa48e3Michael Kolb            // invoked to view the content by another application. In this case,
3168233facddcc51865d612a919d450db6954aa48e3Michael Kolb            // the tab will be close when exit.
3171461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb            UrlData urlData = IntentHandler.getUrlDataFromIntent(intent);
3187bcafde2ba532941c1eb8c9022eebd5398aeae2aMichael Kolb            Tab t = null;
3197bcafde2ba532941c1eb8c9022eebd5398aeae2aMichael Kolb            if (urlData.isEmpty()) {
3207bcafde2ba532941c1eb8c9022eebd5398aeae2aMichael Kolb                t = openTabToHomePage();
3217bcafde2ba532941c1eb8c9022eebd5398aeae2aMichael Kolb            } else {
3227bcafde2ba532941c1eb8c9022eebd5398aeae2aMichael Kolb                t = openTab(urlData);
3237bcafde2ba532941c1eb8c9022eebd5398aeae2aMichael Kolb            }
3247bcafde2ba532941c1eb8c9022eebd5398aeae2aMichael Kolb            if (t != null) {
3257bcafde2ba532941c1eb8c9022eebd5398aeae2aMichael Kolb                t.setAppId(intent.getStringExtra(Browser.EXTRA_APPLICATION_ID));
3267bcafde2ba532941c1eb8c9022eebd5398aeae2aMichael Kolb            }
3278233facddcc51865d612a919d450db6954aa48e3Michael Kolb            WebView webView = t.getWebView();
3288233facddcc51865d612a919d450db6954aa48e3Michael Kolb            if (extra != null) {
3298233facddcc51865d612a919d450db6954aa48e3Michael Kolb                int scale = extra.getInt(Browser.INITIAL_ZOOM_LEVEL, 0);
3308233facddcc51865d612a919d450db6954aa48e3Michael Kolb                if (scale > 0 && scale <= 1000) {
3318233facddcc51865d612a919d450db6954aa48e3Michael Kolb                    webView.setInitialScale(scale);
3328233facddcc51865d612a919d450db6954aa48e3Michael Kolb                }
3338233facddcc51865d612a919d450db6954aa48e3Michael Kolb            }
334d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck            mUi.updateTabs(mTabControl.getTabs());
3358233facddcc51865d612a919d450db6954aa48e3Michael Kolb        } else {
336c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb            mTabControl.restoreState(icicle, currentTabId, restoreIncognitoTabs,
3377d50a9364107c21e3358e1dbc51a06359a5287fbPatrick Scott                    mUi.needsRestoreAllTabs());
3381bf231334fd4bda8dbde5b9a0345c756a213b3a2Michael Kolb            mUi.updateTabs(mTabControl.getTabs());
3398233facddcc51865d612a919d450db6954aa48e3Michael Kolb            // TabControl.restoreState() will create a new tab even if
3408233facddcc51865d612a919d450db6954aa48e3Michael Kolb            // restoring the state fails.
3418233facddcc51865d612a919d450db6954aa48e3Michael Kolb            setActiveTab(mTabControl.getCurrentTab());
342db22ec4ee014900988062d910bc810172a07df56John Reck            // Handle the intent
343db22ec4ee014900988062d910bc810172a07df56John Reck            mIntentHandler.onNewIntent(intent);
3448233facddcc51865d612a919d450db6954aa48e3Michael Kolb        }
3458233facddcc51865d612a919d450db6954aa48e3Michael Kolb        // clear up the thumbnail directory, which is no longer used;
3468233facddcc51865d612a919d450db6954aa48e3Michael Kolb        // ideally this should only be run once after an upgrade from
3478233facddcc51865d612a919d450db6954aa48e3Michael Kolb        // a previous version of the browser
3488233facddcc51865d612a919d450db6954aa48e3Michael Kolb        new ClearThumbnails().execute(mTabControl.getThumbnailDir()
3498233facddcc51865d612a919d450db6954aa48e3Michael Kolb                .listFiles());
3508233facddcc51865d612a919d450db6954aa48e3Michael Kolb        // Read JavaScript flags if it exists.
35135e9dd6283a2d65687104eb0b3a459c02dcb150bJohn Reck        String jsFlags = getSettings().getJsEngineFlags();
3528233facddcc51865d612a919d450db6954aa48e3Michael Kolb        if (jsFlags.trim().length() != 0) {
3538233facddcc51865d612a919d450db6954aa48e3Michael Kolb            getCurrentWebView().setJsFlags(jsFlags);
3548233facddcc51865d612a919d450db6954aa48e3Michael Kolb        }
355439c9a58765aa6aab95d55422ee61ea8360e912dJohn Reck        if (BrowserActivity.ACTION_SHOW_BOOKMARKS.equals(intent.getAction())) {
356439c9a58765aa6aab95d55422ee61ea8360e912dJohn Reck            bookmarksOrHistoryPicker(false);
357439c9a58765aa6aab95d55422ee61ea8360e912dJohn Reck        }
3588233facddcc51865d612a919d450db6954aa48e3Michael Kolb    }
3598233facddcc51865d612a919d450db6954aa48e3Michael Kolb
3601514bb7ed5656316a8dac966cee21653f3c59affMichael Kolb    @Override
3611514bb7ed5656316a8dac966cee21653f3c59affMichael Kolb    public WebViewFactory getWebViewFactory() {
3628233facddcc51865d612a919d450db6954aa48e3Michael Kolb        return mFactory;
3638233facddcc51865d612a919d450db6954aa48e3Michael Kolb    }
3648233facddcc51865d612a919d450db6954aa48e3Michael Kolb
3658233facddcc51865d612a919d450db6954aa48e3Michael Kolb    @Override
366a713ec8cc9da6c0c8078cd297c6240eb8bf01bbbMichael Kolb    public void onSetWebView(Tab tab, WebView view) {
367a713ec8cc9da6c0c8078cd297c6240eb8bf01bbbMichael Kolb        mUi.onSetWebView(tab, view);
368a713ec8cc9da6c0c8078cd297c6240eb8bf01bbbMichael Kolb    }
369a713ec8cc9da6c0c8078cd297c6240eb8bf01bbbMichael Kolb
370a713ec8cc9da6c0c8078cd297c6240eb8bf01bbbMichael Kolb    @Override
3711514bb7ed5656316a8dac966cee21653f3c59affMichael Kolb    public void createSubWindow(Tab tab) {
3721514bb7ed5656316a8dac966cee21653f3c59affMichael Kolb        endActionMode();
3731514bb7ed5656316a8dac966cee21653f3c59affMichael Kolb        WebView mainView = tab.getWebView();
3741514bb7ed5656316a8dac966cee21653f3c59affMichael Kolb        WebView subView = mFactory.createWebView((mainView == null)
3751514bb7ed5656316a8dac966cee21653f3c59affMichael Kolb                ? false
3761514bb7ed5656316a8dac966cee21653f3c59affMichael Kolb                : mainView.isPrivateBrowsingEnabled());
3771514bb7ed5656316a8dac966cee21653f3c59affMichael Kolb        mUi.createSubWindow(tab, subView);
3781514bb7ed5656316a8dac966cee21653f3c59affMichael Kolb    }
3791514bb7ed5656316a8dac966cee21653f3c59affMichael Kolb
3801514bb7ed5656316a8dac966cee21653f3c59affMichael Kolb    @Override
3811461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb    public Context getContext() {
3821461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb        return mActivity;
3831461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb    }
3841461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb
3851461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb    @Override
3868233facddcc51865d612a919d450db6954aa48e3Michael Kolb    public Activity getActivity() {
3878233facddcc51865d612a919d450db6954aa48e3Michael Kolb        return mActivity;
3888233facddcc51865d612a919d450db6954aa48e3Michael Kolb    }
3898233facddcc51865d612a919d450db6954aa48e3Michael Kolb
3908233facddcc51865d612a919d450db6954aa48e3Michael Kolb    void setUi(UI ui) {
3918233facddcc51865d612a919d450db6954aa48e3Michael Kolb        mUi = ui;
3928233facddcc51865d612a919d450db6954aa48e3Michael Kolb    }
3938233facddcc51865d612a919d450db6954aa48e3Michael Kolb
3948233facddcc51865d612a919d450db6954aa48e3Michael Kolb    BrowserSettings getSettings() {
3958233facddcc51865d612a919d450db6954aa48e3Michael Kolb        return mSettings;
3968233facddcc51865d612a919d450db6954aa48e3Michael Kolb    }
3978233facddcc51865d612a919d450db6954aa48e3Michael Kolb
3988233facddcc51865d612a919d450db6954aa48e3Michael Kolb    IntentHandler getIntentHandler() {
3998233facddcc51865d612a919d450db6954aa48e3Michael Kolb        return mIntentHandler;
4008233facddcc51865d612a919d450db6954aa48e3Michael Kolb    }
4018233facddcc51865d612a919d450db6954aa48e3Michael Kolb
4028233facddcc51865d612a919d450db6954aa48e3Michael Kolb    @Override
4038233facddcc51865d612a919d450db6954aa48e3Michael Kolb    public UI getUi() {
4048233facddcc51865d612a919d450db6954aa48e3Michael Kolb        return mUi;
4058233facddcc51865d612a919d450db6954aa48e3Michael Kolb    }
4068233facddcc51865d612a919d450db6954aa48e3Michael Kolb
4078233facddcc51865d612a919d450db6954aa48e3Michael Kolb    int getMaxTabs() {
4088233facddcc51865d612a919d450db6954aa48e3Michael Kolb        return mActivity.getResources().getInteger(R.integer.max_tabs);
4098233facddcc51865d612a919d450db6954aa48e3Michael Kolb    }
4108233facddcc51865d612a919d450db6954aa48e3Michael Kolb
4118233facddcc51865d612a919d450db6954aa48e3Michael Kolb    @Override
4128233facddcc51865d612a919d450db6954aa48e3Michael Kolb    public TabControl getTabControl() {
4138233facddcc51865d612a919d450db6954aa48e3Michael Kolb        return mTabControl;
4148233facddcc51865d612a919d450db6954aa48e3Michael Kolb    }
4158233facddcc51865d612a919d450db6954aa48e3Michael Kolb
4161bf231334fd4bda8dbde5b9a0345c756a213b3a2Michael Kolb    @Override
4171bf231334fd4bda8dbde5b9a0345c756a213b3a2Michael Kolb    public List<Tab> getTabs() {
4181bf231334fd4bda8dbde5b9a0345c756a213b3a2Michael Kolb        return mTabControl.getTabs();
4191bf231334fd4bda8dbde5b9a0345c756a213b3a2Michael Kolb    }
4201bf231334fd4bda8dbde5b9a0345c756a213b3a2Michael Kolb
4218233facddcc51865d612a919d450db6954aa48e3Michael Kolb    // Open the icon database and retain all the icons for visited sites.
4229446b9351cec1ffddd211ba02d985b91853f8398Ben Murdoch    // This is done on a background thread so as not to stall startup.
4238233facddcc51865d612a919d450db6954aa48e3Michael Kolb    private void retainIconsOnStartup() {
4249446b9351cec1ffddd211ba02d985b91853f8398Ben Murdoch        // WebIconDatabase needs to be retrieved on the UI thread so that if
4259446b9351cec1ffddd211ba02d985b91853f8398Ben Murdoch        // it has not been created successfully yet the Handler is started on the
4269446b9351cec1ffddd211ba02d985b91853f8398Ben Murdoch        // UI thread.
4279446b9351cec1ffddd211ba02d985b91853f8398Ben Murdoch        new RetainIconsOnStartupTask(WebIconDatabase.getInstance()).execute();
4289446b9351cec1ffddd211ba02d985b91853f8398Ben Murdoch    }
4299446b9351cec1ffddd211ba02d985b91853f8398Ben Murdoch
4309446b9351cec1ffddd211ba02d985b91853f8398Ben Murdoch    private class RetainIconsOnStartupTask extends AsyncTask<Void, Void, Void> {
4319446b9351cec1ffddd211ba02d985b91853f8398Ben Murdoch        private WebIconDatabase mDb;
4329446b9351cec1ffddd211ba02d985b91853f8398Ben Murdoch
4339446b9351cec1ffddd211ba02d985b91853f8398Ben Murdoch        public RetainIconsOnStartupTask(WebIconDatabase db) {
4349446b9351cec1ffddd211ba02d985b91853f8398Ben Murdoch            mDb = db;
4359446b9351cec1ffddd211ba02d985b91853f8398Ben Murdoch        }
4369446b9351cec1ffddd211ba02d985b91853f8398Ben Murdoch
437a00cbbde0b77a3e1eef5691a7adb17edd5d8ab9eJohn Reck        @Override
4389446b9351cec1ffddd211ba02d985b91853f8398Ben Murdoch        protected Void doInBackground(Void... unused) {
4399446b9351cec1ffddd211ba02d985b91853f8398Ben Murdoch            mDb.open(mActivity.getDir("icons", 0).getPath());
4409446b9351cec1ffddd211ba02d985b91853f8398Ben Murdoch            Cursor c = null;
4419446b9351cec1ffddd211ba02d985b91853f8398Ben Murdoch            try {
4429446b9351cec1ffddd211ba02d985b91853f8398Ben Murdoch                c = Browser.getAllBookmarks(mActivity.getContentResolver());
4439446b9351cec1ffddd211ba02d985b91853f8398Ben Murdoch                if (c.moveToFirst()) {
4449446b9351cec1ffddd211ba02d985b91853f8398Ben Murdoch                    int urlIndex = c.getColumnIndex(Browser.BookmarkColumns.URL);
4459446b9351cec1ffddd211ba02d985b91853f8398Ben Murdoch                    do {
4469446b9351cec1ffddd211ba02d985b91853f8398Ben Murdoch                        String url = c.getString(urlIndex);
4479446b9351cec1ffddd211ba02d985b91853f8398Ben Murdoch                        mDb.retainIconForPageUrl(url);
4489446b9351cec1ffddd211ba02d985b91853f8398Ben Murdoch                    } while (c.moveToNext());
4499446b9351cec1ffddd211ba02d985b91853f8398Ben Murdoch                }
4509446b9351cec1ffddd211ba02d985b91853f8398Ben Murdoch            } catch (IllegalStateException e) {
4519446b9351cec1ffddd211ba02d985b91853f8398Ben Murdoch                Log.e(LOGTAG, "retainIconsOnStartup", e);
4529446b9351cec1ffddd211ba02d985b91853f8398Ben Murdoch            } finally {
4539446b9351cec1ffddd211ba02d985b91853f8398Ben Murdoch                if (c != null) c.close();
4548233facddcc51865d612a919d450db6954aa48e3Michael Kolb            }
4559446b9351cec1ffddd211ba02d985b91853f8398Ben Murdoch
4569446b9351cec1ffddd211ba02d985b91853f8398Ben Murdoch            return null;
4578233facddcc51865d612a919d450db6954aa48e3Michael Kolb        }
4588233facddcc51865d612a919d450db6954aa48e3Michael Kolb    }
4598233facddcc51865d612a919d450db6954aa48e3Michael Kolb
4608233facddcc51865d612a919d450db6954aa48e3Michael Kolb    private void startHandler() {
4618233facddcc51865d612a919d450db6954aa48e3Michael Kolb        mHandler = new Handler() {
4628233facddcc51865d612a919d450db6954aa48e3Michael Kolb
4638233facddcc51865d612a919d450db6954aa48e3Michael Kolb            @Override
4648233facddcc51865d612a919d450db6954aa48e3Michael Kolb            public void handleMessage(Message msg) {
4658233facddcc51865d612a919d450db6954aa48e3Michael Kolb                switch (msg.what) {
4668233facddcc51865d612a919d450db6954aa48e3Michael Kolb                    case OPEN_BOOKMARKS:
4678233facddcc51865d612a919d450db6954aa48e3Michael Kolb                        bookmarksOrHistoryPicker(false);
4688233facddcc51865d612a919d450db6954aa48e3Michael Kolb                        break;
4698233facddcc51865d612a919d450db6954aa48e3Michael Kolb                    case FOCUS_NODE_HREF:
4708233facddcc51865d612a919d450db6954aa48e3Michael Kolb                    {
4718233facddcc51865d612a919d450db6954aa48e3Michael Kolb                        String url = (String) msg.getData().get("url");
4728233facddcc51865d612a919d450db6954aa48e3Michael Kolb                        String title = (String) msg.getData().get("title");
473043c2d63f65464e13a50e831f054a8f18414b9e6Cary Clark                        String src = (String) msg.getData().get("src");
474043c2d63f65464e13a50e831f054a8f18414b9e6Cary Clark                        if (url == "") url = src; // use image if no anchor
4758233facddcc51865d612a919d450db6954aa48e3Michael Kolb                        if (TextUtils.isEmpty(url)) {
4768233facddcc51865d612a919d450db6954aa48e3Michael Kolb                            break;
4778233facddcc51865d612a919d450db6954aa48e3Michael Kolb                        }
4788233facddcc51865d612a919d450db6954aa48e3Michael Kolb                        HashMap focusNodeMap = (HashMap) msg.obj;
4798233facddcc51865d612a919d450db6954aa48e3Michael Kolb                        WebView view = (WebView) focusNodeMap.get("webview");
4808233facddcc51865d612a919d450db6954aa48e3Michael Kolb                        // Only apply the action if the top window did not change.
4818233facddcc51865d612a919d450db6954aa48e3Michael Kolb                        if (getCurrentTopWebView() != view) {
4828233facddcc51865d612a919d450db6954aa48e3Michael Kolb                            break;
4838233facddcc51865d612a919d450db6954aa48e3Michael Kolb                        }
4848233facddcc51865d612a919d450db6954aa48e3Michael Kolb                        switch (msg.arg1) {
4858233facddcc51865d612a919d450db6954aa48e3Michael Kolb                            case R.id.open_context_menu_id:
48626b183292dc087b16af10f482744c3bb30e1f163John Reck                                loadUrlFromContext(url);
4878233facddcc51865d612a919d450db6954aa48e3Michael Kolb                                break;
488043c2d63f65464e13a50e831f054a8f18414b9e6Cary Clark                            case R.id.view_image_context_menu_id:
48926b183292dc087b16af10f482744c3bb30e1f163John Reck                                loadUrlFromContext(src);
490043c2d63f65464e13a50e831f054a8f18414b9e6Cary Clark                                break;
491026f254cff9d762a9f9c9d9bf74f15809d730cd2Leon Scroggins                            case R.id.open_newtab_context_menu_id:
492026f254cff9d762a9f9c9d9bf74f15809d730cd2Leon Scroggins                                final Tab parent = mTabControl.getCurrentTab();
4935949c661b51295148706d53a03b41df2eb840ae3John Reck                                openTab(url, parent,
4945949c661b51295148706d53a03b41df2eb840ae3John Reck                                        !mSettings.openInBackground(), true);
495026f254cff9d762a9f9c9d9bf74f15809d730cd2Leon Scroggins                                break;
4968233facddcc51865d612a919d450db6954aa48e3Michael Kolb                            case R.id.copy_link_context_menu_id:
4978233facddcc51865d612a919d450db6954aa48e3Michael Kolb                                copy(url);
4988233facddcc51865d612a919d450db6954aa48e3Michael Kolb                                break;
4998233facddcc51865d612a919d450db6954aa48e3Michael Kolb                            case R.id.save_link_context_menu_id:
5008233facddcc51865d612a919d450db6954aa48e3Michael Kolb                            case R.id.download_context_menu_id:
50163c0266b5d1fca4df859fe4fa3a9555d0783a2b6Leon Scroggins                                DownloadHandler.onDownloadStartNoStream(
502bc5cc75c302eb49d15258155fc6f672fcbd62842Kristian Monsen                                        mActivity, url, null, null, null,
503bc5cc75c302eb49d15258155fc6f672fcbd62842Kristian Monsen                                        view.isPrivateBrowsingEnabled());
5048233facddcc51865d612a919d450db6954aa48e3Michael Kolb                                break;
5058233facddcc51865d612a919d450db6954aa48e3Michael Kolb                        }
5068233facddcc51865d612a919d450db6954aa48e3Michael Kolb                        break;
5078233facddcc51865d612a919d450db6954aa48e3Michael Kolb                    }
5088233facddcc51865d612a919d450db6954aa48e3Michael Kolb
5098233facddcc51865d612a919d450db6954aa48e3Michael Kolb                    case LOAD_URL:
51026b183292dc087b16af10f482744c3bb30e1f163John Reck                        loadUrlFromContext((String) msg.obj);
5118233facddcc51865d612a919d450db6954aa48e3Michael Kolb                        break;
5128233facddcc51865d612a919d450db6954aa48e3Michael Kolb
5138233facddcc51865d612a919d450db6954aa48e3Michael Kolb                    case STOP_LOAD:
5148233facddcc51865d612a919d450db6954aa48e3Michael Kolb                        stopLoading();
5158233facddcc51865d612a919d450db6954aa48e3Michael Kolb                        break;
5168233facddcc51865d612a919d450db6954aa48e3Michael Kolb
5178233facddcc51865d612a919d450db6954aa48e3Michael Kolb                    case RELEASE_WAKELOCK:
5188233facddcc51865d612a919d450db6954aa48e3Michael Kolb                        if (mWakeLock.isHeld()) {
5198233facddcc51865d612a919d450db6954aa48e3Michael Kolb                            mWakeLock.release();
5208233facddcc51865d612a919d450db6954aa48e3Michael Kolb                            // if we reach here, Browser should be still in the
5218233facddcc51865d612a919d450db6954aa48e3Michael Kolb                            // background loading after WAKELOCK_TIMEOUT (5-min).
5228233facddcc51865d612a919d450db6954aa48e3Michael Kolb                            // To avoid burning the battery, stop loading.
5238233facddcc51865d612a919d450db6954aa48e3Michael Kolb                            mTabControl.stopAllLoading();
5248233facddcc51865d612a919d450db6954aa48e3Michael Kolb                        }
5258233facddcc51865d612a919d450db6954aa48e3Michael Kolb                        break;
5268233facddcc51865d612a919d450db6954aa48e3Michael Kolb
5278233facddcc51865d612a919d450db6954aa48e3Michael Kolb                    case UPDATE_BOOKMARK_THUMBNAIL:
52834ef26756a751b99b5c021ee2b9221c582c88208John Reck                        Tab tab = (Tab) msg.obj;
52934ef26756a751b99b5c021ee2b9221c582c88208John Reck                        if (tab != null) {
53034ef26756a751b99b5c021ee2b9221c582c88208John Reck                            updateScreenshot(tab);
5318233facddcc51865d612a919d450db6954aa48e3Michael Kolb                        }
5328233facddcc51865d612a919d450db6954aa48e3Michael Kolb                        break;
5338233facddcc51865d612a919d450db6954aa48e3Michael Kolb                }
5348233facddcc51865d612a919d450db6954aa48e3Michael Kolb            }
5358233facddcc51865d612a919d450db6954aa48e3Michael Kolb        };
5368233facddcc51865d612a919d450db6954aa48e3Michael Kolb
5378233facddcc51865d612a919d450db6954aa48e3Michael Kolb    }
5388233facddcc51865d612a919d450db6954aa48e3Michael Kolb
539ef654f1dd80f55609060005342fc4f2cde62990cJohn Reck    @Override
540b2f93556ac91fe06eb8f6acab05b6a6d1b2fdbe1Martijn Coenen    public Tab getCurrentTab() {
541b2f93556ac91fe06eb8f6acab05b6a6d1b2fdbe1Martijn Coenen        return mTabControl.getCurrentTab();
542b2f93556ac91fe06eb8f6acab05b6a6d1b2fdbe1Martijn Coenen    }
543b2f93556ac91fe06eb8f6acab05b6a6d1b2fdbe1Martijn Coenen
544ba99c5d1a71c384c930152f7c98e2fbe15bd1e85Michael Kolb    @Override
545ba99c5d1a71c384c930152f7c98e2fbe15bd1e85Michael Kolb    public void shareCurrentPage() {
546ba99c5d1a71c384c930152f7c98e2fbe15bd1e85Michael Kolb        shareCurrentPage(mTabControl.getCurrentTab());
547ba99c5d1a71c384c930152f7c98e2fbe15bd1e85Michael Kolb    }
548ba99c5d1a71c384c930152f7c98e2fbe15bd1e85Michael Kolb
549ba99c5d1a71c384c930152f7c98e2fbe15bd1e85Michael Kolb    private void shareCurrentPage(Tab tab) {
550ba99c5d1a71c384c930152f7c98e2fbe15bd1e85Michael Kolb        if (tab != null) {
551ba99c5d1a71c384c930152f7c98e2fbe15bd1e85Michael Kolb            sharePage(mActivity, tab.getTitle(),
552ba99c5d1a71c384c930152f7c98e2fbe15bd1e85Michael Kolb                    tab.getUrl(), tab.getFavicon(),
553ba99c5d1a71c384c930152f7c98e2fbe15bd1e85Michael Kolb                    createScreenshot(tab.getWebView(),
554ba99c5d1a71c384c930152f7c98e2fbe15bd1e85Michael Kolb                            getDesiredThumbnailWidth(mActivity),
555ba99c5d1a71c384c930152f7c98e2fbe15bd1e85Michael Kolb                            getDesiredThumbnailHeight(mActivity)));
556ba99c5d1a71c384c930152f7c98e2fbe15bd1e85Michael Kolb        }
557ba99c5d1a71c384c930152f7c98e2fbe15bd1e85Michael Kolb    }
558ba99c5d1a71c384c930152f7c98e2fbe15bd1e85Michael Kolb
5598233facddcc51865d612a919d450db6954aa48e3Michael Kolb    /**
5608233facddcc51865d612a919d450db6954aa48e3Michael Kolb     * Share a page, providing the title, url, favicon, and a screenshot.  Uses
5618233facddcc51865d612a919d450db6954aa48e3Michael Kolb     * an {@link Intent} to launch the Activity chooser.
5628233facddcc51865d612a919d450db6954aa48e3Michael Kolb     * @param c Context used to launch a new Activity.
5638233facddcc51865d612a919d450db6954aa48e3Michael Kolb     * @param title Title of the page.  Stored in the Intent with
5648233facddcc51865d612a919d450db6954aa48e3Michael Kolb     *          {@link Intent#EXTRA_SUBJECT}
5658233facddcc51865d612a919d450db6954aa48e3Michael Kolb     * @param url URL of the page.  Stored in the Intent with
5668233facddcc51865d612a919d450db6954aa48e3Michael Kolb     *          {@link Intent#EXTRA_TEXT}
5678233facddcc51865d612a919d450db6954aa48e3Michael Kolb     * @param favicon Bitmap of the favicon for the page.  Stored in the Intent
5688233facddcc51865d612a919d450db6954aa48e3Michael Kolb     *          with {@link Browser#EXTRA_SHARE_FAVICON}
5698233facddcc51865d612a919d450db6954aa48e3Michael Kolb     * @param screenshot Bitmap of a screenshot of the page.  Stored in the
5708233facddcc51865d612a919d450db6954aa48e3Michael Kolb     *          Intent with {@link Browser#EXTRA_SHARE_SCREENSHOT}
5718233facddcc51865d612a919d450db6954aa48e3Michael Kolb     */
5728233facddcc51865d612a919d450db6954aa48e3Michael Kolb    static final void sharePage(Context c, String title, String url,
5738233facddcc51865d612a919d450db6954aa48e3Michael Kolb            Bitmap favicon, Bitmap screenshot) {
5748233facddcc51865d612a919d450db6954aa48e3Michael Kolb        Intent send = new Intent(Intent.ACTION_SEND);
5758233facddcc51865d612a919d450db6954aa48e3Michael Kolb        send.setType("text/plain");
5768233facddcc51865d612a919d450db6954aa48e3Michael Kolb        send.putExtra(Intent.EXTRA_TEXT, url);
5778233facddcc51865d612a919d450db6954aa48e3Michael Kolb        send.putExtra(Intent.EXTRA_SUBJECT, title);
5788233facddcc51865d612a919d450db6954aa48e3Michael Kolb        send.putExtra(Browser.EXTRA_SHARE_FAVICON, favicon);
5798233facddcc51865d612a919d450db6954aa48e3Michael Kolb        send.putExtra(Browser.EXTRA_SHARE_SCREENSHOT, screenshot);
5808233facddcc51865d612a919d450db6954aa48e3Michael Kolb        try {
5818233facddcc51865d612a919d450db6954aa48e3Michael Kolb            c.startActivity(Intent.createChooser(send, c.getString(
5828233facddcc51865d612a919d450db6954aa48e3Michael Kolb                    R.string.choosertitle_sharevia)));
5838233facddcc51865d612a919d450db6954aa48e3Michael Kolb        } catch(android.content.ActivityNotFoundException ex) {
5848233facddcc51865d612a919d450db6954aa48e3Michael Kolb            // if no app handles it, do nothing
5858233facddcc51865d612a919d450db6954aa48e3Michael Kolb        }
5868233facddcc51865d612a919d450db6954aa48e3Michael Kolb    }
5878233facddcc51865d612a919d450db6954aa48e3Michael Kolb
5888233facddcc51865d612a919d450db6954aa48e3Michael Kolb    private void copy(CharSequence text) {
5898233facddcc51865d612a919d450db6954aa48e3Michael Kolb        ClipboardManager cm = (ClipboardManager) mActivity
5908233facddcc51865d612a919d450db6954aa48e3Michael Kolb                .getSystemService(Context.CLIPBOARD_SERVICE);
5918233facddcc51865d612a919d450db6954aa48e3Michael Kolb        cm.setText(text);
5928233facddcc51865d612a919d450db6954aa48e3Michael Kolb    }
5938233facddcc51865d612a919d450db6954aa48e3Michael Kolb
5948233facddcc51865d612a919d450db6954aa48e3Michael Kolb    // lifecycle
5958233facddcc51865d612a919d450db6954aa48e3Michael Kolb
5968233facddcc51865d612a919d450db6954aa48e3Michael Kolb    protected void onConfgurationChanged(Configuration config) {
5978233facddcc51865d612a919d450db6954aa48e3Michael Kolb        mConfigChanged = true;
5988233facddcc51865d612a919d450db6954aa48e3Michael Kolb        if (mPageDialogsHandler != null) {
5998233facddcc51865d612a919d450db6954aa48e3Michael Kolb            mPageDialogsHandler.onConfigurationChanged(config);
6008233facddcc51865d612a919d450db6954aa48e3Michael Kolb        }
6018233facddcc51865d612a919d450db6954aa48e3Michael Kolb        mUi.onConfigurationChanged(config);
6028233facddcc51865d612a919d450db6954aa48e3Michael Kolb    }
6038233facddcc51865d612a919d450db6954aa48e3Michael Kolb
6048233facddcc51865d612a919d450db6954aa48e3Michael Kolb    @Override
6058233facddcc51865d612a919d450db6954aa48e3Michael Kolb    public void handleNewIntent(Intent intent) {
6068233facddcc51865d612a919d450db6954aa48e3Michael Kolb        mIntentHandler.onNewIntent(intent);
6078233facddcc51865d612a919d450db6954aa48e3Michael Kolb    }
6088233facddcc51865d612a919d450db6954aa48e3Michael Kolb
6098233facddcc51865d612a919d450db6954aa48e3Michael Kolb    protected void onPause() {
61011fe02d7b0a9956284fc0677b84b5fdacdd668e8Michael Kolb        if (mUi.isCustomViewShowing()) {
61111fe02d7b0a9956284fc0677b84b5fdacdd668e8Michael Kolb            hideCustomView();
61211fe02d7b0a9956284fc0677b84b5fdacdd668e8Michael Kolb        }
6138233facddcc51865d612a919d450db6954aa48e3Michael Kolb        if (mActivityPaused) {
6148233facddcc51865d612a919d450db6954aa48e3Michael Kolb            Log.e(LOGTAG, "BrowserActivity is already paused.");
6158233facddcc51865d612a919d450db6954aa48e3Michael Kolb            return;
6168233facddcc51865d612a919d450db6954aa48e3Michael Kolb        }
6178233facddcc51865d612a919d450db6954aa48e3Michael Kolb        mActivityPaused = true;
61870976938146d1b13b9e183ceec41edce50c5d6afMichael Kolb        Tab tab = mTabControl.getCurrentTab();
61970976938146d1b13b9e183ceec41edce50c5d6afMichael Kolb        if (tab != null) {
62070976938146d1b13b9e183ceec41edce50c5d6afMichael Kolb            tab.pause();
62170976938146d1b13b9e183ceec41edce50c5d6afMichael Kolb            if (!pauseWebViewTimers(tab)) {
62270976938146d1b13b9e183ceec41edce50c5d6afMichael Kolb                mWakeLock.acquire();
62370976938146d1b13b9e183ceec41edce50c5d6afMichael Kolb                mHandler.sendMessageDelayed(mHandler
62470976938146d1b13b9e183ceec41edce50c5d6afMichael Kolb                        .obtainMessage(RELEASE_WAKELOCK), WAKELOCK_TIMEOUT);
62570976938146d1b13b9e183ceec41edce50c5d6afMichael Kolb            }
6268233facddcc51865d612a919d450db6954aa48e3Michael Kolb        }
6278233facddcc51865d612a919d450db6954aa48e3Michael Kolb        mUi.onPause();
6288233facddcc51865d612a919d450db6954aa48e3Michael Kolb        mNetworkHandler.onPause();
629b2f93556ac91fe06eb8f6acab05b6a6d1b2fdbe1Martijn Coenen        mNfcHandler.onPause();
6308233facddcc51865d612a919d450db6954aa48e3Michael Kolb
6318233facddcc51865d612a919d450db6954aa48e3Michael Kolb        WebView.disablePlatformNotifications();
632378a41055fab6c521cdc1d9b2cfeefff2af19e7cJohn Reck        mCrashRecoveryHandler.backupState();
633b2f93556ac91fe06eb8f6acab05b6a6d1b2fdbe1Martijn Coenen
6348233facddcc51865d612a919d450db6954aa48e3Michael Kolb    }
6358233facddcc51865d612a919d450db6954aa48e3Michael Kolb
636aed9c54d8e67bb683a5a415b3775525a3ac00508John Reck    void onSaveInstanceState(Bundle outState, boolean saveImages) {
6378233facddcc51865d612a919d450db6954aa48e3Michael Kolb        // the default implementation requires each view to have an id. As the
6388233facddcc51865d612a919d450db6954aa48e3Michael Kolb        // browser handles the state itself and it doesn't use id for the views,
6398233facddcc51865d612a919d450db6954aa48e3Michael Kolb        // don't call the default implementation. Otherwise it will trigger the
6408233facddcc51865d612a919d450db6954aa48e3Michael Kolb        // warning like this, "couldn't save which view has focus because the
6418233facddcc51865d612a919d450db6954aa48e3Michael Kolb        // focused view XXX has no id".
6428233facddcc51865d612a919d450db6954aa48e3Michael Kolb
6438233facddcc51865d612a919d450db6954aa48e3Michael Kolb        // Save all the tabs
644aed9c54d8e67bb683a5a415b3775525a3ac00508John Reck        mTabControl.saveState(outState, saveImages);
64524f1826440334ba8a3d2453699c51c1a4b117c7bJohn Reck        if (!outState.isEmpty()) {
64624f1826440334ba8a3d2453699c51c1a4b117c7bJohn Reck            // Save time so that we know how old incognito tabs (if any) are.
64724f1826440334ba8a3d2453699c51c1a4b117c7bJohn Reck            outState.putSerializable("lastActiveDate", Calendar.getInstance());
64824f1826440334ba8a3d2453699c51c1a4b117c7bJohn Reck        }
6498233facddcc51865d612a919d450db6954aa48e3Michael Kolb    }
6508233facddcc51865d612a919d450db6954aa48e3Michael Kolb
6518233facddcc51865d612a919d450db6954aa48e3Michael Kolb    void onResume() {
6528233facddcc51865d612a919d450db6954aa48e3Michael Kolb        if (!mActivityPaused) {
6538233facddcc51865d612a919d450db6954aa48e3Michael Kolb            Log.e(LOGTAG, "BrowserActivity is already resumed.");
6548233facddcc51865d612a919d450db6954aa48e3Michael Kolb            return;
6558233facddcc51865d612a919d450db6954aa48e3Michael Kolb        }
6568233facddcc51865d612a919d450db6954aa48e3Michael Kolb        mActivityPaused = false;
65770976938146d1b13b9e183ceec41edce50c5d6afMichael Kolb        Tab current = mTabControl.getCurrentTab();
65870976938146d1b13b9e183ceec41edce50c5d6afMichael Kolb        if (current != null) {
65970976938146d1b13b9e183ceec41edce50c5d6afMichael Kolb            current.resume();
66070976938146d1b13b9e183ceec41edce50c5d6afMichael Kolb            resumeWebViewTimers(current);
66170976938146d1b13b9e183ceec41edce50c5d6afMichael Kolb        }
6628233facddcc51865d612a919d450db6954aa48e3Michael Kolb        if (mWakeLock.isHeld()) {
6638233facddcc51865d612a919d450db6954aa48e3Michael Kolb            mHandler.removeMessages(RELEASE_WAKELOCK);
6648233facddcc51865d612a919d450db6954aa48e3Michael Kolb            mWakeLock.release();
6658233facddcc51865d612a919d450db6954aa48e3Michael Kolb        }
666b2f93556ac91fe06eb8f6acab05b6a6d1b2fdbe1Martijn Coenen
6678233facddcc51865d612a919d450db6954aa48e3Michael Kolb        mUi.onResume();
6688233facddcc51865d612a919d450db6954aa48e3Michael Kolb        mNetworkHandler.onResume();
669b2f93556ac91fe06eb8f6acab05b6a6d1b2fdbe1Martijn Coenen        mNfcHandler.onResume();
6708233facddcc51865d612a919d450db6954aa48e3Michael Kolb        WebView.enablePlatformNotifications();
6718233facddcc51865d612a919d450db6954aa48e3Michael Kolb    }
6728233facddcc51865d612a919d450db6954aa48e3Michael Kolb
67370976938146d1b13b9e183ceec41edce50c5d6afMichael Kolb    /**
674ba99c5d1a71c384c930152f7c98e2fbe15bd1e85Michael Kolb     * resume all WebView timers using the WebView instance of the given tab
67570976938146d1b13b9e183ceec41edce50c5d6afMichael Kolb     * @param tab guaranteed non-null
67670976938146d1b13b9e183ceec41edce50c5d6afMichael Kolb     */
67770976938146d1b13b9e183ceec41edce50c5d6afMichael Kolb    private void resumeWebViewTimers(Tab tab) {
6788233facddcc51865d612a919d450db6954aa48e3Michael Kolb        boolean inLoad = tab.inPageLoad();
6798233facddcc51865d612a919d450db6954aa48e3Michael Kolb        if ((!mActivityPaused && !inLoad) || (mActivityPaused && inLoad)) {
6808233facddcc51865d612a919d450db6954aa48e3Michael Kolb            CookieSyncManager.getInstance().startSync();
6818233facddcc51865d612a919d450db6954aa48e3Michael Kolb            WebView w = tab.getWebView();
682e1dbb956d762c3f07033f247c05270a9882a79a7Mathew Inwood            WebViewTimersControl.getInstance().onBrowserActivityResume(w);
6838233facddcc51865d612a919d450db6954aa48e3Michael Kolb        }
6848233facddcc51865d612a919d450db6954aa48e3Michael Kolb    }
6858233facddcc51865d612a919d450db6954aa48e3Michael Kolb
68670976938146d1b13b9e183ceec41edce50c5d6afMichael Kolb    /**
68770976938146d1b13b9e183ceec41edce50c5d6afMichael Kolb     * Pause all WebView timers using the WebView of the given tab
68870976938146d1b13b9e183ceec41edce50c5d6afMichael Kolb     * @param tab
68970976938146d1b13b9e183ceec41edce50c5d6afMichael Kolb     * @return true if the timers are paused or tab is null
69070976938146d1b13b9e183ceec41edce50c5d6afMichael Kolb     */
69170976938146d1b13b9e183ceec41edce50c5d6afMichael Kolb    private boolean pauseWebViewTimers(Tab tab) {
69270976938146d1b13b9e183ceec41edce50c5d6afMichael Kolb        if (tab == null) {
69370976938146d1b13b9e183ceec41edce50c5d6afMichael Kolb            return true;
69470976938146d1b13b9e183ceec41edce50c5d6afMichael Kolb        } else if (!tab.inPageLoad()) {
6958233facddcc51865d612a919d450db6954aa48e3Michael Kolb            CookieSyncManager.getInstance().stopSync();
696e1dbb956d762c3f07033f247c05270a9882a79a7Mathew Inwood            WebViewTimersControl.getInstance().onBrowserActivityPause(getCurrentWebView());
6978233facddcc51865d612a919d450db6954aa48e3Michael Kolb            return true;
6988233facddcc51865d612a919d450db6954aa48e3Michael Kolb        }
69970976938146d1b13b9e183ceec41edce50c5d6afMichael Kolb        return false;
7008233facddcc51865d612a919d450db6954aa48e3Michael Kolb    }
7018233facddcc51865d612a919d450db6954aa48e3Michael Kolb
7028233facddcc51865d612a919d450db6954aa48e3Michael Kolb    void onDestroy() {
70338b4bf5f9cbb6adf2c5ca353e3b0c2a4ae9eeb87John Reck        if (mUploadHandler != null && !mUploadHandler.handled()) {
7048233facddcc51865d612a919d450db6954aa48e3Michael Kolb            mUploadHandler.onResult(Activity.RESULT_CANCELED, null);
7058233facddcc51865d612a919d450db6954aa48e3Michael Kolb            mUploadHandler = null;
7068233facddcc51865d612a919d450db6954aa48e3Michael Kolb        }
7078233facddcc51865d612a919d450db6954aa48e3Michael Kolb        if (mTabControl == null) return;
7088233facddcc51865d612a919d450db6954aa48e3Michael Kolb        mUi.onDestroy();
7098233facddcc51865d612a919d450db6954aa48e3Michael Kolb        // Remove the current tab and sub window
7108233facddcc51865d612a919d450db6954aa48e3Michael Kolb        Tab t = mTabControl.getCurrentTab();
7118233facddcc51865d612a919d450db6954aa48e3Michael Kolb        if (t != null) {
7128233facddcc51865d612a919d450db6954aa48e3Michael Kolb            dismissSubWindow(t);
7138233facddcc51865d612a919d450db6954aa48e3Michael Kolb            removeTab(t);
7148233facddcc51865d612a919d450db6954aa48e3Michael Kolb        }
7151961ed2f2856ca0993c8c4d15924bbb4e4ef98c0Leon Scroggins        mActivity.getContentResolver().unregisterContentObserver(mBookmarksObserver);
7168233facddcc51865d612a919d450db6954aa48e3Michael Kolb        // Destroy all the tabs
7178233facddcc51865d612a919d450db6954aa48e3Michael Kolb        mTabControl.destroy();
7188233facddcc51865d612a919d450db6954aa48e3Michael Kolb        WebIconDatabase.getInstance().close();
7198233facddcc51865d612a919d450db6954aa48e3Michael Kolb        // Stop watching the default geolocation permissions
7208233facddcc51865d612a919d450db6954aa48e3Michael Kolb        mSystemAllowGeolocationOrigins.stop();
7218233facddcc51865d612a919d450db6954aa48e3Michael Kolb        mSystemAllowGeolocationOrigins = null;
7228233facddcc51865d612a919d450db6954aa48e3Michael Kolb    }
7238233facddcc51865d612a919d450db6954aa48e3Michael Kolb
7248233facddcc51865d612a919d450db6954aa48e3Michael Kolb    protected boolean isActivityPaused() {
7258233facddcc51865d612a919d450db6954aa48e3Michael Kolb        return mActivityPaused;
7268233facddcc51865d612a919d450db6954aa48e3Michael Kolb    }
7278233facddcc51865d612a919d450db6954aa48e3Michael Kolb
7288233facddcc51865d612a919d450db6954aa48e3Michael Kolb    protected void onLowMemory() {
7298233facddcc51865d612a919d450db6954aa48e3Michael Kolb        mTabControl.freeMemory();
7308233facddcc51865d612a919d450db6954aa48e3Michael Kolb    }
7318233facddcc51865d612a919d450db6954aa48e3Michael Kolb
7328233facddcc51865d612a919d450db6954aa48e3Michael Kolb    @Override
7338233facddcc51865d612a919d450db6954aa48e3Michael Kolb    public boolean shouldShowErrorConsole() {
7348233facddcc51865d612a919d450db6954aa48e3Michael Kolb        return mShouldShowErrorConsole;
7358233facddcc51865d612a919d450db6954aa48e3Michael Kolb    }
7368233facddcc51865d612a919d450db6954aa48e3Michael Kolb
7378233facddcc51865d612a919d450db6954aa48e3Michael Kolb    protected void setShouldShowErrorConsole(boolean show) {
7388233facddcc51865d612a919d450db6954aa48e3Michael Kolb        if (show == mShouldShowErrorConsole) {
7398233facddcc51865d612a919d450db6954aa48e3Michael Kolb            // Nothing to do.
7408233facddcc51865d612a919d450db6954aa48e3Michael Kolb            return;
7418233facddcc51865d612a919d450db6954aa48e3Michael Kolb        }
7428233facddcc51865d612a919d450db6954aa48e3Michael Kolb        mShouldShowErrorConsole = show;
7438233facddcc51865d612a919d450db6954aa48e3Michael Kolb        Tab t = mTabControl.getCurrentTab();
7448233facddcc51865d612a919d450db6954aa48e3Michael Kolb        if (t == null) {
7458233facddcc51865d612a919d450db6954aa48e3Michael Kolb            // There is no current tab so we cannot toggle the error console
7468233facddcc51865d612a919d450db6954aa48e3Michael Kolb            return;
7478233facddcc51865d612a919d450db6954aa48e3Michael Kolb        }
7488233facddcc51865d612a919d450db6954aa48e3Michael Kolb        mUi.setShouldShowErrorConsole(t, show);
7498233facddcc51865d612a919d450db6954aa48e3Michael Kolb    }
7508233facddcc51865d612a919d450db6954aa48e3Michael Kolb
7518233facddcc51865d612a919d450db6954aa48e3Michael Kolb    @Override
7528233facddcc51865d612a919d450db6954aa48e3Michael Kolb    public void stopLoading() {
7538233facddcc51865d612a919d450db6954aa48e3Michael Kolb        mLoadStopped = true;
7548233facddcc51865d612a919d450db6954aa48e3Michael Kolb        Tab tab = mTabControl.getCurrentTab();
7558233facddcc51865d612a919d450db6954aa48e3Michael Kolb        WebView w = getCurrentTopWebView();
7568233facddcc51865d612a919d450db6954aa48e3Michael Kolb        w.stopLoading();
7578233facddcc51865d612a919d450db6954aa48e3Michael Kolb        mUi.onPageStopped(tab);
7588233facddcc51865d612a919d450db6954aa48e3Michael Kolb    }
7598233facddcc51865d612a919d450db6954aa48e3Michael Kolb
7608233facddcc51865d612a919d450db6954aa48e3Michael Kolb    boolean didUserStopLoading() {
7618233facddcc51865d612a919d450db6954aa48e3Michael Kolb        return mLoadStopped;
7628233facddcc51865d612a919d450db6954aa48e3Michael Kolb    }
7638233facddcc51865d612a919d450db6954aa48e3Michael Kolb
7648233facddcc51865d612a919d450db6954aa48e3Michael Kolb    // WebViewController
7658233facddcc51865d612a919d450db6954aa48e3Michael Kolb
7668233facddcc51865d612a919d450db6954aa48e3Michael Kolb    @Override
767324d440ea7dc44da8beef8a6c2e6f7a33b20a41dJohn Reck    public void onPageStarted(Tab tab, WebView view, Bitmap favicon) {
7688233facddcc51865d612a919d450db6954aa48e3Michael Kolb
7698233facddcc51865d612a919d450db6954aa48e3Michael Kolb        // We've started to load a new page. If there was a pending message
7708233facddcc51865d612a919d450db6954aa48e3Michael Kolb        // to save a screenshot then we will now take the new page and save
7718233facddcc51865d612a919d450db6954aa48e3Michael Kolb        // an incorrect screenshot. Therefore, remove any pending thumbnail
7728233facddcc51865d612a919d450db6954aa48e3Michael Kolb        // messages from the queue.
7738233facddcc51865d612a919d450db6954aa48e3Michael Kolb        mHandler.removeMessages(Controller.UPDATE_BOOKMARK_THUMBNAIL,
77434ef26756a751b99b5c021ee2b9221c582c88208John Reck                tab);
7758233facddcc51865d612a919d450db6954aa48e3Michael Kolb
7768233facddcc51865d612a919d450db6954aa48e3Michael Kolb        // reset sync timer to avoid sync starts during loading a page
7778233facddcc51865d612a919d450db6954aa48e3Michael Kolb        CookieSyncManager.getInstance().resetSync();
7788233facddcc51865d612a919d450db6954aa48e3Michael Kolb
7798233facddcc51865d612a919d450db6954aa48e3Michael Kolb        if (!mNetworkHandler.isNetworkUp()) {
7808233facddcc51865d612a919d450db6954aa48e3Michael Kolb            view.setNetworkAvailable(false);
7818233facddcc51865d612a919d450db6954aa48e3Michael Kolb        }
7828233facddcc51865d612a919d450db6954aa48e3Michael Kolb
7838233facddcc51865d612a919d450db6954aa48e3Michael Kolb        // when BrowserActivity just starts, onPageStarted may be called before
7848233facddcc51865d612a919d450db6954aa48e3Michael Kolb        // onResume as it is triggered from onCreate. Call resumeWebViewTimers
7858233facddcc51865d612a919d450db6954aa48e3Michael Kolb        // to start the timer. As we won't switch tabs while an activity is in
7868233facddcc51865d612a919d450db6954aa48e3Michael Kolb        // pause state, we can ensure calling resume and pause in pair.
7878233facddcc51865d612a919d450db6954aa48e3Michael Kolb        if (mActivityPaused) {
78870976938146d1b13b9e183ceec41edce50c5d6afMichael Kolb            resumeWebViewTimers(tab);
7898233facddcc51865d612a919d450db6954aa48e3Michael Kolb        }
7908233facddcc51865d612a919d450db6954aa48e3Michael Kolb        mLoadStopped = false;
7918233facddcc51865d612a919d450db6954aa48e3Michael Kolb        if (!mNetworkHandler.isNetworkUp()) {
7928233facddcc51865d612a919d450db6954aa48e3Michael Kolb            mNetworkHandler.createAndShowNetworkDialog();
7938233facddcc51865d612a919d450db6954aa48e3Michael Kolb        }
7948233facddcc51865d612a919d450db6954aa48e3Michael Kolb        endActionMode();
7958233facddcc51865d612a919d450db6954aa48e3Michael Kolb
79630c714c853a4239e72ab1e238ce2a92472d06ab0John Reck        mUi.onTabDataChanged(tab);
7978233facddcc51865d612a919d450db6954aa48e3Michael Kolb
798324d440ea7dc44da8beef8a6c2e6f7a33b20a41dJohn Reck        String url = tab.getUrl();
7998233facddcc51865d612a919d450db6954aa48e3Michael Kolb        // update the bookmark database for favicon
8008233facddcc51865d612a919d450db6954aa48e3Michael Kolb        maybeUpdateFavicon(tab, null, url, favicon);
8018233facddcc51865d612a919d450db6954aa48e3Michael Kolb
8028233facddcc51865d612a919d450db6954aa48e3Michael Kolb        Performance.tracePageStart(url);
8038233facddcc51865d612a919d450db6954aa48e3Michael Kolb
8048233facddcc51865d612a919d450db6954aa48e3Michael Kolb        // Performance probe
8058233facddcc51865d612a919d450db6954aa48e3Michael Kolb        if (false) {
8068233facddcc51865d612a919d450db6954aa48e3Michael Kolb            Performance.onPageStarted();
8078233facddcc51865d612a919d450db6954aa48e3Michael Kolb        }
8088233facddcc51865d612a919d450db6954aa48e3Michael Kolb
8098233facddcc51865d612a919d450db6954aa48e3Michael Kolb    }
8108233facddcc51865d612a919d450db6954aa48e3Michael Kolb
8118233facddcc51865d612a919d450db6954aa48e3Michael Kolb    @Override
812324d440ea7dc44da8beef8a6c2e6f7a33b20a41dJohn Reck    public void onPageFinished(Tab tab) {
81330c714c853a4239e72ab1e238ce2a92472d06ab0John Reck        mUi.onTabDataChanged(tab);
814324d440ea7dc44da8beef8a6c2e6f7a33b20a41dJohn Reck        if (!tab.isPrivateBrowsingEnabled()
815d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck                && !TextUtils.isEmpty(tab.getUrl())
816d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck                && !tab.isSnapshot()) {
817a169628f9424256e5bcf45807869c4c4eaa114c0John Reck            // Only update the bookmark screenshot if the user did not
818a169628f9424256e5bcf45807869c4c4eaa114c0John Reck            // cancel the load early and there is not already
819a169628f9424256e5bcf45807869c4c4eaa114c0John Reck            // a pending update for the tab.
8208233facddcc51865d612a919d450db6954aa48e3Michael Kolb            if (tab.inForeground() && !didUserStopLoading()
8218233facddcc51865d612a919d450db6954aa48e3Michael Kolb                    || !tab.inForeground()) {
822a169628f9424256e5bcf45807869c4c4eaa114c0John Reck                if (!mHandler.hasMessages(UPDATE_BOOKMARK_THUMBNAIL, tab)) {
823a169628f9424256e5bcf45807869c4c4eaa114c0John Reck                    mHandler.sendMessageDelayed(mHandler.obtainMessage(
824a169628f9424256e5bcf45807869c4c4eaa114c0John Reck                            UPDATE_BOOKMARK_THUMBNAIL, 0, 0, tab),
825a169628f9424256e5bcf45807869c4c4eaa114c0John Reck                            500);
826a169628f9424256e5bcf45807869c4c4eaa114c0John Reck                }
8278233facddcc51865d612a919d450db6954aa48e3Michael Kolb            }
8288233facddcc51865d612a919d450db6954aa48e3Michael Kolb        }
8298233facddcc51865d612a919d450db6954aa48e3Michael Kolb        // pause the WebView timer and release the wake lock if it is finished
8308233facddcc51865d612a919d450db6954aa48e3Michael Kolb        // while BrowserActivity is in pause state.
83170976938146d1b13b9e183ceec41edce50c5d6afMichael Kolb        if (mActivityPaused && pauseWebViewTimers(tab)) {
8328233facddcc51865d612a919d450db6954aa48e3Michael Kolb            if (mWakeLock.isHeld()) {
8338233facddcc51865d612a919d450db6954aa48e3Michael Kolb                mHandler.removeMessages(RELEASE_WAKELOCK);
8348233facddcc51865d612a919d450db6954aa48e3Michael Kolb                mWakeLock.release();
8358233facddcc51865d612a919d450db6954aa48e3Michael Kolb            }
8368233facddcc51865d612a919d450db6954aa48e3Michael Kolb        }
837b2f93556ac91fe06eb8f6acab05b6a6d1b2fdbe1Martijn Coenen
8388233facddcc51865d612a919d450db6954aa48e3Michael Kolb        // Performance probe
8398233facddcc51865d612a919d450db6954aa48e3Michael Kolb        if (false) {
840324d440ea7dc44da8beef8a6c2e6f7a33b20a41dJohn Reck            Performance.onPageFinished(tab.getUrl());
8418233facddcc51865d612a919d450db6954aa48e3Michael Kolb         }
8428233facddcc51865d612a919d450db6954aa48e3Michael Kolb
8438233facddcc51865d612a919d450db6954aa48e3Michael Kolb        Performance.tracePageFinished();
8448233facddcc51865d612a919d450db6954aa48e3Michael Kolb    }
8458233facddcc51865d612a919d450db6954aa48e3Michael Kolb
8468233facddcc51865d612a919d450db6954aa48e3Michael Kolb    @Override
84730c714c853a4239e72ab1e238ce2a92472d06ab0John Reck    public void onProgressChanged(Tab tab) {
84830c714c853a4239e72ab1e238ce2a92472d06ab0John Reck        int newProgress = tab.getLoadProgress();
8498233facddcc51865d612a919d450db6954aa48e3Michael Kolb
8508233facddcc51865d612a919d450db6954aa48e3Michael Kolb        if (newProgress == 100) {
8518233facddcc51865d612a919d450db6954aa48e3Michael Kolb            CookieSyncManager.getInstance().sync();
8528233facddcc51865d612a919d450db6954aa48e3Michael Kolb            // onProgressChanged() may continue to be called after the main
8538233facddcc51865d612a919d450db6954aa48e3Michael Kolb            // frame has finished loading, as any remaining sub frames continue
8548233facddcc51865d612a919d450db6954aa48e3Michael Kolb            // to load. We'll only get called once though with newProgress as
8558233facddcc51865d612a919d450db6954aa48e3Michael Kolb            // 100 when everything is loaded. (onPageFinished is called once
8568233facddcc51865d612a919d450db6954aa48e3Michael Kolb            // when the main frame completes loading regardless of the state of
8578233facddcc51865d612a919d450db6954aa48e3Michael Kolb            // any sub frames so calls to onProgressChanges may continue after
8588233facddcc51865d612a919d450db6954aa48e3Michael Kolb            // onPageFinished has executed)
8598233facddcc51865d612a919d450db6954aa48e3Michael Kolb            if (mInLoad) {
8608233facddcc51865d612a919d450db6954aa48e3Michael Kolb                mInLoad = false;
8618233facddcc51865d612a919d450db6954aa48e3Michael Kolb                updateInLoadMenuItems(mCachedMenu);
8628233facddcc51865d612a919d450db6954aa48e3Michael Kolb            }
8638233facddcc51865d612a919d450db6954aa48e3Michael Kolb        } else {
8648233facddcc51865d612a919d450db6954aa48e3Michael Kolb            if (!mInLoad) {
8658233facddcc51865d612a919d450db6954aa48e3Michael Kolb                // onPageFinished may have already been called but a subframe is
8668233facddcc51865d612a919d450db6954aa48e3Michael Kolb                // still loading and updating the progress. Reset mInLoad and
8678233facddcc51865d612a919d450db6954aa48e3Michael Kolb                // update the menu items.
8688233facddcc51865d612a919d450db6954aa48e3Michael Kolb                mInLoad = true;
8698233facddcc51865d612a919d450db6954aa48e3Michael Kolb                updateInLoadMenuItems(mCachedMenu);
8708233facddcc51865d612a919d450db6954aa48e3Michael Kolb            }
8718233facddcc51865d612a919d450db6954aa48e3Michael Kolb        }
87230c714c853a4239e72ab1e238ce2a92472d06ab0John Reck        mUi.onProgressChanged(tab);
87330c714c853a4239e72ab1e238ce2a92472d06ab0John Reck    }
87430c714c853a4239e72ab1e238ce2a92472d06ab0John Reck
87530c714c853a4239e72ab1e238ce2a92472d06ab0John Reck    @Override
87630c714c853a4239e72ab1e238ce2a92472d06ab0John Reck    public void onUpdatedLockIcon(Tab tab) {
87730c714c853a4239e72ab1e238ce2a92472d06ab0John Reck        mUi.onTabDataChanged(tab);
8788233facddcc51865d612a919d450db6954aa48e3Michael Kolb    }
8798233facddcc51865d612a919d450db6954aa48e3Michael Kolb
8808233facddcc51865d612a919d450db6954aa48e3Michael Kolb    @Override
8818233facddcc51865d612a919d450db6954aa48e3Michael Kolb    public void onReceivedTitle(Tab tab, final String title) {
88230c714c853a4239e72ab1e238ce2a92472d06ab0John Reck        mUi.onTabDataChanged(tab);
88349a603c11b00b6e68a54e070abf4eb33eaddfa84John Reck        final String pageUrl = tab.getOriginalUrl();
884324d440ea7dc44da8beef8a6c2e6f7a33b20a41dJohn Reck        if (TextUtils.isEmpty(pageUrl) || pageUrl.length()
8858233facddcc51865d612a919d450db6954aa48e3Michael Kolb                >= SQLiteDatabase.SQLITE_MAX_LIKE_PATTERN_LENGTH) {
8868233facddcc51865d612a919d450db6954aa48e3Michael Kolb            return;
8878233facddcc51865d612a919d450db6954aa48e3Michael Kolb        }
8888233facddcc51865d612a919d450db6954aa48e3Michael Kolb        // Update the title in the history database if not in private browsing mode
8898233facddcc51865d612a919d450db6954aa48e3Michael Kolb        if (!tab.isPrivateBrowsingEnabled()) {
8900ebd3ac69a76ec76d9caab65a1947f971242994eJohn Reck            mDataController.updateHistoryTitle(pageUrl, title);
8918233facddcc51865d612a919d450db6954aa48e3Michael Kolb        }
8928233facddcc51865d612a919d450db6954aa48e3Michael Kolb    }
8938233facddcc51865d612a919d450db6954aa48e3Michael Kolb
8948233facddcc51865d612a919d450db6954aa48e3Michael Kolb    @Override
8958233facddcc51865d612a919d450db6954aa48e3Michael Kolb    public void onFavicon(Tab tab, WebView view, Bitmap icon) {
89630c714c853a4239e72ab1e238ce2a92472d06ab0John Reck        mUi.onTabDataChanged(tab);
8978233facddcc51865d612a919d450db6954aa48e3Michael Kolb        maybeUpdateFavicon(tab, view.getOriginalUrl(), view.getUrl(), icon);
8988233facddcc51865d612a919d450db6954aa48e3Michael Kolb    }
8998233facddcc51865d612a919d450db6954aa48e3Michael Kolb
9008233facddcc51865d612a919d450db6954aa48e3Michael Kolb    @Override
90118eb377badf8e6f9ea2925bcb7e978facf3171d9Michael Kolb    public boolean shouldOverrideUrlLoading(Tab tab, WebView view, String url) {
90218eb377badf8e6f9ea2925bcb7e978facf3171d9Michael Kolb        return mUrlHandler.shouldOverrideUrlLoading(tab, view, url);
9038233facddcc51865d612a919d450db6954aa48e3Michael Kolb    }
9048233facddcc51865d612a919d450db6954aa48e3Michael Kolb
9058233facddcc51865d612a919d450db6954aa48e3Michael Kolb    @Override
9068233facddcc51865d612a919d450db6954aa48e3Michael Kolb    public boolean shouldOverrideKeyEvent(KeyEvent event) {
9078233facddcc51865d612a919d450db6954aa48e3Michael Kolb        if (mMenuIsDown) {
9088233facddcc51865d612a919d450db6954aa48e3Michael Kolb            // only check shortcut key when MENU is held
9098233facddcc51865d612a919d450db6954aa48e3Michael Kolb            return mActivity.getWindow().isShortcutKey(event.getKeyCode(),
9108233facddcc51865d612a919d450db6954aa48e3Michael Kolb                    event);
9118233facddcc51865d612a919d450db6954aa48e3Michael Kolb        } else {
9128233facddcc51865d612a919d450db6954aa48e3Michael Kolb            return false;
9138233facddcc51865d612a919d450db6954aa48e3Michael Kolb        }
9148233facddcc51865d612a919d450db6954aa48e3Michael Kolb    }
9158233facddcc51865d612a919d450db6954aa48e3Michael Kolb
9168233facddcc51865d612a919d450db6954aa48e3Michael Kolb    @Override
9178233facddcc51865d612a919d450db6954aa48e3Michael Kolb    public void onUnhandledKeyEvent(KeyEvent event) {
9188233facddcc51865d612a919d450db6954aa48e3Michael Kolb        if (!isActivityPaused()) {
9198233facddcc51865d612a919d450db6954aa48e3Michael Kolb            if (event.getAction() == KeyEvent.ACTION_DOWN) {
9208233facddcc51865d612a919d450db6954aa48e3Michael Kolb                mActivity.onKeyDown(event.getKeyCode(), event);
9218233facddcc51865d612a919d450db6954aa48e3Michael Kolb            } else {
9228233facddcc51865d612a919d450db6954aa48e3Michael Kolb                mActivity.onKeyUp(event.getKeyCode(), event);
9238233facddcc51865d612a919d450db6954aa48e3Michael Kolb            }
9248233facddcc51865d612a919d450db6954aa48e3Michael Kolb        }
9258233facddcc51865d612a919d450db6954aa48e3Michael Kolb    }
9268233facddcc51865d612a919d450db6954aa48e3Michael Kolb
9278233facddcc51865d612a919d450db6954aa48e3Michael Kolb    @Override
928324d440ea7dc44da8beef8a6c2e6f7a33b20a41dJohn Reck    public void doUpdateVisitedHistory(Tab tab, boolean isReload) {
9298233facddcc51865d612a919d450db6954aa48e3Michael Kolb        // Don't save anything in private browsing mode
9308233facddcc51865d612a919d450db6954aa48e3Michael Kolb        if (tab.isPrivateBrowsingEnabled()) return;
93149a603c11b00b6e68a54e070abf4eb33eaddfa84John Reck        String url = tab.getOriginalUrl();
9328233facddcc51865d612a919d450db6954aa48e3Michael Kolb
933324d440ea7dc44da8beef8a6c2e6f7a33b20a41dJohn Reck        if (TextUtils.isEmpty(url)
934324d440ea7dc44da8beef8a6c2e6f7a33b20a41dJohn Reck                || url.regionMatches(true, 0, "about:", 0, 6)) {
9358233facddcc51865d612a919d450db6954aa48e3Michael Kolb            return;
9368233facddcc51865d612a919d450db6954aa48e3Michael Kolb        }
9370ebd3ac69a76ec76d9caab65a1947f971242994eJohn Reck        mDataController.updateVisitedHistory(url);
9388233facddcc51865d612a919d450db6954aa48e3Michael Kolb        WebIconDatabase.getInstance().retainIconForPageUrl(url);
939847b532045e3cb117a847ebb956c9919401f332dJohn Reck        if (!mActivityPaused) {
940847b532045e3cb117a847ebb956c9919401f332dJohn Reck            // Since we clear the state in onPause, don't backup the current
941847b532045e3cb117a847ebb956c9919401f332dJohn Reck            // state if we are already paused
942847b532045e3cb117a847ebb956c9919401f332dJohn Reck            mCrashRecoveryHandler.backupState();
943847b532045e3cb117a847ebb956c9919401f332dJohn Reck        }
9448233facddcc51865d612a919d450db6954aa48e3Michael Kolb    }
9458233facddcc51865d612a919d450db6954aa48e3Michael Kolb
9468233facddcc51865d612a919d450db6954aa48e3Michael Kolb    @Override
9478233facddcc51865d612a919d450db6954aa48e3Michael Kolb    public void getVisitedHistory(final ValueCallback<String[]> callback) {
9488233facddcc51865d612a919d450db6954aa48e3Michael Kolb        AsyncTask<Void, Void, String[]> task =
9498233facddcc51865d612a919d450db6954aa48e3Michael Kolb                new AsyncTask<Void, Void, String[]>() {
9508233facddcc51865d612a919d450db6954aa48e3Michael Kolb            @Override
9518233facddcc51865d612a919d450db6954aa48e3Michael Kolb            public String[] doInBackground(Void... unused) {
9528233facddcc51865d612a919d450db6954aa48e3Michael Kolb                return Browser.getVisitedHistory(mActivity.getContentResolver());
9538233facddcc51865d612a919d450db6954aa48e3Michael Kolb            }
9548233facddcc51865d612a919d450db6954aa48e3Michael Kolb            @Override
9558233facddcc51865d612a919d450db6954aa48e3Michael Kolb            public void onPostExecute(String[] result) {
9568233facddcc51865d612a919d450db6954aa48e3Michael Kolb                callback.onReceiveValue(result);
9578233facddcc51865d612a919d450db6954aa48e3Michael Kolb            }
9588233facddcc51865d612a919d450db6954aa48e3Michael Kolb        };
9598233facddcc51865d612a919d450db6954aa48e3Michael Kolb        task.execute();
9608233facddcc51865d612a919d450db6954aa48e3Michael Kolb    }
9618233facddcc51865d612a919d450db6954aa48e3Michael Kolb
9628233facddcc51865d612a919d450db6954aa48e3Michael Kolb    @Override
9638233facddcc51865d612a919d450db6954aa48e3Michael Kolb    public void onReceivedHttpAuthRequest(Tab tab, WebView view,
9648233facddcc51865d612a919d450db6954aa48e3Michael Kolb            final HttpAuthHandler handler, final String host,
9658233facddcc51865d612a919d450db6954aa48e3Michael Kolb            final String realm) {
9668233facddcc51865d612a919d450db6954aa48e3Michael Kolb        String username = null;
9678233facddcc51865d612a919d450db6954aa48e3Michael Kolb        String password = null;
9688233facddcc51865d612a919d450db6954aa48e3Michael Kolb
9698233facddcc51865d612a919d450db6954aa48e3Michael Kolb        boolean reuseHttpAuthUsernamePassword
9708233facddcc51865d612a919d450db6954aa48e3Michael Kolb                = handler.useHttpAuthUsernamePassword();
9718233facddcc51865d612a919d450db6954aa48e3Michael Kolb
9728233facddcc51865d612a919d450db6954aa48e3Michael Kolb        if (reuseHttpAuthUsernamePassword && view != null) {
9738233facddcc51865d612a919d450db6954aa48e3Michael Kolb            String[] credentials = view.getHttpAuthUsernamePassword(host, realm);
9748233facddcc51865d612a919d450db6954aa48e3Michael Kolb            if (credentials != null && credentials.length == 2) {
9758233facddcc51865d612a919d450db6954aa48e3Michael Kolb                username = credentials[0];
9768233facddcc51865d612a919d450db6954aa48e3Michael Kolb                password = credentials[1];
9778233facddcc51865d612a919d450db6954aa48e3Michael Kolb            }
9788233facddcc51865d612a919d450db6954aa48e3Michael Kolb        }
9798233facddcc51865d612a919d450db6954aa48e3Michael Kolb
9808233facddcc51865d612a919d450db6954aa48e3Michael Kolb        if (username != null && password != null) {
9818233facddcc51865d612a919d450db6954aa48e3Michael Kolb            handler.proceed(username, password);
9828233facddcc51865d612a919d450db6954aa48e3Michael Kolb        } else {
9838233facddcc51865d612a919d450db6954aa48e3Michael Kolb            if (tab.inForeground()) {
9848233facddcc51865d612a919d450db6954aa48e3Michael Kolb                mPageDialogsHandler.showHttpAuthentication(tab, handler, host, realm);
9858233facddcc51865d612a919d450db6954aa48e3Michael Kolb            } else {
9868233facddcc51865d612a919d450db6954aa48e3Michael Kolb                handler.cancel();
9878233facddcc51865d612a919d450db6954aa48e3Michael Kolb            }
9888233facddcc51865d612a919d450db6954aa48e3Michael Kolb        }
9898233facddcc51865d612a919d450db6954aa48e3Michael Kolb    }
9908233facddcc51865d612a919d450db6954aa48e3Michael Kolb
9918233facddcc51865d612a919d450db6954aa48e3Michael Kolb    @Override
9928233facddcc51865d612a919d450db6954aa48e3Michael Kolb    public void onDownloadStart(Tab tab, String url, String userAgent,
9938233facddcc51865d612a919d450db6954aa48e3Michael Kolb            String contentDisposition, String mimetype, long contentLength) {
994bc5cc75c302eb49d15258155fc6f672fcbd62842Kristian Monsen        WebView w = tab.getWebView();
99563c0266b5d1fca4df859fe4fa3a9555d0783a2b6Leon Scroggins        DownloadHandler.onDownloadStart(mActivity, url, userAgent,
996bc5cc75c302eb49d15258155fc6f672fcbd62842Kristian Monsen                contentDisposition, mimetype, w.isPrivateBrowsingEnabled());
997bc5cc75c302eb49d15258155fc6f672fcbd62842Kristian Monsen        if (w.copyBackForwardList().getSize() == 0) {
9988233facddcc51865d612a919d450db6954aa48e3Michael Kolb            // This Tab was opened for the sole purpose of downloading a
9998233facddcc51865d612a919d450db6954aa48e3Michael Kolb            // file. Remove it.
10008233facddcc51865d612a919d450db6954aa48e3Michael Kolb            if (tab == mTabControl.getCurrentTab()) {
10018233facddcc51865d612a919d450db6954aa48e3Michael Kolb                // In this case, the Tab is still on top.
10028233facddcc51865d612a919d450db6954aa48e3Michael Kolb                goBackOnePageOrQuit();
10038233facddcc51865d612a919d450db6954aa48e3Michael Kolb            } else {
10048233facddcc51865d612a919d450db6954aa48e3Michael Kolb                // In this case, it is not.
10058233facddcc51865d612a919d450db6954aa48e3Michael Kolb                closeTab(tab);
10068233facddcc51865d612a919d450db6954aa48e3Michael Kolb            }
10078233facddcc51865d612a919d450db6954aa48e3Michael Kolb        }
10088233facddcc51865d612a919d450db6954aa48e3Michael Kolb    }
10098233facddcc51865d612a919d450db6954aa48e3Michael Kolb
10108233facddcc51865d612a919d450db6954aa48e3Michael Kolb    @Override
10118233facddcc51865d612a919d450db6954aa48e3Michael Kolb    public Bitmap getDefaultVideoPoster() {
10128233facddcc51865d612a919d450db6954aa48e3Michael Kolb        return mUi.getDefaultVideoPoster();
10138233facddcc51865d612a919d450db6954aa48e3Michael Kolb    }
10148233facddcc51865d612a919d450db6954aa48e3Michael Kolb
10158233facddcc51865d612a919d450db6954aa48e3Michael Kolb    @Override
10168233facddcc51865d612a919d450db6954aa48e3Michael Kolb    public View getVideoLoadingProgressView() {
10178233facddcc51865d612a919d450db6954aa48e3Michael Kolb        return mUi.getVideoLoadingProgressView();
10188233facddcc51865d612a919d450db6954aa48e3Michael Kolb    }
10198233facddcc51865d612a919d450db6954aa48e3Michael Kolb
10208233facddcc51865d612a919d450db6954aa48e3Michael Kolb    @Override
10218233facddcc51865d612a919d450db6954aa48e3Michael Kolb    public void showSslCertificateOnError(WebView view, SslErrorHandler handler,
10228233facddcc51865d612a919d450db6954aa48e3Michael Kolb            SslError error) {
10238233facddcc51865d612a919d450db6954aa48e3Michael Kolb        mPageDialogsHandler.showSSLCertificateOnError(view, handler, error);
10248233facddcc51865d612a919d450db6954aa48e3Michael Kolb    }
10258233facddcc51865d612a919d450db6954aa48e3Michael Kolb
10269206677e461328f15854c5fcb1366d0e261534c6Patrick Scott    @Override
10279206677e461328f15854c5fcb1366d0e261534c6Patrick Scott    public void showAutoLogin(Tab tab) {
10289206677e461328f15854c5fcb1366d0e261534c6Patrick Scott        assert tab.inForeground();
10299206677e461328f15854c5fcb1366d0e261534c6Patrick Scott        // Update the title bar to show the auto-login request.
10309206677e461328f15854c5fcb1366d0e261534c6Patrick Scott        mUi.showAutoLogin(tab);
10319206677e461328f15854c5fcb1366d0e261534c6Patrick Scott    }
10329206677e461328f15854c5fcb1366d0e261534c6Patrick Scott
10339206677e461328f15854c5fcb1366d0e261534c6Patrick Scott    @Override
10349206677e461328f15854c5fcb1366d0e261534c6Patrick Scott    public void hideAutoLogin(Tab tab) {
10359206677e461328f15854c5fcb1366d0e261534c6Patrick Scott        assert tab.inForeground();
10369206677e461328f15854c5fcb1366d0e261534c6Patrick Scott        mUi.hideAutoLogin(tab);
10379206677e461328f15854c5fcb1366d0e261534c6Patrick Scott    }
10389206677e461328f15854c5fcb1366d0e261534c6Patrick Scott
10398233facddcc51865d612a919d450db6954aa48e3Michael Kolb    // helper method
10408233facddcc51865d612a919d450db6954aa48e3Michael Kolb
10418233facddcc51865d612a919d450db6954aa48e3Michael Kolb    /*
10428233facddcc51865d612a919d450db6954aa48e3Michael Kolb     * Update the favorites icon if the private browsing isn't enabled and the
10438233facddcc51865d612a919d450db6954aa48e3Michael Kolb     * icon is valid.
10448233facddcc51865d612a919d450db6954aa48e3Michael Kolb     */
10458233facddcc51865d612a919d450db6954aa48e3Michael Kolb    private void maybeUpdateFavicon(Tab tab, final String originalUrl,
10468233facddcc51865d612a919d450db6954aa48e3Michael Kolb            final String url, Bitmap favicon) {
10478233facddcc51865d612a919d450db6954aa48e3Michael Kolb        if (favicon == null) {
10488233facddcc51865d612a919d450db6954aa48e3Michael Kolb            return;
10498233facddcc51865d612a919d450db6954aa48e3Michael Kolb        }
10508233facddcc51865d612a919d450db6954aa48e3Michael Kolb        if (!tab.isPrivateBrowsingEnabled()) {
10518233facddcc51865d612a919d450db6954aa48e3Michael Kolb            Bookmarks.updateFavicon(mActivity
10528233facddcc51865d612a919d450db6954aa48e3Michael Kolb                    .getContentResolver(), originalUrl, url, favicon);
10538233facddcc51865d612a919d450db6954aa48e3Michael Kolb        }
10548233facddcc51865d612a919d450db6954aa48e3Michael Kolb    }
10558233facddcc51865d612a919d450db6954aa48e3Michael Kolb
10564cd97793901e8f5681cf642d0b2684697964a37aLeon Scroggins    @Override
10574cd97793901e8f5681cf642d0b2684697964a37aLeon Scroggins    public void bookmarkedStatusHasChanged(Tab tab) {
1058e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck        // TODO: Switch to using onTabDataChanged after b/3262950 is fixed
10594cd97793901e8f5681cf642d0b2684697964a37aLeon Scroggins        mUi.bookmarkedStatusHasChanged(tab);
10604cd97793901e8f5681cf642d0b2684697964a37aLeon Scroggins    }
10614cd97793901e8f5681cf642d0b2684697964a37aLeon Scroggins
10628233facddcc51865d612a919d450db6954aa48e3Michael Kolb    // end WebViewController
10638233facddcc51865d612a919d450db6954aa48e3Michael Kolb
10648233facddcc51865d612a919d450db6954aa48e3Michael Kolb    protected void pageUp() {
10658233facddcc51865d612a919d450db6954aa48e3Michael Kolb        getCurrentTopWebView().pageUp(false);
10668233facddcc51865d612a919d450db6954aa48e3Michael Kolb    }
10678233facddcc51865d612a919d450db6954aa48e3Michael Kolb
10688233facddcc51865d612a919d450db6954aa48e3Michael Kolb    protected void pageDown() {
10698233facddcc51865d612a919d450db6954aa48e3Michael Kolb        getCurrentTopWebView().pageDown(false);
10708233facddcc51865d612a919d450db6954aa48e3Michael Kolb    }
10718233facddcc51865d612a919d450db6954aa48e3Michael Kolb
10728233facddcc51865d612a919d450db6954aa48e3Michael Kolb    // callback from phone title bar
10738233facddcc51865d612a919d450db6954aa48e3Michael Kolb    public void editUrl() {
10748233facddcc51865d612a919d450db6954aa48e3Michael Kolb        if (mOptionsMenuOpen) mActivity.closeOptionsMenu();
1075dc2ee1bfb50b7bec0cf3215e3d298b246dc71101Michael Kolb        mUi.editUrl(false);
10768233facddcc51865d612a919d450db6954aa48e3Michael Kolb    }
10778233facddcc51865d612a919d450db6954aa48e3Michael Kolb
1078cfa3af5c59abb38c895416a80ef16da0ec1b5287Michael Kolb    public void startVoiceSearch() {
1079cfa3af5c59abb38c895416a80ef16da0ec1b5287Michael Kolb        Intent intent = new Intent(RecognizerIntent.ACTION_WEB_SEARCH);
1080cfa3af5c59abb38c895416a80ef16da0ec1b5287Michael Kolb        intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL,
1081cfa3af5c59abb38c895416a80ef16da0ec1b5287Michael Kolb                RecognizerIntent.LANGUAGE_MODEL_WEB_SEARCH);
1082cfa3af5c59abb38c895416a80ef16da0ec1b5287Michael Kolb        intent.putExtra(RecognizerIntent.EXTRA_CALLING_PACKAGE,
1083cfa3af5c59abb38c895416a80ef16da0ec1b5287Michael Kolb                mActivity.getComponentName().flattenToString());
1084cfa3af5c59abb38c895416a80ef16da0ec1b5287Michael Kolb        intent.putExtra(SEND_APP_ID_EXTRA, false);
108517c4eba32d411830f67aca2077253ac42f606452Michael Kolb        intent.putExtra(RecognizerIntent.EXTRA_WEB_SEARCH_ONLY, true);
1086cfa3af5c59abb38c895416a80ef16da0ec1b5287Michael Kolb        mActivity.startActivity(intent);
1087cfa3af5c59abb38c895416a80ef16da0ec1b5287Michael Kolb    }
1088cfa3af5c59abb38c895416a80ef16da0ec1b5287Michael Kolb
108911d1978d8d16004598347abc93918b54a5ef760bMichael Kolb    @Override
109011d1978d8d16004598347abc93918b54a5ef760bMichael Kolb    public void activateVoiceSearchMode(String title, List<String> results) {
109111d1978d8d16004598347abc93918b54a5ef760bMichael Kolb        mUi.showVoiceTitleBar(title, results);
10928233facddcc51865d612a919d450db6954aa48e3Michael Kolb    }
10938233facddcc51865d612a919d450db6954aa48e3Michael Kolb
10948233facddcc51865d612a919d450db6954aa48e3Michael Kolb    public void revertVoiceSearchMode(Tab tab) {
10958233facddcc51865d612a919d450db6954aa48e3Michael Kolb        mUi.revertVoiceTitleBar(tab);
10968233facddcc51865d612a919d450db6954aa48e3Michael Kolb    }
10978233facddcc51865d612a919d450db6954aa48e3Michael Kolb
1098736990cb9c57a346666d4424304947c21fb78ab7Michael Kolb    public boolean supportsVoiceSearch() {
109935e9dd6283a2d65687104eb0b3a459c02dcb150bJohn Reck        SearchEngine searchEngine = getSettings().getSearchEngine();
1100736990cb9c57a346666d4424304947c21fb78ab7Michael Kolb        return (searchEngine != null && searchEngine.supportsVoiceSearch());
1101736990cb9c57a346666d4424304947c21fb78ab7Michael Kolb    }
1102736990cb9c57a346666d4424304947c21fb78ab7Michael Kolb
11032d4f1e2553dee6bce5a12162ff6d4459babe2512Derek Sollenberger    public void showCustomView(Tab tab, View view, int requestedOrientation,
11048233facddcc51865d612a919d450db6954aa48e3Michael Kolb            WebChromeClient.CustomViewCallback callback) {
11058233facddcc51865d612a919d450db6954aa48e3Michael Kolb        if (tab.inForeground()) {
11068233facddcc51865d612a919d450db6954aa48e3Michael Kolb            if (mUi.isCustomViewShowing()) {
11078233facddcc51865d612a919d450db6954aa48e3Michael Kolb                callback.onCustomViewHidden();
11088233facddcc51865d612a919d450db6954aa48e3Michael Kolb                return;
11098233facddcc51865d612a919d450db6954aa48e3Michael Kolb            }
11102d4f1e2553dee6bce5a12162ff6d4459babe2512Derek Sollenberger            mUi.showCustomView(view, requestedOrientation, callback);
11118233facddcc51865d612a919d450db6954aa48e3Michael Kolb            // Save the menu state and set it to empty while the custom
11128233facddcc51865d612a919d450db6954aa48e3Michael Kolb            // view is showing.
11138233facddcc51865d612a919d450db6954aa48e3Michael Kolb            mOldMenuState = mMenuState;
11148233facddcc51865d612a919d450db6954aa48e3Michael Kolb            mMenuState = EMPTY_MENU;
1115d73c5a2bd0cee6801dce425c31d0c3e027588bcaJohn Reck            mActivity.invalidateOptionsMenu();
11168233facddcc51865d612a919d450db6954aa48e3Michael Kolb        }
11178233facddcc51865d612a919d450db6954aa48e3Michael Kolb    }
11188233facddcc51865d612a919d450db6954aa48e3Michael Kolb
11198233facddcc51865d612a919d450db6954aa48e3Michael Kolb    @Override
11208233facddcc51865d612a919d450db6954aa48e3Michael Kolb    public void hideCustomView() {
11218233facddcc51865d612a919d450db6954aa48e3Michael Kolb        if (mUi.isCustomViewShowing()) {
11228233facddcc51865d612a919d450db6954aa48e3Michael Kolb            mUi.onHideCustomView();
11238233facddcc51865d612a919d450db6954aa48e3Michael Kolb            // Reset the old menu state.
11248233facddcc51865d612a919d450db6954aa48e3Michael Kolb            mMenuState = mOldMenuState;
11258233facddcc51865d612a919d450db6954aa48e3Michael Kolb            mOldMenuState = EMPTY_MENU;
1126d73c5a2bd0cee6801dce425c31d0c3e027588bcaJohn Reck            mActivity.invalidateOptionsMenu();
11278233facddcc51865d612a919d450db6954aa48e3Michael Kolb        }
11288233facddcc51865d612a919d450db6954aa48e3Michael Kolb    }
11298233facddcc51865d612a919d450db6954aa48e3Michael Kolb
11308233facddcc51865d612a919d450db6954aa48e3Michael Kolb    protected void onActivityResult(int requestCode, int resultCode,
11318233facddcc51865d612a919d450db6954aa48e3Michael Kolb            Intent intent) {
11328233facddcc51865d612a919d450db6954aa48e3Michael Kolb        if (getCurrentTopWebView() == null) return;
11338233facddcc51865d612a919d450db6954aa48e3Michael Kolb        switch (requestCode) {
11348233facddcc51865d612a919d450db6954aa48e3Michael Kolb            case PREFERENCES_PAGE:
11358233facddcc51865d612a919d450db6954aa48e3Michael Kolb                if (resultCode == Activity.RESULT_OK && intent != null) {
11368233facddcc51865d612a919d450db6954aa48e3Michael Kolb                    String action = intent.getStringExtra(Intent.EXTRA_TEXT);
113735e9dd6283a2d65687104eb0b3a459c02dcb150bJohn Reck                    if (PreferenceKeys.PREF_PRIVACY_CLEAR_HISTORY.equals(action)) {
11388233facddcc51865d612a919d450db6954aa48e3Michael Kolb                        mTabControl.removeParentChildRelationShips();
11398233facddcc51865d612a919d450db6954aa48e3Michael Kolb                    }
11408233facddcc51865d612a919d450db6954aa48e3Michael Kolb                }
11418233facddcc51865d612a919d450db6954aa48e3Michael Kolb                break;
11428233facddcc51865d612a919d450db6954aa48e3Michael Kolb            case FILE_SELECTED:
114351f6a2f1dc524b31476fb71de36f2bd79f499d08Ben Murdoch                // Chose a file from the file picker.
11449dfcdb1490d7abac107e4d2b1c2fef51ccdf6b98John Reck                if (null == mUploadHandler) break;
11458233facddcc51865d612a919d450db6954aa48e3Michael Kolb                mUploadHandler.onResult(resultCode, intent);
11468233facddcc51865d612a919d450db6954aa48e3Michael Kolb                break;
11478029a777106fa6fb911ee1d58402b0de768a583aBen Murdoch            case AUTOFILL_SETUP:
11488029a777106fa6fb911ee1d58402b0de768a583aBen Murdoch                // Determine whether a profile was actually set up or not
11498029a777106fa6fb911ee1d58402b0de768a583aBen Murdoch                // and if so, send the message back to the WebTextView to
11508029a777106fa6fb911ee1d58402b0de768a583aBen Murdoch                // fill the form with the new profile.
11518029a777106fa6fb911ee1d58402b0de768a583aBen Murdoch                if (getSettings().getAutoFillProfile() != null) {
11528029a777106fa6fb911ee1d58402b0de768a583aBen Murdoch                    mAutoFillSetupMessage.sendToTarget();
11538029a777106fa6fb911ee1d58402b0de768a583aBen Murdoch                    mAutoFillSetupMessage = null;
11548029a777106fa6fb911ee1d58402b0de768a583aBen Murdoch                }
11558029a777106fa6fb911ee1d58402b0de768a583aBen Murdoch                break;
11568233facddcc51865d612a919d450db6954aa48e3Michael Kolb            default:
11578233facddcc51865d612a919d450db6954aa48e3Michael Kolb                break;
11588233facddcc51865d612a919d450db6954aa48e3Michael Kolb        }
11598233facddcc51865d612a919d450db6954aa48e3Michael Kolb        getCurrentTopWebView().requestFocus();
11608233facddcc51865d612a919d450db6954aa48e3Michael Kolb    }
11618233facddcc51865d612a919d450db6954aa48e3Michael Kolb
11628233facddcc51865d612a919d450db6954aa48e3Michael Kolb    /**
11638233facddcc51865d612a919d450db6954aa48e3Michael Kolb     * Open the Go page.
11648233facddcc51865d612a919d450db6954aa48e3Michael Kolb     * @param startWithHistory If true, open starting on the history tab.
11658233facddcc51865d612a919d450db6954aa48e3Michael Kolb     *                         Otherwise, start with the bookmarks tab.
11668233facddcc51865d612a919d450db6954aa48e3Michael Kolb     */
11678233facddcc51865d612a919d450db6954aa48e3Michael Kolb    @Override
11688233facddcc51865d612a919d450db6954aa48e3Michael Kolb    public void bookmarksOrHistoryPicker(boolean startWithHistory) {
11698233facddcc51865d612a919d450db6954aa48e3Michael Kolb        if (mTabControl.getCurrentWebView() == null) {
11708233facddcc51865d612a919d450db6954aa48e3Michael Kolb            return;
11718233facddcc51865d612a919d450db6954aa48e3Michael Kolb        }
1172bd3dd948312df22888a8a90aef21e3460ba2f0b3Michael Kolb        // clear action mode
1173bd3dd948312df22888a8a90aef21e3460ba2f0b3Michael Kolb        if (isInCustomActionMode()) {
1174bd3dd948312df22888a8a90aef21e3460ba2f0b3Michael Kolb            endActionMode();
1175bd3dd948312df22888a8a90aef21e3460ba2f0b3Michael Kolb        }
11768233facddcc51865d612a919d450db6954aa48e3Michael Kolb        Bundle extras = new Bundle();
11778233facddcc51865d612a919d450db6954aa48e3Michael Kolb        // Disable opening in a new window if we have maxed out the windows
11788233facddcc51865d612a919d450db6954aa48e3Michael Kolb        extras.putBoolean(BrowserBookmarksPage.EXTRA_DISABLE_WINDOW,
11798233facddcc51865d612a919d450db6954aa48e3Michael Kolb                !mTabControl.canCreateNewTab());
11802bc8042224be51966d748b870768ec1b376a1621John Reck        mUi.showComboView(startWithHistory
11812bc8042224be51966d748b870768ec1b376a1621John Reck                ? ComboViews.History : ComboViews.Bookmarks, extras);
11828233facddcc51865d612a919d450db6954aa48e3Michael Kolb    }
11838233facddcc51865d612a919d450db6954aa48e3Michael Kolb
11848233facddcc51865d612a919d450db6954aa48e3Michael Kolb    // combo view callbacks
11858233facddcc51865d612a919d450db6954aa48e3Michael Kolb
11868233facddcc51865d612a919d450db6954aa48e3Michael Kolb    /**
11878233facddcc51865d612a919d450db6954aa48e3Michael Kolb     * callback from ComboPage when clear history is requested
11888233facddcc51865d612a919d450db6954aa48e3Michael Kolb     */
11898233facddcc51865d612a919d450db6954aa48e3Michael Kolb    public void onRemoveParentChildRelationships() {
11908233facddcc51865d612a919d450db6954aa48e3Michael Kolb        mTabControl.removeParentChildRelationShips();
11918233facddcc51865d612a919d450db6954aa48e3Michael Kolb    }
11928233facddcc51865d612a919d450db6954aa48e3Michael Kolb
11938233facddcc51865d612a919d450db6954aa48e3Michael Kolb    /**
11948233facddcc51865d612a919d450db6954aa48e3Michael Kolb     * callback from ComboPage when bookmark/history selection
11958233facddcc51865d612a919d450db6954aa48e3Michael Kolb     */
11968233facddcc51865d612a919d450db6954aa48e3Michael Kolb    @Override
11978233facddcc51865d612a919d450db6954aa48e3Michael Kolb    public void onUrlSelected(String url, boolean newTab) {
11988233facddcc51865d612a919d450db6954aa48e3Michael Kolb        removeComboView();
11998233facddcc51865d612a919d450db6954aa48e3Michael Kolb        if (!TextUtils.isEmpty(url)) {
12008233facddcc51865d612a919d450db6954aa48e3Michael Kolb            if (newTab) {
12017bcafde2ba532941c1eb8c9022eebd5398aeae2aMichael Kolb                final Tab parent = mTabControl.getCurrentTab();
12027bcafde2ba532941c1eb8c9022eebd5398aeae2aMichael Kolb                openTab(url,
12037bcafde2ba532941c1eb8c9022eebd5398aeae2aMichael Kolb                        (parent != null) && parent.isPrivateBrowsingEnabled(),
12047bcafde2ba532941c1eb8c9022eebd5398aeae2aMichael Kolb                        !mSettings.openInBackground(),
12057bcafde2ba532941c1eb8c9022eebd5398aeae2aMichael Kolb                        true);
12068233facddcc51865d612a919d450db6954aa48e3Michael Kolb            } else {
12078233facddcc51865d612a919d450db6954aa48e3Michael Kolb                final Tab currentTab = mTabControl.getCurrentTab();
120826b183292dc087b16af10f482744c3bb30e1f163John Reck                loadUrl(currentTab, url);
12098233facddcc51865d612a919d450db6954aa48e3Michael Kolb            }
12108233facddcc51865d612a919d450db6954aa48e3Michael Kolb        }
12118233facddcc51865d612a919d450db6954aa48e3Michael Kolb    }
12128233facddcc51865d612a919d450db6954aa48e3Michael Kolb
12138233facddcc51865d612a919d450db6954aa48e3Michael Kolb    /**
12148233facddcc51865d612a919d450db6954aa48e3Michael Kolb     * dismiss the ComboPage
12158233facddcc51865d612a919d450db6954aa48e3Michael Kolb     */
12168233facddcc51865d612a919d450db6954aa48e3Michael Kolb    @Override
12178233facddcc51865d612a919d450db6954aa48e3Michael Kolb    public void removeComboView() {
12188233facddcc51865d612a919d450db6954aa48e3Michael Kolb        mUi.hideComboView();
12198233facddcc51865d612a919d450db6954aa48e3Michael Kolb    }
12208233facddcc51865d612a919d450db6954aa48e3Michael Kolb
12218233facddcc51865d612a919d450db6954aa48e3Michael Kolb    // key handling
12228233facddcc51865d612a919d450db6954aa48e3Michael Kolb    protected void onBackKey() {
12238233facddcc51865d612a919d450db6954aa48e3Michael Kolb        if (!mUi.onBackKey()) {
12248233facddcc51865d612a919d450db6954aa48e3Michael Kolb            WebView subwindow = mTabControl.getCurrentSubWindow();
12258233facddcc51865d612a919d450db6954aa48e3Michael Kolb            if (subwindow != null) {
12268233facddcc51865d612a919d450db6954aa48e3Michael Kolb                if (subwindow.canGoBack()) {
12278233facddcc51865d612a919d450db6954aa48e3Michael Kolb                    subwindow.goBack();
12288233facddcc51865d612a919d450db6954aa48e3Michael Kolb                } else {
12298233facddcc51865d612a919d450db6954aa48e3Michael Kolb                    dismissSubWindow(mTabControl.getCurrentTab());
12308233facddcc51865d612a919d450db6954aa48e3Michael Kolb                }
12318233facddcc51865d612a919d450db6954aa48e3Michael Kolb            } else {
12328233facddcc51865d612a919d450db6954aa48e3Michael Kolb                goBackOnePageOrQuit();
12338233facddcc51865d612a919d450db6954aa48e3Michael Kolb            }
12348233facddcc51865d612a919d450db6954aa48e3Michael Kolb        }
12358233facddcc51865d612a919d450db6954aa48e3Michael Kolb    }
12368233facddcc51865d612a919d450db6954aa48e3Michael Kolb
12374bd767d2f4ce166a44687170c6af18e242447205Michael Kolb    protected boolean onMenuKey() {
12384bd767d2f4ce166a44687170c6af18e242447205Michael Kolb        return mUi.onMenuKey();
12392814a362c21ac219410d9b54e1bd3e8152b845c7Michael Kolb    }
12402814a362c21ac219410d9b54e1bd3e8152b845c7Michael Kolb
12418233facddcc51865d612a919d450db6954aa48e3Michael Kolb    // menu handling and state
12428233facddcc51865d612a919d450db6954aa48e3Michael Kolb    // TODO: maybe put into separate handler
12438233facddcc51865d612a919d450db6954aa48e3Michael Kolb
12448233facddcc51865d612a919d450db6954aa48e3Michael Kolb    protected boolean onCreateOptionsMenu(Menu menu) {
1245b3417f0a68a1efc64604ea354ae7f856ce79cb16John Reck        if (mOptionsMenuHandler != null) {
1246b3417f0a68a1efc64604ea354ae7f856ce79cb16John Reck            return mOptionsMenuHandler.onCreateOptionsMenu(menu);
1247b3417f0a68a1efc64604ea354ae7f856ce79cb16John Reck        }
1248b3417f0a68a1efc64604ea354ae7f856ce79cb16John Reck
1249d73c5a2bd0cee6801dce425c31d0c3e027588bcaJohn Reck        if (mMenuState == EMPTY_MENU) {
1250d73c5a2bd0cee6801dce425c31d0c3e027588bcaJohn Reck            return false;
1251d73c5a2bd0cee6801dce425c31d0c3e027588bcaJohn Reck        }
12528233facddcc51865d612a919d450db6954aa48e3Michael Kolb        MenuInflater inflater = mActivity.getMenuInflater();
12538233facddcc51865d612a919d450db6954aa48e3Michael Kolb        inflater.inflate(R.menu.browser, menu);
12548233facddcc51865d612a919d450db6954aa48e3Michael Kolb        updateInLoadMenuItems(menu);
12558233facddcc51865d612a919d450db6954aa48e3Michael Kolb        // hold on to the menu reference here; it is used by the page callbacks
12568233facddcc51865d612a919d450db6954aa48e3Michael Kolb        // to update the menu based on loading state
12578233facddcc51865d612a919d450db6954aa48e3Michael Kolb        mCachedMenu = menu;
12588233facddcc51865d612a919d450db6954aa48e3Michael Kolb        return true;
12598233facddcc51865d612a919d450db6954aa48e3Michael Kolb    }
12608233facddcc51865d612a919d450db6954aa48e3Michael Kolb
12618233facddcc51865d612a919d450db6954aa48e3Michael Kolb    protected void onCreateContextMenu(ContextMenu menu, View v,
12628233facddcc51865d612a919d450db6954aa48e3Michael Kolb            ContextMenuInfo menuInfo) {
12630f602f3933dcd88702fdb514b6611e3066ca7a2bJohn Reck        if (v instanceof TitleBar) {
12648233facddcc51865d612a919d450db6954aa48e3Michael Kolb            return;
12658233facddcc51865d612a919d450db6954aa48e3Michael Kolb        }
12668233facddcc51865d612a919d450db6954aa48e3Michael Kolb        if (!(v instanceof WebView)) {
12678233facddcc51865d612a919d450db6954aa48e3Michael Kolb            return;
12688233facddcc51865d612a919d450db6954aa48e3Michael Kolb        }
1269026f254cff9d762a9f9c9d9bf74f15809d730cd2Leon Scroggins        final WebView webview = (WebView) v;
12708233facddcc51865d612a919d450db6954aa48e3Michael Kolb        WebView.HitTestResult result = webview.getHitTestResult();
12718233facddcc51865d612a919d450db6954aa48e3Michael Kolb        if (result == null) {
12728233facddcc51865d612a919d450db6954aa48e3Michael Kolb            return;
12738233facddcc51865d612a919d450db6954aa48e3Michael Kolb        }
12748233facddcc51865d612a919d450db6954aa48e3Michael Kolb
12758233facddcc51865d612a919d450db6954aa48e3Michael Kolb        int type = result.getType();
12768233facddcc51865d612a919d450db6954aa48e3Michael Kolb        if (type == WebView.HitTestResult.UNKNOWN_TYPE) {
12778233facddcc51865d612a919d450db6954aa48e3Michael Kolb            Log.w(LOGTAG,
12788233facddcc51865d612a919d450db6954aa48e3Michael Kolb                    "We should not show context menu when nothing is touched");
12798233facddcc51865d612a919d450db6954aa48e3Michael Kolb            return;
12808233facddcc51865d612a919d450db6954aa48e3Michael Kolb        }
12818233facddcc51865d612a919d450db6954aa48e3Michael Kolb        if (type == WebView.HitTestResult.EDIT_TEXT_TYPE) {
12828233facddcc51865d612a919d450db6954aa48e3Michael Kolb            // let TextView handles context menu
12838233facddcc51865d612a919d450db6954aa48e3Michael Kolb            return;
12848233facddcc51865d612a919d450db6954aa48e3Michael Kolb        }
12858233facddcc51865d612a919d450db6954aa48e3Michael Kolb
12868233facddcc51865d612a919d450db6954aa48e3Michael Kolb        // Note, http://b/issue?id=1106666 is requesting that
12878233facddcc51865d612a919d450db6954aa48e3Michael Kolb        // an inflated menu can be used again. This is not available
12888233facddcc51865d612a919d450db6954aa48e3Michael Kolb        // yet, so inflate each time (yuk!)
12898233facddcc51865d612a919d450db6954aa48e3Michael Kolb        MenuInflater inflater = mActivity.getMenuInflater();
12908233facddcc51865d612a919d450db6954aa48e3Michael Kolb        inflater.inflate(R.menu.browsercontext, menu);
12918233facddcc51865d612a919d450db6954aa48e3Michael Kolb
12928233facddcc51865d612a919d450db6954aa48e3Michael Kolb        // Show the correct menu group
12938233facddcc51865d612a919d450db6954aa48e3Michael Kolb        final String extra = result.getExtra();
12948233facddcc51865d612a919d450db6954aa48e3Michael Kolb        menu.setGroupVisible(R.id.PHONE_MENU,
12958233facddcc51865d612a919d450db6954aa48e3Michael Kolb                type == WebView.HitTestResult.PHONE_TYPE);
12968233facddcc51865d612a919d450db6954aa48e3Michael Kolb        menu.setGroupVisible(R.id.EMAIL_MENU,
12978233facddcc51865d612a919d450db6954aa48e3Michael Kolb                type == WebView.HitTestResult.EMAIL_TYPE);
12988233facddcc51865d612a919d450db6954aa48e3Michael Kolb        menu.setGroupVisible(R.id.GEO_MENU,
12998233facddcc51865d612a919d450db6954aa48e3Michael Kolb                type == WebView.HitTestResult.GEO_TYPE);
13008233facddcc51865d612a919d450db6954aa48e3Michael Kolb        menu.setGroupVisible(R.id.IMAGE_MENU,
13018233facddcc51865d612a919d450db6954aa48e3Michael Kolb                type == WebView.HitTestResult.IMAGE_TYPE
13028233facddcc51865d612a919d450db6954aa48e3Michael Kolb                || type == WebView.HitTestResult.SRC_IMAGE_ANCHOR_TYPE);
13038233facddcc51865d612a919d450db6954aa48e3Michael Kolb        menu.setGroupVisible(R.id.ANCHOR_MENU,
13048233facddcc51865d612a919d450db6954aa48e3Michael Kolb                type == WebView.HitTestResult.SRC_ANCHOR_TYPE
13058233facddcc51865d612a919d450db6954aa48e3Michael Kolb                || type == WebView.HitTestResult.SRC_IMAGE_ANCHOR_TYPE);
13068974d281fa5c96bf50d5f5bac665cae44568f6e8Cary Clark        boolean hitText = type == WebView.HitTestResult.SRC_ANCHOR_TYPE
13078974d281fa5c96bf50d5f5bac665cae44568f6e8Cary Clark                || type == WebView.HitTestResult.PHONE_TYPE
13088974d281fa5c96bf50d5f5bac665cae44568f6e8Cary Clark                || type == WebView.HitTestResult.EMAIL_TYPE
13098974d281fa5c96bf50d5f5bac665cae44568f6e8Cary Clark                || type == WebView.HitTestResult.GEO_TYPE;
13108974d281fa5c96bf50d5f5bac665cae44568f6e8Cary Clark        menu.setGroupVisible(R.id.SELECT_TEXT_MENU, hitText);
13118974d281fa5c96bf50d5f5bac665cae44568f6e8Cary Clark        if (hitText) {
13128974d281fa5c96bf50d5f5bac665cae44568f6e8Cary Clark            menu.findItem(R.id.select_text_menu_id)
13138974d281fa5c96bf50d5f5bac665cae44568f6e8Cary Clark                    .setOnMenuItemClickListener(new SelectText(webview));
13148974d281fa5c96bf50d5f5bac665cae44568f6e8Cary Clark        }
13158233facddcc51865d612a919d450db6954aa48e3Michael Kolb        // Setup custom handling depending on the type
13168233facddcc51865d612a919d450db6954aa48e3Michael Kolb        switch (type) {
13178233facddcc51865d612a919d450db6954aa48e3Michael Kolb            case WebView.HitTestResult.PHONE_TYPE:
13188233facddcc51865d612a919d450db6954aa48e3Michael Kolb                menu.setHeaderTitle(Uri.decode(extra));
13198233facddcc51865d612a919d450db6954aa48e3Michael Kolb                menu.findItem(R.id.dial_context_menu_id).setIntent(
13208233facddcc51865d612a919d450db6954aa48e3Michael Kolb                        new Intent(Intent.ACTION_VIEW, Uri
13218233facddcc51865d612a919d450db6954aa48e3Michael Kolb                                .parse(WebView.SCHEME_TEL + extra)));
13228233facddcc51865d612a919d450db6954aa48e3Michael Kolb                Intent addIntent = new Intent(Intent.ACTION_INSERT_OR_EDIT);
13238233facddcc51865d612a919d450db6954aa48e3Michael Kolb                addIntent.putExtra(Insert.PHONE, Uri.decode(extra));
13248233facddcc51865d612a919d450db6954aa48e3Michael Kolb                addIntent.setType(ContactsContract.Contacts.CONTENT_ITEM_TYPE);
13258233facddcc51865d612a919d450db6954aa48e3Michael Kolb                menu.findItem(R.id.add_contact_context_menu_id).setIntent(
13268233facddcc51865d612a919d450db6954aa48e3Michael Kolb                        addIntent);
13278233facddcc51865d612a919d450db6954aa48e3Michael Kolb                menu.findItem(R.id.copy_phone_context_menu_id)
13288233facddcc51865d612a919d450db6954aa48e3Michael Kolb                        .setOnMenuItemClickListener(
13298233facddcc51865d612a919d450db6954aa48e3Michael Kolb                        new Copy(extra));
13308233facddcc51865d612a919d450db6954aa48e3Michael Kolb                break;
13318233facddcc51865d612a919d450db6954aa48e3Michael Kolb
13328233facddcc51865d612a919d450db6954aa48e3Michael Kolb            case WebView.HitTestResult.EMAIL_TYPE:
13338233facddcc51865d612a919d450db6954aa48e3Michael Kolb                menu.setHeaderTitle(extra);
13348233facddcc51865d612a919d450db6954aa48e3Michael Kolb                menu.findItem(R.id.email_context_menu_id).setIntent(
13358233facddcc51865d612a919d450db6954aa48e3Michael Kolb                        new Intent(Intent.ACTION_VIEW, Uri
13368233facddcc51865d612a919d450db6954aa48e3Michael Kolb                                .parse(WebView.SCHEME_MAILTO + extra)));
13378233facddcc51865d612a919d450db6954aa48e3Michael Kolb                menu.findItem(R.id.copy_mail_context_menu_id)
13388233facddcc51865d612a919d450db6954aa48e3Michael Kolb                        .setOnMenuItemClickListener(
13398233facddcc51865d612a919d450db6954aa48e3Michael Kolb                        new Copy(extra));
13408233facddcc51865d612a919d450db6954aa48e3Michael Kolb                break;
13418233facddcc51865d612a919d450db6954aa48e3Michael Kolb
13428233facddcc51865d612a919d450db6954aa48e3Michael Kolb            case WebView.HitTestResult.GEO_TYPE:
13438233facddcc51865d612a919d450db6954aa48e3Michael Kolb                menu.setHeaderTitle(extra);
13448233facddcc51865d612a919d450db6954aa48e3Michael Kolb                menu.findItem(R.id.map_context_menu_id).setIntent(
13458233facddcc51865d612a919d450db6954aa48e3Michael Kolb                        new Intent(Intent.ACTION_VIEW, Uri
13468233facddcc51865d612a919d450db6954aa48e3Michael Kolb                                .parse(WebView.SCHEME_GEO
13478233facddcc51865d612a919d450db6954aa48e3Michael Kolb                                        + URLEncoder.encode(extra))));
13488233facddcc51865d612a919d450db6954aa48e3Michael Kolb                menu.findItem(R.id.copy_geo_context_menu_id)
13498233facddcc51865d612a919d450db6954aa48e3Michael Kolb                        .setOnMenuItemClickListener(
13508233facddcc51865d612a919d450db6954aa48e3Michael Kolb                        new Copy(extra));
13518233facddcc51865d612a919d450db6954aa48e3Michael Kolb                break;
13528233facddcc51865d612a919d450db6954aa48e3Michael Kolb
13538233facddcc51865d612a919d450db6954aa48e3Michael Kolb            case WebView.HitTestResult.SRC_ANCHOR_TYPE:
13548233facddcc51865d612a919d450db6954aa48e3Michael Kolb            case WebView.HitTestResult.SRC_IMAGE_ANCHOR_TYPE:
13554c537ce641be22ca0ce49a73bbbf92c36bd061feMichael Kolb                menu.setHeaderTitle(extra);
13568233facddcc51865d612a919d450db6954aa48e3Michael Kolb                // decide whether to show the open link in new tab option
13578233facddcc51865d612a919d450db6954aa48e3Michael Kolb                boolean showNewTab = mTabControl.canCreateNewTab();
13588233facddcc51865d612a919d450db6954aa48e3Michael Kolb                MenuItem newTabItem
13598233facddcc51865d612a919d450db6954aa48e3Michael Kolb                        = menu.findItem(R.id.open_newtab_context_menu_id);
136035e9dd6283a2d65687104eb0b3a459c02dcb150bJohn Reck                newTabItem.setTitle(getSettings().openInBackground()
13612dd65c8bf13b11c99c78ec22a0fef2c58494bb9eMichael Kolb                        ? R.string.contextmenu_openlink_newwindow_background
13622dd65c8bf13b11c99c78ec22a0fef2c58494bb9eMichael Kolb                        : R.string.contextmenu_openlink_newwindow);
13638233facddcc51865d612a919d450db6954aa48e3Michael Kolb                newTabItem.setVisible(showNewTab);
13648233facddcc51865d612a919d450db6954aa48e3Michael Kolb                if (showNewTab) {
1365026f254cff9d762a9f9c9d9bf74f15809d730cd2Leon Scroggins                    if (WebView.HitTestResult.SRC_IMAGE_ANCHOR_TYPE == type) {
1366026f254cff9d762a9f9c9d9bf74f15809d730cd2Leon Scroggins                        newTabItem.setOnMenuItemClickListener(
1367026f254cff9d762a9f9c9d9bf74f15809d730cd2Leon Scroggins                                new MenuItem.OnMenuItemClickListener() {
1368026f254cff9d762a9f9c9d9bf74f15809d730cd2Leon Scroggins                                    @Override
1369026f254cff9d762a9f9c9d9bf74f15809d730cd2Leon Scroggins                                    public boolean onMenuItemClick(MenuItem item) {
1370026f254cff9d762a9f9c9d9bf74f15809d730cd2Leon Scroggins                                        final HashMap<String, WebView> hrefMap =
1371026f254cff9d762a9f9c9d9bf74f15809d730cd2Leon Scroggins                                                new HashMap<String, WebView>();
1372026f254cff9d762a9f9c9d9bf74f15809d730cd2Leon Scroggins                                        hrefMap.put("webview", webview);
1373026f254cff9d762a9f9c9d9bf74f15809d730cd2Leon Scroggins                                        final Message msg = mHandler.obtainMessage(
1374026f254cff9d762a9f9c9d9bf74f15809d730cd2Leon Scroggins                                                FOCUS_NODE_HREF,
1375026f254cff9d762a9f9c9d9bf74f15809d730cd2Leon Scroggins                                                R.id.open_newtab_context_menu_id,
1376026f254cff9d762a9f9c9d9bf74f15809d730cd2Leon Scroggins                                                0, hrefMap);
1377026f254cff9d762a9f9c9d9bf74f15809d730cd2Leon Scroggins                                        webview.requestFocusNodeHref(msg);
1378026f254cff9d762a9f9c9d9bf74f15809d730cd2Leon Scroggins                                        return true;
13798233facddcc51865d612a919d450db6954aa48e3Michael Kolb                                    }
1380026f254cff9d762a9f9c9d9bf74f15809d730cd2Leon Scroggins                                });
1381026f254cff9d762a9f9c9d9bf74f15809d730cd2Leon Scroggins                    } else {
1382026f254cff9d762a9f9c9d9bf74f15809d730cd2Leon Scroggins                        newTabItem.setOnMenuItemClickListener(
1383026f254cff9d762a9f9c9d9bf74f15809d730cd2Leon Scroggins                                new MenuItem.OnMenuItemClickListener() {
1384026f254cff9d762a9f9c9d9bf74f15809d730cd2Leon Scroggins                                    @Override
1385026f254cff9d762a9f9c9d9bf74f15809d730cd2Leon Scroggins                                    public boolean onMenuItemClick(MenuItem item) {
1386026f254cff9d762a9f9c9d9bf74f15809d730cd2Leon Scroggins                                        final Tab parent = mTabControl.getCurrentTab();
13875949c661b51295148706d53a03b41df2eb840ae3John Reck                                        openTab(extra, parent,
13885949c661b51295148706d53a03b41df2eb840ae3John Reck                                                !mSettings.openInBackground(),
13895949c661b51295148706d53a03b41df2eb840ae3John Reck                                                true);
1390026f254cff9d762a9f9c9d9bf74f15809d730cd2Leon Scroggins                                        return true;
1391026f254cff9d762a9f9c9d9bf74f15809d730cd2Leon Scroggins                                    }
1392026f254cff9d762a9f9c9d9bf74f15809d730cd2Leon Scroggins                                });
1393026f254cff9d762a9f9c9d9bf74f15809d730cd2Leon Scroggins                    }
13948233facddcc51865d612a919d450db6954aa48e3Michael Kolb                }
13958233facddcc51865d612a919d450db6954aa48e3Michael Kolb                if (type == WebView.HitTestResult.SRC_ANCHOR_TYPE) {
13968233facddcc51865d612a919d450db6954aa48e3Michael Kolb                    break;
13978233facddcc51865d612a919d450db6954aa48e3Michael Kolb                }
13988233facddcc51865d612a919d450db6954aa48e3Michael Kolb                // otherwise fall through to handle image part
13998233facddcc51865d612a919d450db6954aa48e3Michael Kolb            case WebView.HitTestResult.IMAGE_TYPE:
14008233facddcc51865d612a919d450db6954aa48e3Michael Kolb                if (type == WebView.HitTestResult.IMAGE_TYPE) {
14018233facddcc51865d612a919d450db6954aa48e3Michael Kolb                    menu.setHeaderTitle(extra);
14028233facddcc51865d612a919d450db6954aa48e3Michael Kolb                }
14038233facddcc51865d612a919d450db6954aa48e3Michael Kolb                menu.findItem(R.id.view_image_context_menu_id).setIntent(
14048233facddcc51865d612a919d450db6954aa48e3Michael Kolb                        new Intent(Intent.ACTION_VIEW, Uri.parse(extra)));
14058233facddcc51865d612a919d450db6954aa48e3Michael Kolb                menu.findItem(R.id.download_context_menu_id).
1406bc5cc75c302eb49d15258155fc6f672fcbd62842Kristian Monsen                        setOnMenuItemClickListener(
1407bc5cc75c302eb49d15258155fc6f672fcbd62842Kristian Monsen                                new Download(mActivity, extra, webview.isPrivateBrowsingEnabled()));
14083527dd1ff849ec4798eab6289593aa404dcae40bJohn Reck                menu.findItem(R.id.set_wallpaper_context_menu_id).
14093527dd1ff849ec4798eab6289593aa404dcae40bJohn Reck                        setOnMenuItemClickListener(new WallpaperHandler(mActivity,
14103527dd1ff849ec4798eab6289593aa404dcae40bJohn Reck                                extra));
14118233facddcc51865d612a919d450db6954aa48e3Michael Kolb                break;
14128233facddcc51865d612a919d450db6954aa48e3Michael Kolb
14138233facddcc51865d612a919d450db6954aa48e3Michael Kolb            default:
14148233facddcc51865d612a919d450db6954aa48e3Michael Kolb                Log.w(LOGTAG, "We should not get here.");
14158233facddcc51865d612a919d450db6954aa48e3Michael Kolb                break;
14168233facddcc51865d612a919d450db6954aa48e3Michael Kolb        }
14178233facddcc51865d612a919d450db6954aa48e3Michael Kolb        //update the ui
14188233facddcc51865d612a919d450db6954aa48e3Michael Kolb        mUi.onContextMenuCreated(menu);
14198233facddcc51865d612a919d450db6954aa48e3Michael Kolb    }
14208233facddcc51865d612a919d450db6954aa48e3Michael Kolb
14218233facddcc51865d612a919d450db6954aa48e3Michael Kolb    /**
14228233facddcc51865d612a919d450db6954aa48e3Michael Kolb     * As the menu can be open when loading state changes
14238233facddcc51865d612a919d450db6954aa48e3Michael Kolb     * we must manually update the state of the stop/reload menu
14248233facddcc51865d612a919d450db6954aa48e3Michael Kolb     * item
14258233facddcc51865d612a919d450db6954aa48e3Michael Kolb     */
14268233facddcc51865d612a919d450db6954aa48e3Michael Kolb    private void updateInLoadMenuItems(Menu menu) {
14278233facddcc51865d612a919d450db6954aa48e3Michael Kolb        if (menu == null) {
14288233facddcc51865d612a919d450db6954aa48e3Michael Kolb            return;
14298233facddcc51865d612a919d450db6954aa48e3Michael Kolb        }
14308233facddcc51865d612a919d450db6954aa48e3Michael Kolb        MenuItem dest = menu.findItem(R.id.stop_reload_menu_id);
14318233facddcc51865d612a919d450db6954aa48e3Michael Kolb        MenuItem src = mInLoad ?
14328233facddcc51865d612a919d450db6954aa48e3Michael Kolb                menu.findItem(R.id.stop_menu_id):
14338233facddcc51865d612a919d450db6954aa48e3Michael Kolb                menu.findItem(R.id.reload_menu_id);
14348233facddcc51865d612a919d450db6954aa48e3Michael Kolb        if (src != null) {
14358233facddcc51865d612a919d450db6954aa48e3Michael Kolb            dest.setIcon(src.getIcon());
14368233facddcc51865d612a919d450db6954aa48e3Michael Kolb            dest.setTitle(src.getTitle());
14378233facddcc51865d612a919d450db6954aa48e3Michael Kolb        }
14388233facddcc51865d612a919d450db6954aa48e3Michael Kolb    }
14398233facddcc51865d612a919d450db6954aa48e3Michael Kolb
1440b3417f0a68a1efc64604ea354ae7f856ce79cb16John Reck    boolean onPrepareOptionsMenu(Menu menu) {
1441b3417f0a68a1efc64604ea354ae7f856ce79cb16John Reck        if (mOptionsMenuHandler != null) {
1442b3417f0a68a1efc64604ea354ae7f856ce79cb16John Reck            return mOptionsMenuHandler.onPrepareOptionsMenu(menu);
1443b3417f0a68a1efc64604ea354ae7f856ce79cb16John Reck        }
14448233facddcc51865d612a919d450db6954aa48e3Michael Kolb        // Note: setVisible will decide whether an item is visible; while
14458233facddcc51865d612a919d450db6954aa48e3Michael Kolb        // setEnabled() will decide whether an item is enabled, which also means
14468233facddcc51865d612a919d450db6954aa48e3Michael Kolb        // whether the matching shortcut key will function.
14478233facddcc51865d612a919d450db6954aa48e3Michael Kolb        switch (mMenuState) {
14488233facddcc51865d612a919d450db6954aa48e3Michael Kolb            case EMPTY_MENU:
14498233facddcc51865d612a919d450db6954aa48e3Michael Kolb                if (mCurrentMenuState != mMenuState) {
14508233facddcc51865d612a919d450db6954aa48e3Michael Kolb                    menu.setGroupVisible(R.id.MAIN_MENU, false);
14518233facddcc51865d612a919d450db6954aa48e3Michael Kolb                    menu.setGroupEnabled(R.id.MAIN_MENU, false);
14528233facddcc51865d612a919d450db6954aa48e3Michael Kolb                    menu.setGroupEnabled(R.id.MAIN_SHORTCUT_MENU, false);
14538233facddcc51865d612a919d450db6954aa48e3Michael Kolb                }
14548233facddcc51865d612a919d450db6954aa48e3Michael Kolb                break;
14558233facddcc51865d612a919d450db6954aa48e3Michael Kolb            default:
14568233facddcc51865d612a919d450db6954aa48e3Michael Kolb                if (mCurrentMenuState != mMenuState) {
14578233facddcc51865d612a919d450db6954aa48e3Michael Kolb                    menu.setGroupVisible(R.id.MAIN_MENU, true);
14588233facddcc51865d612a919d450db6954aa48e3Michael Kolb                    menu.setGroupEnabled(R.id.MAIN_MENU, true);
14598233facddcc51865d612a919d450db6954aa48e3Michael Kolb                    menu.setGroupEnabled(R.id.MAIN_SHORTCUT_MENU, true);
14608233facddcc51865d612a919d450db6954aa48e3Michael Kolb                }
1461ef654f1dd80f55609060005342fc4f2cde62990cJohn Reck                final Tab t = getCurrentTab();
14628233facddcc51865d612a919d450db6954aa48e3Michael Kolb                boolean canGoBack = false;
14638233facddcc51865d612a919d450db6954aa48e3Michael Kolb                boolean canGoForward = false;
14648233facddcc51865d612a919d450db6954aa48e3Michael Kolb                boolean isHome = false;
1465ef654f1dd80f55609060005342fc4f2cde62990cJohn Reck                if (t != null) {
1466ef654f1dd80f55609060005342fc4f2cde62990cJohn Reck                    canGoBack = t.canGoBack();
1467ef654f1dd80f55609060005342fc4f2cde62990cJohn Reck                    canGoForward = t.canGoForward();
1468ef654f1dd80f55609060005342fc4f2cde62990cJohn Reck                    isHome = mSettings.getHomePage().equals(t.getUrl());
14698233facddcc51865d612a919d450db6954aa48e3Michael Kolb                }
14708233facddcc51865d612a919d450db6954aa48e3Michael Kolb                final MenuItem back = menu.findItem(R.id.back_menu_id);
14718233facddcc51865d612a919d450db6954aa48e3Michael Kolb                back.setEnabled(canGoBack);
14728233facddcc51865d612a919d450db6954aa48e3Michael Kolb
14738233facddcc51865d612a919d450db6954aa48e3Michael Kolb                final MenuItem home = menu.findItem(R.id.homepage_menu_id);
14748233facddcc51865d612a919d450db6954aa48e3Michael Kolb                home.setEnabled(!isHome);
14758233facddcc51865d612a919d450db6954aa48e3Michael Kolb
14768233facddcc51865d612a919d450db6954aa48e3Michael Kolb                final MenuItem forward = menu.findItem(R.id.forward_menu_id);
14778233facddcc51865d612a919d450db6954aa48e3Michael Kolb                forward.setEnabled(canGoForward);
14788233facddcc51865d612a919d450db6954aa48e3Michael Kolb
14798233facddcc51865d612a919d450db6954aa48e3Michael Kolb                // decide whether to show the share link option
14808233facddcc51865d612a919d450db6954aa48e3Michael Kolb                PackageManager pm = mActivity.getPackageManager();
14818233facddcc51865d612a919d450db6954aa48e3Michael Kolb                Intent send = new Intent(Intent.ACTION_SEND);
14828233facddcc51865d612a919d450db6954aa48e3Michael Kolb                send.setType("text/plain");
14838233facddcc51865d612a919d450db6954aa48e3Michael Kolb                ResolveInfo ri = pm.resolveActivity(send,
14848233facddcc51865d612a919d450db6954aa48e3Michael Kolb                        PackageManager.MATCH_DEFAULT_ONLY);
14858233facddcc51865d612a919d450db6954aa48e3Michael Kolb                menu.findItem(R.id.share_page_menu_id).setVisible(ri != null);
14868233facddcc51865d612a919d450db6954aa48e3Michael Kolb
148735e9dd6283a2d65687104eb0b3a459c02dcb150bJohn Reck                boolean isNavDump = mSettings.enableNavDump();
14888233facddcc51865d612a919d450db6954aa48e3Michael Kolb                final MenuItem nav = menu.findItem(R.id.dump_nav_menu_id);
14898233facddcc51865d612a919d450db6954aa48e3Michael Kolb                nav.setVisible(isNavDump);
14908233facddcc51865d612a919d450db6954aa48e3Michael Kolb                nav.setEnabled(isNavDump);
14918233facddcc51865d612a919d450db6954aa48e3Michael Kolb
149235e9dd6283a2d65687104eb0b3a459c02dcb150bJohn Reck                boolean showDebugSettings = mSettings.isDebugEnabled();
14938233facddcc51865d612a919d450db6954aa48e3Michael Kolb                final MenuItem counter = menu.findItem(R.id.dump_counters_menu_id);
14948233facddcc51865d612a919d450db6954aa48e3Michael Kolb                counter.setVisible(showDebugSettings);
14958233facddcc51865d612a919d450db6954aa48e3Michael Kolb                counter.setEnabled(showDebugSettings);
14968233facddcc51865d612a919d450db6954aa48e3Michael Kolb
1497b3417f0a68a1efc64604ea354ae7f856ce79cb16John Reck                final MenuItem newtab = menu.findItem(R.id.new_tab_menu_id);
1498b3417f0a68a1efc64604ea354ae7f856ce79cb16John Reck                newtab.setEnabled(getTabControl().canCreateNewTab());
14998233facddcc51865d612a919d450db6954aa48e3Michael Kolb
15002bc8042224be51966d748b870768ec1b376a1621John Reck                MenuItem saveSnapshot = menu.findItem(R.id.save_snapshot_menu_id);
15012bc8042224be51966d748b870768ec1b376a1621John Reck                Tab tab = getCurrentTab();
15022bc8042224be51966d748b870768ec1b376a1621John Reck                saveSnapshot.setVisible(tab != null && !tab.isSnapshot());
15038233facddcc51865d612a919d450db6954aa48e3Michael Kolb                break;
15048233facddcc51865d612a919d450db6954aa48e3Michael Kolb        }
15058233facddcc51865d612a919d450db6954aa48e3Michael Kolb        mCurrentMenuState = mMenuState;
15061acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb        return mUi.onPrepareOptionsMenu(menu);
15078233facddcc51865d612a919d450db6954aa48e3Michael Kolb    }
15088233facddcc51865d612a919d450db6954aa48e3Michael Kolb
15098233facddcc51865d612a919d450db6954aa48e3Michael Kolb    public boolean onOptionsItemSelected(MenuItem item) {
1510b3417f0a68a1efc64604ea354ae7f856ce79cb16John Reck        if (mOptionsMenuHandler != null &&
1511b3417f0a68a1efc64604ea354ae7f856ce79cb16John Reck                mOptionsMenuHandler.onOptionsItemSelected(item)) {
1512b3417f0a68a1efc64604ea354ae7f856ce79cb16John Reck            return true;
1513b3417f0a68a1efc64604ea354ae7f856ce79cb16John Reck        }
1514b3417f0a68a1efc64604ea354ae7f856ce79cb16John Reck
15158233facddcc51865d612a919d450db6954aa48e3Michael Kolb        if (item.getGroupId() != R.id.CONTEXT_MENU) {
15168233facddcc51865d612a919d450db6954aa48e3Michael Kolb            // menu remains active, so ensure comboview is dismissed
15178233facddcc51865d612a919d450db6954aa48e3Michael Kolb            // if main menu option is selected
15188233facddcc51865d612a919d450db6954aa48e3Michael Kolb            removeComboView();
15198233facddcc51865d612a919d450db6954aa48e3Michael Kolb        }
15208233facddcc51865d612a919d450db6954aa48e3Michael Kolb        if (null == getCurrentTopWebView()) {
15218233facddcc51865d612a919d450db6954aa48e3Michael Kolb            return false;
15228233facddcc51865d612a919d450db6954aa48e3Michael Kolb        }
15238233facddcc51865d612a919d450db6954aa48e3Michael Kolb        if (mMenuIsDown) {
15248233facddcc51865d612a919d450db6954aa48e3Michael Kolb            // The shortcut action consumes the MENU. Even if it is still down,
15258233facddcc51865d612a919d450db6954aa48e3Michael Kolb            // it won't trigger the next shortcut action. In the case of the
15268233facddcc51865d612a919d450db6954aa48e3Michael Kolb            // shortcut action triggering a new activity, like Bookmarks, we
15278233facddcc51865d612a919d450db6954aa48e3Michael Kolb            // won't get onKeyUp for MENU. So it is important to reset it here.
15288233facddcc51865d612a919d450db6954aa48e3Michael Kolb            mMenuIsDown = false;
15298233facddcc51865d612a919d450db6954aa48e3Michael Kolb        }
15308233facddcc51865d612a919d450db6954aa48e3Michael Kolb        switch (item.getItemId()) {
15318233facddcc51865d612a919d450db6954aa48e3Michael Kolb            // -- Main menu
15328233facddcc51865d612a919d450db6954aa48e3Michael Kolb            case R.id.new_tab_menu_id:
15338233facddcc51865d612a919d450db6954aa48e3Michael Kolb                openTabToHomePage();
15348233facddcc51865d612a919d450db6954aa48e3Michael Kolb                break;
15358233facddcc51865d612a919d450db6954aa48e3Michael Kolb
15368233facddcc51865d612a919d450db6954aa48e3Michael Kolb            case R.id.incognito_menu_id:
1537519d22840ea587988214a625dc8106e1302ac4a9Michael Kolb                openIncognitoTab();
15388233facddcc51865d612a919d450db6954aa48e3Michael Kolb                break;
15398233facddcc51865d612a919d450db6954aa48e3Michael Kolb
15408233facddcc51865d612a919d450db6954aa48e3Michael Kolb            case R.id.goto_menu_id:
15418233facddcc51865d612a919d450db6954aa48e3Michael Kolb                editUrl();
15428233facddcc51865d612a919d450db6954aa48e3Michael Kolb                break;
15438233facddcc51865d612a919d450db6954aa48e3Michael Kolb
15448233facddcc51865d612a919d450db6954aa48e3Michael Kolb            case R.id.bookmarks_menu_id:
15458233facddcc51865d612a919d450db6954aa48e3Michael Kolb                bookmarksOrHistoryPicker(false);
15468233facddcc51865d612a919d450db6954aa48e3Michael Kolb                break;
15478233facddcc51865d612a919d450db6954aa48e3Michael Kolb
15488233facddcc51865d612a919d450db6954aa48e3Michael Kolb            case R.id.add_bookmark_menu_id:
15493ffc5ca7cd5e79dec9f7d2bb83e6f909d826ff0dJohn Reck                bookmarkCurrentPage(false);
15508233facddcc51865d612a919d450db6954aa48e3Michael Kolb                break;
15518233facddcc51865d612a919d450db6954aa48e3Michael Kolb
15528233facddcc51865d612a919d450db6954aa48e3Michael Kolb            case R.id.stop_reload_menu_id:
15538233facddcc51865d612a919d450db6954aa48e3Michael Kolb                if (mInLoad) {
15548233facddcc51865d612a919d450db6954aa48e3Michael Kolb                    stopLoading();
15558233facddcc51865d612a919d450db6954aa48e3Michael Kolb                } else {
15568233facddcc51865d612a919d450db6954aa48e3Michael Kolb                    getCurrentTopWebView().reload();
15578233facddcc51865d612a919d450db6954aa48e3Michael Kolb                }
15588233facddcc51865d612a919d450db6954aa48e3Michael Kolb                break;
15598233facddcc51865d612a919d450db6954aa48e3Michael Kolb
15608233facddcc51865d612a919d450db6954aa48e3Michael Kolb            case R.id.back_menu_id:
1561ef654f1dd80f55609060005342fc4f2cde62990cJohn Reck                getCurrentTab().goBack();
15628233facddcc51865d612a919d450db6954aa48e3Michael Kolb                break;
15638233facddcc51865d612a919d450db6954aa48e3Michael Kolb
15648233facddcc51865d612a919d450db6954aa48e3Michael Kolb            case R.id.forward_menu_id:
1565ef654f1dd80f55609060005342fc4f2cde62990cJohn Reck                getCurrentTab().goForward();
15668233facddcc51865d612a919d450db6954aa48e3Michael Kolb                break;
15678233facddcc51865d612a919d450db6954aa48e3Michael Kolb
15688233facddcc51865d612a919d450db6954aa48e3Michael Kolb            case R.id.close_menu_id:
15698233facddcc51865d612a919d450db6954aa48e3Michael Kolb                // Close the subwindow if it exists.
15708233facddcc51865d612a919d450db6954aa48e3Michael Kolb                if (mTabControl.getCurrentSubWindow() != null) {
15718233facddcc51865d612a919d450db6954aa48e3Michael Kolb                    dismissSubWindow(mTabControl.getCurrentTab());
15728233facddcc51865d612a919d450db6954aa48e3Michael Kolb                    break;
15738233facddcc51865d612a919d450db6954aa48e3Michael Kolb                }
15748233facddcc51865d612a919d450db6954aa48e3Michael Kolb                closeCurrentTab();
15758233facddcc51865d612a919d450db6954aa48e3Michael Kolb                break;
15768233facddcc51865d612a919d450db6954aa48e3Michael Kolb
15778233facddcc51865d612a919d450db6954aa48e3Michael Kolb            case R.id.homepage_menu_id:
15788233facddcc51865d612a919d450db6954aa48e3Michael Kolb                Tab current = mTabControl.getCurrentTab();
157926b183292dc087b16af10f482744c3bb30e1f163John Reck                loadUrl(current, mSettings.getHomePage());
15808233facddcc51865d612a919d450db6954aa48e3Michael Kolb                break;
15818233facddcc51865d612a919d450db6954aa48e3Michael Kolb
15828233facddcc51865d612a919d450db6954aa48e3Michael Kolb            case R.id.preferences_menu_id:
15838233facddcc51865d612a919d450db6954aa48e3Michael Kolb                Intent intent = new Intent(mActivity, BrowserPreferencesPage.class);
15848233facddcc51865d612a919d450db6954aa48e3Michael Kolb                intent.putExtra(BrowserPreferencesPage.CURRENT_PAGE,
15858233facddcc51865d612a919d450db6954aa48e3Michael Kolb                        getCurrentTopWebView().getUrl());
15868233facddcc51865d612a919d450db6954aa48e3Michael Kolb                mActivity.startActivityForResult(intent, PREFERENCES_PAGE);
15878233facddcc51865d612a919d450db6954aa48e3Michael Kolb                break;
15888233facddcc51865d612a919d450db6954aa48e3Michael Kolb
15898233facddcc51865d612a919d450db6954aa48e3Michael Kolb            case R.id.find_menu_id:
15901c00d5e7b5e7377c995d14106968c59e5761d137Leon Scroggins                getCurrentTopWebView().showFindDialog(null, true);
15918233facddcc51865d612a919d450db6954aa48e3Michael Kolb                break;
15928233facddcc51865d612a919d450db6954aa48e3Michael Kolb
15932bc8042224be51966d748b870768ec1b376a1621John Reck            case R.id.save_snapshot_menu_id:
15942bc8042224be51966d748b870768ec1b376a1621John Reck                final Tab source = getTabControl().getCurrentTab();
1595f33b1637487af3786ee30f295f2c84db6db1e6b3John Reck                if (source == null) break;
1596d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck                final ContentResolver cr = mActivity.getContentResolver();
1597d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck                final ContentValues values = source.createSnapshotValues();
15982bc8042224be51966d748b870768ec1b376a1621John Reck                if (values != null) {
15992bc8042224be51966d748b870768ec1b376a1621John Reck                    new AsyncTask<Tab, Void, Long>() {
16002bc8042224be51966d748b870768ec1b376a1621John Reck
16012bc8042224be51966d748b870768ec1b376a1621John Reck                        @Override
16022bc8042224be51966d748b870768ec1b376a1621John Reck                        protected Long doInBackground(Tab... params) {
16032bc8042224be51966d748b870768ec1b376a1621John Reck                            Uri result = cr.insert(Snapshots.CONTENT_URI, values);
16042bc8042224be51966d748b870768ec1b376a1621John Reck                            long id = ContentUris.parseId(result);
16052bc8042224be51966d748b870768ec1b376a1621John Reck                            return id;
1606d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck                        }
1607f33b1637487af3786ee30f295f2c84db6db1e6b3John Reck
16082bc8042224be51966d748b870768ec1b376a1621John Reck                        @Override
16092bc8042224be51966d748b870768ec1b376a1621John Reck                        protected void onPostExecute(Long id) {
16102bc8042224be51966d748b870768ec1b376a1621John Reck                            Bundle b = new Bundle();
16112bc8042224be51966d748b870768ec1b376a1621John Reck                            b.putLong(BrowserSnapshotPage.EXTRA_ANIMATE_ID, id);
16122bc8042224be51966d748b870768ec1b376a1621John Reck                            mUi.showComboView(ComboViews.Snapshots, b);
16132bc8042224be51966d748b870768ec1b376a1621John Reck                        };
16142bc8042224be51966d748b870768ec1b376a1621John Reck                    }.execute(source);
16152bc8042224be51966d748b870768ec1b376a1621John Reck                } else {
16162bc8042224be51966d748b870768ec1b376a1621John Reck                    Toast.makeText(mActivity, R.string.snapshot_failed,
1617ac993841b3f810dd55a985141c574d4dfebd8c1aLeon Scroggins                            Toast.LENGTH_SHORT).show();
1618ac993841b3f810dd55a985141c574d4dfebd8c1aLeon Scroggins                }
1619ac993841b3f810dd55a985141c574d4dfebd8c1aLeon Scroggins                break;
1620ac993841b3f810dd55a985141c574d4dfebd8c1aLeon Scroggins
16218233facddcc51865d612a919d450db6954aa48e3Michael Kolb            case R.id.page_info_menu_id:
1622ae0c0411bb502976c6374e30c5d1aa4271a64dafHuahui Wu                mPageDialogsHandler.showPageInfo(mTabControl.getCurrentTab(), false, null);
16238233facddcc51865d612a919d450db6954aa48e3Michael Kolb                break;
16248233facddcc51865d612a919d450db6954aa48e3Michael Kolb
16258233facddcc51865d612a919d450db6954aa48e3Michael Kolb            case R.id.classic_history_menu_id:
16268233facddcc51865d612a919d450db6954aa48e3Michael Kolb                bookmarksOrHistoryPicker(true);
16278233facddcc51865d612a919d450db6954aa48e3Michael Kolb                break;
16288233facddcc51865d612a919d450db6954aa48e3Michael Kolb
16298233facddcc51865d612a919d450db6954aa48e3Michael Kolb            case R.id.title_bar_share_page_url:
16308233facddcc51865d612a919d450db6954aa48e3Michael Kolb            case R.id.share_page_menu_id:
16318233facddcc51865d612a919d450db6954aa48e3Michael Kolb                Tab currentTab = mTabControl.getCurrentTab();
16328233facddcc51865d612a919d450db6954aa48e3Michael Kolb                if (null == currentTab) {
16338233facddcc51865d612a919d450db6954aa48e3Michael Kolb                    return false;
16348233facddcc51865d612a919d450db6954aa48e3Michael Kolb                }
1635ba99c5d1a71c384c930152f7c98e2fbe15bd1e85Michael Kolb                shareCurrentPage(currentTab);
16368233facddcc51865d612a919d450db6954aa48e3Michael Kolb                break;
16378233facddcc51865d612a919d450db6954aa48e3Michael Kolb
16388233facddcc51865d612a919d450db6954aa48e3Michael Kolb            case R.id.dump_nav_menu_id:
16398233facddcc51865d612a919d450db6954aa48e3Michael Kolb                getCurrentTopWebView().debugDump();
16408233facddcc51865d612a919d450db6954aa48e3Michael Kolb                break;
16418233facddcc51865d612a919d450db6954aa48e3Michael Kolb
16428233facddcc51865d612a919d450db6954aa48e3Michael Kolb            case R.id.dump_counters_menu_id:
16438233facddcc51865d612a919d450db6954aa48e3Michael Kolb                getCurrentTopWebView().dumpV8Counters();
16448233facddcc51865d612a919d450db6954aa48e3Michael Kolb                break;
16458233facddcc51865d612a919d450db6954aa48e3Michael Kolb
16468233facddcc51865d612a919d450db6954aa48e3Michael Kolb            case R.id.zoom_in_menu_id:
16478233facddcc51865d612a919d450db6954aa48e3Michael Kolb                getCurrentTopWebView().zoomIn();
16488233facddcc51865d612a919d450db6954aa48e3Michael Kolb                break;
16498233facddcc51865d612a919d450db6954aa48e3Michael Kolb
16508233facddcc51865d612a919d450db6954aa48e3Michael Kolb            case R.id.zoom_out_menu_id:
16518233facddcc51865d612a919d450db6954aa48e3Michael Kolb                getCurrentTopWebView().zoomOut();
16528233facddcc51865d612a919d450db6954aa48e3Michael Kolb                break;
16538233facddcc51865d612a919d450db6954aa48e3Michael Kolb
16548233facddcc51865d612a919d450db6954aa48e3Michael Kolb            case R.id.view_downloads_menu_id:
16558233facddcc51865d612a919d450db6954aa48e3Michael Kolb                viewDownloads();
16568233facddcc51865d612a919d450db6954aa48e3Michael Kolb                break;
16578233facddcc51865d612a919d450db6954aa48e3Michael Kolb
16588233facddcc51865d612a919d450db6954aa48e3Michael Kolb            case R.id.window_one_menu_id:
16598233facddcc51865d612a919d450db6954aa48e3Michael Kolb            case R.id.window_two_menu_id:
16608233facddcc51865d612a919d450db6954aa48e3Michael Kolb            case R.id.window_three_menu_id:
16618233facddcc51865d612a919d450db6954aa48e3Michael Kolb            case R.id.window_four_menu_id:
16628233facddcc51865d612a919d450db6954aa48e3Michael Kolb            case R.id.window_five_menu_id:
16638233facddcc51865d612a919d450db6954aa48e3Michael Kolb            case R.id.window_six_menu_id:
16648233facddcc51865d612a919d450db6954aa48e3Michael Kolb            case R.id.window_seven_menu_id:
16658233facddcc51865d612a919d450db6954aa48e3Michael Kolb            case R.id.window_eight_menu_id:
16668233facddcc51865d612a919d450db6954aa48e3Michael Kolb                {
16678233facddcc51865d612a919d450db6954aa48e3Michael Kolb                    int menuid = item.getItemId();
16688233facddcc51865d612a919d450db6954aa48e3Michael Kolb                    for (int id = 0; id < WINDOW_SHORTCUT_ID_ARRAY.length; id++) {
16698233facddcc51865d612a919d450db6954aa48e3Michael Kolb                        if (WINDOW_SHORTCUT_ID_ARRAY[id] == menuid) {
16708233facddcc51865d612a919d450db6954aa48e3Michael Kolb                            Tab desiredTab = mTabControl.getTab(id);
16718233facddcc51865d612a919d450db6954aa48e3Michael Kolb                            if (desiredTab != null &&
16728233facddcc51865d612a919d450db6954aa48e3Michael Kolb                                    desiredTab != mTabControl.getCurrentTab()) {
1673c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb                                switchToTab(desiredTab);
16748233facddcc51865d612a919d450db6954aa48e3Michael Kolb                            }
16758233facddcc51865d612a919d450db6954aa48e3Michael Kolb                            break;
16768233facddcc51865d612a919d450db6954aa48e3Michael Kolb                        }
16778233facddcc51865d612a919d450db6954aa48e3Michael Kolb                    }
16788233facddcc51865d612a919d450db6954aa48e3Michael Kolb                }
16798233facddcc51865d612a919d450db6954aa48e3Michael Kolb                break;
16808233facddcc51865d612a919d450db6954aa48e3Michael Kolb
16818233facddcc51865d612a919d450db6954aa48e3Michael Kolb            default:
16828233facddcc51865d612a919d450db6954aa48e3Michael Kolb                return false;
16838233facddcc51865d612a919d450db6954aa48e3Michael Kolb        }
16848233facddcc51865d612a919d450db6954aa48e3Michael Kolb        return true;
16858233facddcc51865d612a919d450db6954aa48e3Michael Kolb    }
16868233facddcc51865d612a919d450db6954aa48e3Michael Kolb
16878233facddcc51865d612a919d450db6954aa48e3Michael Kolb    public boolean onContextItemSelected(MenuItem item) {
1688dbf57df890f091286f0107933b0034d39629a9a8John Reck        // Let the History and Bookmark fragments handle menus they created.
1689dbf57df890f091286f0107933b0034d39629a9a8John Reck        if (item.getGroupId() == R.id.CONTEXT_MENU) {
1690dbf57df890f091286f0107933b0034d39629a9a8John Reck            return false;
1691dbf57df890f091286f0107933b0034d39629a9a8John Reck        }
1692dbf57df890f091286f0107933b0034d39629a9a8John Reck
16938233facddcc51865d612a919d450db6954aa48e3Michael Kolb        int id = item.getItemId();
16948233facddcc51865d612a919d450db6954aa48e3Michael Kolb        boolean result = true;
16958233facddcc51865d612a919d450db6954aa48e3Michael Kolb        switch (id) {
16968233facddcc51865d612a919d450db6954aa48e3Michael Kolb            // For the context menu from the title bar
16978233facddcc51865d612a919d450db6954aa48e3Michael Kolb            case R.id.title_bar_copy_page_url:
16988233facddcc51865d612a919d450db6954aa48e3Michael Kolb                Tab currentTab = mTabControl.getCurrentTab();
16998233facddcc51865d612a919d450db6954aa48e3Michael Kolb                if (null == currentTab) {
17008233facddcc51865d612a919d450db6954aa48e3Michael Kolb                    result = false;
17018233facddcc51865d612a919d450db6954aa48e3Michael Kolb                    break;
17028233facddcc51865d612a919d450db6954aa48e3Michael Kolb                }
17038233facddcc51865d612a919d450db6954aa48e3Michael Kolb                WebView mainView = currentTab.getWebView();
17048233facddcc51865d612a919d450db6954aa48e3Michael Kolb                if (null == mainView) {
17058233facddcc51865d612a919d450db6954aa48e3Michael Kolb                    result = false;
17068233facddcc51865d612a919d450db6954aa48e3Michael Kolb                    break;
17078233facddcc51865d612a919d450db6954aa48e3Michael Kolb                }
17088233facddcc51865d612a919d450db6954aa48e3Michael Kolb                copy(mainView.getUrl());
17098233facddcc51865d612a919d450db6954aa48e3Michael Kolb                break;
17108233facddcc51865d612a919d450db6954aa48e3Michael Kolb            // -- Browser context menu
17118233facddcc51865d612a919d450db6954aa48e3Michael Kolb            case R.id.open_context_menu_id:
17128233facddcc51865d612a919d450db6954aa48e3Michael Kolb            case R.id.save_link_context_menu_id:
17138233facddcc51865d612a919d450db6954aa48e3Michael Kolb            case R.id.copy_link_context_menu_id:
17148233facddcc51865d612a919d450db6954aa48e3Michael Kolb                final WebView webView = getCurrentTopWebView();
17158233facddcc51865d612a919d450db6954aa48e3Michael Kolb                if (null == webView) {
17168233facddcc51865d612a919d450db6954aa48e3Michael Kolb                    result = false;
17178233facddcc51865d612a919d450db6954aa48e3Michael Kolb                    break;
17188233facddcc51865d612a919d450db6954aa48e3Michael Kolb                }
17198233facddcc51865d612a919d450db6954aa48e3Michael Kolb                final HashMap<String, WebView> hrefMap =
17208233facddcc51865d612a919d450db6954aa48e3Michael Kolb                        new HashMap<String, WebView>();
17218233facddcc51865d612a919d450db6954aa48e3Michael Kolb                hrefMap.put("webview", webView);
17228233facddcc51865d612a919d450db6954aa48e3Michael Kolb                final Message msg = mHandler.obtainMessage(
17238233facddcc51865d612a919d450db6954aa48e3Michael Kolb                        FOCUS_NODE_HREF, id, 0, hrefMap);
17248233facddcc51865d612a919d450db6954aa48e3Michael Kolb                webView.requestFocusNodeHref(msg);
17258233facddcc51865d612a919d450db6954aa48e3Michael Kolb                break;
17268233facddcc51865d612a919d450db6954aa48e3Michael Kolb
17278233facddcc51865d612a919d450db6954aa48e3Michael Kolb            default:
17288233facddcc51865d612a919d450db6954aa48e3Michael Kolb                // For other context menus
17298233facddcc51865d612a919d450db6954aa48e3Michael Kolb                result = onOptionsItemSelected(item);
17308233facddcc51865d612a919d450db6954aa48e3Michael Kolb        }
17318233facddcc51865d612a919d450db6954aa48e3Michael Kolb        return result;
17328233facddcc51865d612a919d450db6954aa48e3Michael Kolb    }
17338233facddcc51865d612a919d450db6954aa48e3Michael Kolb
17348233facddcc51865d612a919d450db6954aa48e3Michael Kolb    /**
17358233facddcc51865d612a919d450db6954aa48e3Michael Kolb     * support programmatically opening the context menu
17368233facddcc51865d612a919d450db6954aa48e3Michael Kolb     */
17378233facddcc51865d612a919d450db6954aa48e3Michael Kolb    public void openContextMenu(View view) {
17388233facddcc51865d612a919d450db6954aa48e3Michael Kolb        mActivity.openContextMenu(view);
17398233facddcc51865d612a919d450db6954aa48e3Michael Kolb    }
17408233facddcc51865d612a919d450db6954aa48e3Michael Kolb
17418233facddcc51865d612a919d450db6954aa48e3Michael Kolb    /**
17428233facddcc51865d612a919d450db6954aa48e3Michael Kolb     * programmatically open the options menu
17438233facddcc51865d612a919d450db6954aa48e3Michael Kolb     */
17448233facddcc51865d612a919d450db6954aa48e3Michael Kolb    public void openOptionsMenu() {
17458233facddcc51865d612a919d450db6954aa48e3Michael Kolb        mActivity.openOptionsMenu();
17468233facddcc51865d612a919d450db6954aa48e3Michael Kolb    }
17478233facddcc51865d612a919d450db6954aa48e3Michael Kolb
17488233facddcc51865d612a919d450db6954aa48e3Michael Kolb    public boolean onMenuOpened(int featureId, Menu menu) {
17498233facddcc51865d612a919d450db6954aa48e3Michael Kolb        if (mOptionsMenuOpen) {
17508233facddcc51865d612a919d450db6954aa48e3Michael Kolb            if (mConfigChanged) {
17518233facddcc51865d612a919d450db6954aa48e3Michael Kolb                // We do not need to make any changes to the state of the
17528233facddcc51865d612a919d450db6954aa48e3Michael Kolb                // title bar, since the only thing that happened was a
17538233facddcc51865d612a919d450db6954aa48e3Michael Kolb                // change in orientation
17548233facddcc51865d612a919d450db6954aa48e3Michael Kolb                mConfigChanged = false;
17558233facddcc51865d612a919d450db6954aa48e3Michael Kolb            } else {
17568233facddcc51865d612a919d450db6954aa48e3Michael Kolb                if (!mExtendedMenuOpen) {
17578233facddcc51865d612a919d450db6954aa48e3Michael Kolb                    mExtendedMenuOpen = true;
17588233facddcc51865d612a919d450db6954aa48e3Michael Kolb                    mUi.onExtendedMenuOpened();
17598233facddcc51865d612a919d450db6954aa48e3Michael Kolb                } else {
17608233facddcc51865d612a919d450db6954aa48e3Michael Kolb                    // Switching the menu back to icon view, so show the
17618233facddcc51865d612a919d450db6954aa48e3Michael Kolb                    // title bar once again.
17628233facddcc51865d612a919d450db6954aa48e3Michael Kolb                    mExtendedMenuOpen = false;
17638233facddcc51865d612a919d450db6954aa48e3Michael Kolb                    mUi.onExtendedMenuClosed(mInLoad);
17648233facddcc51865d612a919d450db6954aa48e3Michael Kolb                }
17658233facddcc51865d612a919d450db6954aa48e3Michael Kolb            }
17668233facddcc51865d612a919d450db6954aa48e3Michael Kolb        } else {
17678233facddcc51865d612a919d450db6954aa48e3Michael Kolb            // The options menu is closed, so open it, and show the title
17688233facddcc51865d612a919d450db6954aa48e3Michael Kolb            mOptionsMenuOpen = true;
17698233facddcc51865d612a919d450db6954aa48e3Michael Kolb            mConfigChanged = false;
17708233facddcc51865d612a919d450db6954aa48e3Michael Kolb            mExtendedMenuOpen = false;
17718233facddcc51865d612a919d450db6954aa48e3Michael Kolb            mUi.onOptionsMenuOpened();
17728233facddcc51865d612a919d450db6954aa48e3Michael Kolb        }
17738233facddcc51865d612a919d450db6954aa48e3Michael Kolb        return true;
17748233facddcc51865d612a919d450db6954aa48e3Michael Kolb    }
17758233facddcc51865d612a919d450db6954aa48e3Michael Kolb
17768233facddcc51865d612a919d450db6954aa48e3Michael Kolb    public void onOptionsMenuClosed(Menu menu) {
17778233facddcc51865d612a919d450db6954aa48e3Michael Kolb        mOptionsMenuOpen = false;
17788233facddcc51865d612a919d450db6954aa48e3Michael Kolb        mUi.onOptionsMenuClosed(mInLoad);
17798233facddcc51865d612a919d450db6954aa48e3Michael Kolb    }
17808233facddcc51865d612a919d450db6954aa48e3Michael Kolb
17818233facddcc51865d612a919d450db6954aa48e3Michael Kolb    public void onContextMenuClosed(Menu menu) {
17828233facddcc51865d612a919d450db6954aa48e3Michael Kolb        mUi.onContextMenuClosed(menu, mInLoad);
17838233facddcc51865d612a919d450db6954aa48e3Michael Kolb    }
17848233facddcc51865d612a919d450db6954aa48e3Michael Kolb
17858233facddcc51865d612a919d450db6954aa48e3Michael Kolb    // Helper method for getting the top window.
17868233facddcc51865d612a919d450db6954aa48e3Michael Kolb    @Override
17878233facddcc51865d612a919d450db6954aa48e3Michael Kolb    public WebView getCurrentTopWebView() {
17888233facddcc51865d612a919d450db6954aa48e3Michael Kolb        return mTabControl.getCurrentTopWebView();
17898233facddcc51865d612a919d450db6954aa48e3Michael Kolb    }
17908233facddcc51865d612a919d450db6954aa48e3Michael Kolb
17918233facddcc51865d612a919d450db6954aa48e3Michael Kolb    @Override
17928233facddcc51865d612a919d450db6954aa48e3Michael Kolb    public WebView getCurrentWebView() {
17938233facddcc51865d612a919d450db6954aa48e3Michael Kolb        return mTabControl.getCurrentWebView();
17948233facddcc51865d612a919d450db6954aa48e3Michael Kolb    }
17958233facddcc51865d612a919d450db6954aa48e3Michael Kolb
17968233facddcc51865d612a919d450db6954aa48e3Michael Kolb    /*
17978233facddcc51865d612a919d450db6954aa48e3Michael Kolb     * This method is called as a result of the user selecting the options
17988233facddcc51865d612a919d450db6954aa48e3Michael Kolb     * menu to see the download window. It shows the download window on top of
17998233facddcc51865d612a919d450db6954aa48e3Michael Kolb     * the current window.
18008233facddcc51865d612a919d450db6954aa48e3Michael Kolb     */
18018233facddcc51865d612a919d450db6954aa48e3Michael Kolb    void viewDownloads() {
18028233facddcc51865d612a919d450db6954aa48e3Michael Kolb        Intent intent = new Intent(DownloadManager.ACTION_VIEW_DOWNLOADS);
18038233facddcc51865d612a919d450db6954aa48e3Michael Kolb        mActivity.startActivity(intent);
18048233facddcc51865d612a919d450db6954aa48e3Michael Kolb    }
18058233facddcc51865d612a919d450db6954aa48e3Michael Kolb
18068233facddcc51865d612a919d450db6954aa48e3Michael Kolb    // action mode
18078233facddcc51865d612a919d450db6954aa48e3Michael Kolb
18088233facddcc51865d612a919d450db6954aa48e3Michael Kolb    void onActionModeStarted(ActionMode mode) {
18098233facddcc51865d612a919d450db6954aa48e3Michael Kolb        mUi.onActionModeStarted(mode);
18108233facddcc51865d612a919d450db6954aa48e3Michael Kolb        mActionMode = mode;
18118233facddcc51865d612a919d450db6954aa48e3Michael Kolb    }
18128233facddcc51865d612a919d450db6954aa48e3Michael Kolb
18138233facddcc51865d612a919d450db6954aa48e3Michael Kolb    /*
18148233facddcc51865d612a919d450db6954aa48e3Michael Kolb     * True if a custom ActionMode (i.e. find or select) is in use.
18158233facddcc51865d612a919d450db6954aa48e3Michael Kolb     */
18168233facddcc51865d612a919d450db6954aa48e3Michael Kolb    @Override
18178233facddcc51865d612a919d450db6954aa48e3Michael Kolb    public boolean isInCustomActionMode() {
18188233facddcc51865d612a919d450db6954aa48e3Michael Kolb        return mActionMode != null;
18198233facddcc51865d612a919d450db6954aa48e3Michael Kolb    }
18208233facddcc51865d612a919d450db6954aa48e3Michael Kolb
18218233facddcc51865d612a919d450db6954aa48e3Michael Kolb    /*
18228233facddcc51865d612a919d450db6954aa48e3Michael Kolb     * End the current ActionMode.
18238233facddcc51865d612a919d450db6954aa48e3Michael Kolb     */
18248233facddcc51865d612a919d450db6954aa48e3Michael Kolb    @Override
18258233facddcc51865d612a919d450db6954aa48e3Michael Kolb    public void endActionMode() {
18268233facddcc51865d612a919d450db6954aa48e3Michael Kolb        if (mActionMode != null) {
18278233facddcc51865d612a919d450db6954aa48e3Michael Kolb            mActionMode.finish();
18288233facddcc51865d612a919d450db6954aa48e3Michael Kolb        }
18298233facddcc51865d612a919d450db6954aa48e3Michael Kolb    }
18308233facddcc51865d612a919d450db6954aa48e3Michael Kolb
18318233facddcc51865d612a919d450db6954aa48e3Michael Kolb    /*
18328233facddcc51865d612a919d450db6954aa48e3Michael Kolb     * Called by find and select when they are finished.  Replace title bars
18338233facddcc51865d612a919d450db6954aa48e3Michael Kolb     * as necessary.
18348233facddcc51865d612a919d450db6954aa48e3Michael Kolb     */
18358233facddcc51865d612a919d450db6954aa48e3Michael Kolb    public void onActionModeFinished(ActionMode mode) {
18368233facddcc51865d612a919d450db6954aa48e3Michael Kolb        if (!isInCustomActionMode()) return;
18378233facddcc51865d612a919d450db6954aa48e3Michael Kolb        mUi.onActionModeFinished(mInLoad);
18388233facddcc51865d612a919d450db6954aa48e3Michael Kolb        mActionMode = null;
18398233facddcc51865d612a919d450db6954aa48e3Michael Kolb    }
18408233facddcc51865d612a919d450db6954aa48e3Michael Kolb
18418233facddcc51865d612a919d450db6954aa48e3Michael Kolb    boolean isInLoad() {
18428233facddcc51865d612a919d450db6954aa48e3Michael Kolb        return mInLoad;
18438233facddcc51865d612a919d450db6954aa48e3Michael Kolb    }
18448233facddcc51865d612a919d450db6954aa48e3Michael Kolb
18458233facddcc51865d612a919d450db6954aa48e3Michael Kolb    // bookmark handling
18468233facddcc51865d612a919d450db6954aa48e3Michael Kolb
18478233facddcc51865d612a919d450db6954aa48e3Michael Kolb    /**
18488233facddcc51865d612a919d450db6954aa48e3Michael Kolb     * add the current page as a bookmark to the given folder id
18498233facddcc51865d612a919d450db6954aa48e3Michael Kolb     * @param folderId use -1 for the default folder
1850bdff8a72bd9894fc59ca658442e6ead37a56fa5dLeon Scroggins     * @param canBeAnEdit If true, check to see whether the site is already
1851bdff8a72bd9894fc59ca658442e6ead37a56fa5dLeon Scroggins     *          bookmarked, and if it is, edit that bookmark.  If false, and
1852bdff8a72bd9894fc59ca658442e6ead37a56fa5dLeon Scroggins     *          the site is already bookmarked, do not attempt to edit the
1853bdff8a72bd9894fc59ca658442e6ead37a56fa5dLeon Scroggins     *          existing bookmark.
18548233facddcc51865d612a919d450db6954aa48e3Michael Kolb     */
18558233facddcc51865d612a919d450db6954aa48e3Michael Kolb    @Override
18563ffc5ca7cd5e79dec9f7d2bb83e6f909d826ff0dJohn Reck    public void bookmarkCurrentPage(boolean canBeAnEdit) {
18578233facddcc51865d612a919d450db6954aa48e3Michael Kolb        Intent i = new Intent(mActivity,
18588233facddcc51865d612a919d450db6954aa48e3Michael Kolb                AddBookmarkPage.class);
18598233facddcc51865d612a919d450db6954aa48e3Michael Kolb        WebView w = getCurrentTopWebView();
18608233facddcc51865d612a919d450db6954aa48e3Michael Kolb        i.putExtra(BrowserContract.Bookmarks.URL, w.getUrl());
18618233facddcc51865d612a919d450db6954aa48e3Michael Kolb        i.putExtra(BrowserContract.Bookmarks.TITLE, w.getTitle());
18628233facddcc51865d612a919d450db6954aa48e3Michael Kolb        String touchIconUrl = w.getTouchIconUrl();
18638233facddcc51865d612a919d450db6954aa48e3Michael Kolb        if (touchIconUrl != null) {
18648233facddcc51865d612a919d450db6954aa48e3Michael Kolb            i.putExtra(AddBookmarkPage.TOUCH_ICON_URL, touchIconUrl);
18658233facddcc51865d612a919d450db6954aa48e3Michael Kolb            WebSettings settings = w.getSettings();
18668233facddcc51865d612a919d450db6954aa48e3Michael Kolb            if (settings != null) {
18678233facddcc51865d612a919d450db6954aa48e3Michael Kolb                i.putExtra(AddBookmarkPage.USER_AGENT,
18688233facddcc51865d612a919d450db6954aa48e3Michael Kolb                        settings.getUserAgentString());
18698233facddcc51865d612a919d450db6954aa48e3Michael Kolb            }
18708233facddcc51865d612a919d450db6954aa48e3Michael Kolb        }
18718233facddcc51865d612a919d450db6954aa48e3Michael Kolb        i.putExtra(BrowserContract.Bookmarks.THUMBNAIL,
18728233facddcc51865d612a919d450db6954aa48e3Michael Kolb                createScreenshot(w, getDesiredThumbnailWidth(mActivity),
18738233facddcc51865d612a919d450db6954aa48e3Michael Kolb                getDesiredThumbnailHeight(mActivity)));
18748233facddcc51865d612a919d450db6954aa48e3Michael Kolb        i.putExtra(BrowserContract.Bookmarks.FAVICON, w.getFavicon());
1875bdff8a72bd9894fc59ca658442e6ead37a56fa5dLeon Scroggins        if (canBeAnEdit) {
1876bdff8a72bd9894fc59ca658442e6ead37a56fa5dLeon Scroggins            i.putExtra(AddBookmarkPage.CHECK_FOR_DUPE, true);
1877bdff8a72bd9894fc59ca658442e6ead37a56fa5dLeon Scroggins        }
18788233facddcc51865d612a919d450db6954aa48e3Michael Kolb        // Put the dialog at the upper right of the screen, covering the
18798233facddcc51865d612a919d450db6954aa48e3Michael Kolb        // star on the title bar.
18808233facddcc51865d612a919d450db6954aa48e3Michael Kolb        i.putExtra("gravity", Gravity.RIGHT | Gravity.TOP);
18818233facddcc51865d612a919d450db6954aa48e3Michael Kolb        mActivity.startActivity(i);
18828233facddcc51865d612a919d450db6954aa48e3Michael Kolb    }
18838233facddcc51865d612a919d450db6954aa48e3Michael Kolb
18848233facddcc51865d612a919d450db6954aa48e3Michael Kolb    // file chooser
18858233facddcc51865d612a919d450db6954aa48e3Michael Kolb    public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType) {
18868233facddcc51865d612a919d450db6954aa48e3Michael Kolb        mUploadHandler = new UploadHandler(this);
18878233facddcc51865d612a919d450db6954aa48e3Michael Kolb        mUploadHandler.openFileChooser(uploadMsg, acceptType);
18888233facddcc51865d612a919d450db6954aa48e3Michael Kolb    }
18898233facddcc51865d612a919d450db6954aa48e3Michael Kolb
18908233facddcc51865d612a919d450db6954aa48e3Michael Kolb    // thumbnails
18918233facddcc51865d612a919d450db6954aa48e3Michael Kolb
18928233facddcc51865d612a919d450db6954aa48e3Michael Kolb    /**
18938233facddcc51865d612a919d450db6954aa48e3Michael Kolb     * Return the desired width for thumbnail screenshots, which are stored in
18948233facddcc51865d612a919d450db6954aa48e3Michael Kolb     * the database, and used on the bookmarks screen.
18958233facddcc51865d612a919d450db6954aa48e3Michael Kolb     * @param context Context for finding out the density of the screen.
18968233facddcc51865d612a919d450db6954aa48e3Michael Kolb     * @return desired width for thumbnail screenshot.
18978233facddcc51865d612a919d450db6954aa48e3Michael Kolb     */
18988233facddcc51865d612a919d450db6954aa48e3Michael Kolb    static int getDesiredThumbnailWidth(Context context) {
18998233facddcc51865d612a919d450db6954aa48e3Michael Kolb        return context.getResources().getDimensionPixelOffset(
19008233facddcc51865d612a919d450db6954aa48e3Michael Kolb                R.dimen.bookmarkThumbnailWidth);
19018233facddcc51865d612a919d450db6954aa48e3Michael Kolb    }
19028233facddcc51865d612a919d450db6954aa48e3Michael Kolb
19038233facddcc51865d612a919d450db6954aa48e3Michael Kolb    /**
19048233facddcc51865d612a919d450db6954aa48e3Michael Kolb     * Return the desired height for thumbnail screenshots, which are stored in
19058233facddcc51865d612a919d450db6954aa48e3Michael Kolb     * the database, and used on the bookmarks screen.
19068233facddcc51865d612a919d450db6954aa48e3Michael Kolb     * @param context Context for finding out the density of the screen.
19078233facddcc51865d612a919d450db6954aa48e3Michael Kolb     * @return desired height for thumbnail screenshot.
19088233facddcc51865d612a919d450db6954aa48e3Michael Kolb     */
19098233facddcc51865d612a919d450db6954aa48e3Michael Kolb    static int getDesiredThumbnailHeight(Context context) {
19108233facddcc51865d612a919d450db6954aa48e3Michael Kolb        return context.getResources().getDimensionPixelOffset(
19118233facddcc51865d612a919d450db6954aa48e3Michael Kolb                R.dimen.bookmarkThumbnailHeight);
19128233facddcc51865d612a919d450db6954aa48e3Michael Kolb    }
19138233facddcc51865d612a919d450db6954aa48e3Michael Kolb
19141acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb    static Bitmap createScreenshot(Tab tab, int width, int height) {
19151acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb        if ((tab != null) && (tab.getWebView() != null)) {
19161acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb            return createScreenshot(tab.getWebView(), width, height);
19171acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb        }
19181acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb        return null;
19191acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb    }
19201acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb
19218cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck    static Bitmap createScreenshot(WebView view, int width, int height) {
19225c6ac2f0bc02b9e91154f7c0b82a67c0a7bdd9b9John Reck        // We render to a bitmap 2x the desired size so that we can then
19235c6ac2f0bc02b9e91154f7c0b82a67c0a7bdd9b9John Reck        // re-scale it with filtering since canvas.scale doesn't filter
19245c6ac2f0bc02b9e91154f7c0b82a67c0a7bdd9b9John Reck        // This helps reduce aliasing at the cost of being slightly blurry
19255c6ac2f0bc02b9e91154f7c0b82a67c0a7bdd9b9John Reck        final int filter_scale = 2;
19268233facddcc51865d612a919d450db6954aa48e3Michael Kolb        Picture thumbnail = view.capturePicture();
19278233facddcc51865d612a919d450db6954aa48e3Michael Kolb        if (thumbnail == null) {
19288233facddcc51865d612a919d450db6954aa48e3Michael Kolb            return null;
19298233facddcc51865d612a919d450db6954aa48e3Michael Kolb        }
19305c6ac2f0bc02b9e91154f7c0b82a67c0a7bdd9b9John Reck        width *= filter_scale;
19315c6ac2f0bc02b9e91154f7c0b82a67c0a7bdd9b9John Reck        height *= filter_scale;
19328233facddcc51865d612a919d450db6954aa48e3Michael Kolb        Bitmap bm = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);
19338233facddcc51865d612a919d450db6954aa48e3Michael Kolb        Canvas canvas = new Canvas(bm);
19348233facddcc51865d612a919d450db6954aa48e3Michael Kolb        // May need to tweak these values to determine what is the
19358233facddcc51865d612a919d450db6954aa48e3Michael Kolb        // best scale factor
19368233facddcc51865d612a919d450db6954aa48e3Michael Kolb        int thumbnailWidth = thumbnail.getWidth();
19378233facddcc51865d612a919d450db6954aa48e3Michael Kolb        int thumbnailHeight = thumbnail.getHeight();
1938fe49ab43d138ee52c04de77729870daf2a890c46John Reck        float scaleFactor = 1.0f;
1939eb95db48b01b3db935601f25bd1a2358674b76daMichael Kolb        if (thumbnailWidth > 0 && thumbnailHeight > 0) {
1940fe49ab43d138ee52c04de77729870daf2a890c46John Reck            scaleFactor = (float) width / (float)thumbnailWidth;
19418233facddcc51865d612a919d450db6954aa48e3Michael Kolb        } else {
19428233facddcc51865d612a919d450db6954aa48e3Michael Kolb            return null;
19438233facddcc51865d612a919d450db6954aa48e3Michael Kolb        }
1944fe49ab43d138ee52c04de77729870daf2a890c46John Reck
1945eb95db48b01b3db935601f25bd1a2358674b76daMichael Kolb        float scaleFactorY = (float) height / (float)thumbnailHeight;
1946eb95db48b01b3db935601f25bd1a2358674b76daMichael Kolb        if (scaleFactorY > scaleFactor) {
1947eb95db48b01b3db935601f25bd1a2358674b76daMichael Kolb            // The picture is narrower than the requested AR
1948eb95db48b01b3db935601f25bd1a2358674b76daMichael Kolb            // Center the thumnail and crop the sides
1949eb95db48b01b3db935601f25bd1a2358674b76daMichael Kolb            scaleFactor = scaleFactorY;
1950fe49ab43d138ee52c04de77729870daf2a890c46John Reck            float wx = (thumbnailWidth * scaleFactor) - width;
1951fe49ab43d138ee52c04de77729870daf2a890c46John Reck            canvas.translate((int) -(wx / 2), 0);
19528233facddcc51865d612a919d450db6954aa48e3Michael Kolb        }
19538233facddcc51865d612a919d450db6954aa48e3Michael Kolb
1954fe49ab43d138ee52c04de77729870daf2a890c46John Reck        canvas.scale(scaleFactor, scaleFactor);
19558233facddcc51865d612a919d450db6954aa48e3Michael Kolb
19568233facddcc51865d612a919d450db6954aa48e3Michael Kolb        thumbnail.draw(canvas);
19575c6ac2f0bc02b9e91154f7c0b82a67c0a7bdd9b9John Reck        Bitmap ret = Bitmap.createScaledBitmap(bm, width / filter_scale,
19585c6ac2f0bc02b9e91154f7c0b82a67c0a7bdd9b9John Reck                height / filter_scale, true);
19595c6ac2f0bc02b9e91154f7c0b82a67c0a7bdd9b9John Reck        bm.recycle();
19605c6ac2f0bc02b9e91154f7c0b82a67c0a7bdd9b9John Reck        return ret;
19618233facddcc51865d612a919d450db6954aa48e3Michael Kolb    }
19628233facddcc51865d612a919d450db6954aa48e3Michael Kolb
196334ef26756a751b99b5c021ee2b9221c582c88208John Reck    private void updateScreenshot(Tab tab) {
19648233facddcc51865d612a919d450db6954aa48e3Michael Kolb        // If this is a bookmarked site, add a screenshot to the database.
19658233facddcc51865d612a919d450db6954aa48e3Michael Kolb        // FIXME: Would like to make sure there is actually something to
19668233facddcc51865d612a919d450db6954aa48e3Michael Kolb        // draw, but the API for that (WebViewCore.pictureReady()) is not
19678233facddcc51865d612a919d450db6954aa48e3Michael Kolb        // currently accessible here.
19688233facddcc51865d612a919d450db6954aa48e3Michael Kolb
196934ef26756a751b99b5c021ee2b9221c582c88208John Reck        WebView view = tab.getWebView();
19707a59120d6e25f9f6ae9a5f7e0cb177a9f4775d54John Reck        if (view == null) {
19717a59120d6e25f9f6ae9a5f7e0cb177a9f4775d54John Reck            // Tab was destroyed
19727a59120d6e25f9f6ae9a5f7e0cb177a9f4775d54John Reck            return;
19737a59120d6e25f9f6ae9a5f7e0cb177a9f4775d54John Reck        }
197434ef26756a751b99b5c021ee2b9221c582c88208John Reck        final String url = tab.getUrl();
197534ef26756a751b99b5c021ee2b9221c582c88208John Reck        final String originalUrl = view.getOriginalUrl();
197634ef26756a751b99b5c021ee2b9221c582c88208John Reck
197734ef26756a751b99b5c021ee2b9221c582c88208John Reck        if (TextUtils.isEmpty(url)) {
197834ef26756a751b99b5c021ee2b9221c582c88208John Reck            return;
197934ef26756a751b99b5c021ee2b9221c582c88208John Reck        }
198034ef26756a751b99b5c021ee2b9221c582c88208John Reck
198134ef26756a751b99b5c021ee2b9221c582c88208John Reck        // Only update thumbnails for web urls (http(s)://), not for
198234ef26756a751b99b5c021ee2b9221c582c88208John Reck        // about:, javascript:, data:, etc...
198334ef26756a751b99b5c021ee2b9221c582c88208John Reck        // Unless it is a bookmarked site, then always update
198434ef26756a751b99b5c021ee2b9221c582c88208John Reck        if (!Patterns.WEB_URL.matcher(url).matches() && !tab.isBookmarkedSite()) {
198534ef26756a751b99b5c021ee2b9221c582c88208John Reck            return;
198634ef26756a751b99b5c021ee2b9221c582c88208John Reck        }
198734ef26756a751b99b5c021ee2b9221c582c88208John Reck
19888233facddcc51865d612a919d450db6954aa48e3Michael Kolb        final Bitmap bm = createScreenshot(view, getDesiredThumbnailWidth(mActivity),
19898233facddcc51865d612a919d450db6954aa48e3Michael Kolb                getDesiredThumbnailHeight(mActivity));
19908233facddcc51865d612a919d450db6954aa48e3Michael Kolb        if (bm == null) {
19918233facddcc51865d612a919d450db6954aa48e3Michael Kolb            return;
19928233facddcc51865d612a919d450db6954aa48e3Michael Kolb        }
19938233facddcc51865d612a919d450db6954aa48e3Michael Kolb
19948233facddcc51865d612a919d450db6954aa48e3Michael Kolb        final ContentResolver cr = mActivity.getContentResolver();
199534ef26756a751b99b5c021ee2b9221c582c88208John Reck        new AsyncTask<Void, Void, Void>() {
199634ef26756a751b99b5c021ee2b9221c582c88208John Reck            @Override
199734ef26756a751b99b5c021ee2b9221c582c88208John Reck            protected Void doInBackground(Void... unused) {
199834ef26756a751b99b5c021ee2b9221c582c88208John Reck                Cursor cursor = null;
199934ef26756a751b99b5c021ee2b9221c582c88208John Reck                try {
200034ef26756a751b99b5c021ee2b9221c582c88208John Reck                    // TODO: Clean this up
200134ef26756a751b99b5c021ee2b9221c582c88208John Reck                    cursor = Bookmarks.queryCombinedForUrl(cr, originalUrl, url);
200234ef26756a751b99b5c021ee2b9221c582c88208John Reck                    if (cursor != null && cursor.moveToFirst()) {
200334ef26756a751b99b5c021ee2b9221c582c88208John Reck                        final ByteArrayOutputStream os =
200434ef26756a751b99b5c021ee2b9221c582c88208John Reck                                new ByteArrayOutputStream();
200534ef26756a751b99b5c021ee2b9221c582c88208John Reck                        bm.compress(Bitmap.CompressFormat.PNG, 100, os);
200634ef26756a751b99b5c021ee2b9221c582c88208John Reck
200734ef26756a751b99b5c021ee2b9221c582c88208John Reck                        ContentValues values = new ContentValues();
200834ef26756a751b99b5c021ee2b9221c582c88208John Reck                        values.put(Images.THUMBNAIL, os.toByteArray());
200934ef26756a751b99b5c021ee2b9221c582c88208John Reck
201034ef26756a751b99b5c021ee2b9221c582c88208John Reck                        do {
2011617fd83615f490817db7d288d732d6cdd0b47ae5John Reck                            values.put(Images.URL, cursor.getString(0));
201234ef26756a751b99b5c021ee2b9221c582c88208John Reck                            cr.update(Images.CONTENT_URI, values, null, null);
201334ef26756a751b99b5c021ee2b9221c582c88208John Reck                        } while (cursor.moveToNext());
20148233facddcc51865d612a919d450db6954aa48e3Michael Kolb                    }
201534ef26756a751b99b5c021ee2b9221c582c88208John Reck                } catch (IllegalStateException e) {
201634ef26756a751b99b5c021ee2b9221c582c88208John Reck                    // Ignore
201734ef26756a751b99b5c021ee2b9221c582c88208John Reck                } finally {
201834ef26756a751b99b5c021ee2b9221c582c88208John Reck                    if (cursor != null) cursor.close();
20198233facddcc51865d612a919d450db6954aa48e3Michael Kolb                }
202034ef26756a751b99b5c021ee2b9221c582c88208John Reck                return null;
202134ef26756a751b99b5c021ee2b9221c582c88208John Reck            }
202234ef26756a751b99b5c021ee2b9221c582c88208John Reck        }.execute();
20238233facddcc51865d612a919d450db6954aa48e3Michael Kolb    }
20248233facddcc51865d612a919d450db6954aa48e3Michael Kolb
20258233facddcc51865d612a919d450db6954aa48e3Michael Kolb    private class Copy implements OnMenuItemClickListener {
20268233facddcc51865d612a919d450db6954aa48e3Michael Kolb        private CharSequence mText;
20278233facddcc51865d612a919d450db6954aa48e3Michael Kolb
20288233facddcc51865d612a919d450db6954aa48e3Michael Kolb        public boolean onMenuItemClick(MenuItem item) {
20298233facddcc51865d612a919d450db6954aa48e3Michael Kolb            copy(mText);
20308233facddcc51865d612a919d450db6954aa48e3Michael Kolb            return true;
20318233facddcc51865d612a919d450db6954aa48e3Michael Kolb        }
20328233facddcc51865d612a919d450db6954aa48e3Michael Kolb
20338233facddcc51865d612a919d450db6954aa48e3Michael Kolb        public Copy(CharSequence toCopy) {
20348233facddcc51865d612a919d450db6954aa48e3Michael Kolb            mText = toCopy;
20358233facddcc51865d612a919d450db6954aa48e3Michael Kolb        }
20368233facddcc51865d612a919d450db6954aa48e3Michael Kolb    }
20378233facddcc51865d612a919d450db6954aa48e3Michael Kolb
203863c0266b5d1fca4df859fe4fa3a9555d0783a2b6Leon Scroggins    private static class Download implements OnMenuItemClickListener {
203963c0266b5d1fca4df859fe4fa3a9555d0783a2b6Leon Scroggins        private Activity mActivity;
20408233facddcc51865d612a919d450db6954aa48e3Michael Kolb        private String mText;
2041bc5cc75c302eb49d15258155fc6f672fcbd62842Kristian Monsen        private boolean mPrivateBrowsing;
20428233facddcc51865d612a919d450db6954aa48e3Michael Kolb
20438233facddcc51865d612a919d450db6954aa48e3Michael Kolb        public boolean onMenuItemClick(MenuItem item) {
204463c0266b5d1fca4df859fe4fa3a9555d0783a2b6Leon Scroggins            DownloadHandler.onDownloadStartNoStream(mActivity, mText, null,
2045bc5cc75c302eb49d15258155fc6f672fcbd62842Kristian Monsen                    null, null, mPrivateBrowsing);
20468233facddcc51865d612a919d450db6954aa48e3Michael Kolb            return true;
20478233facddcc51865d612a919d450db6954aa48e3Michael Kolb        }
20488233facddcc51865d612a919d450db6954aa48e3Michael Kolb
2049bc5cc75c302eb49d15258155fc6f672fcbd62842Kristian Monsen        public Download(Activity activity, String toDownload, boolean privateBrowsing) {
205063c0266b5d1fca4df859fe4fa3a9555d0783a2b6Leon Scroggins            mActivity = activity;
20518233facddcc51865d612a919d450db6954aa48e3Michael Kolb            mText = toDownload;
2052bc5cc75c302eb49d15258155fc6f672fcbd62842Kristian Monsen            mPrivateBrowsing = privateBrowsing;
20538233facddcc51865d612a919d450db6954aa48e3Michael Kolb        }
20548233facddcc51865d612a919d450db6954aa48e3Michael Kolb    }
20558233facddcc51865d612a919d450db6954aa48e3Michael Kolb
20568974d281fa5c96bf50d5f5bac665cae44568f6e8Cary Clark    private static class SelectText implements OnMenuItemClickListener {
20578974d281fa5c96bf50d5f5bac665cae44568f6e8Cary Clark        private WebView mWebView;
20588974d281fa5c96bf50d5f5bac665cae44568f6e8Cary Clark
20598974d281fa5c96bf50d5f5bac665cae44568f6e8Cary Clark        public boolean onMenuItemClick(MenuItem item) {
20608974d281fa5c96bf50d5f5bac665cae44568f6e8Cary Clark            if (mWebView != null) {
20618974d281fa5c96bf50d5f5bac665cae44568f6e8Cary Clark                return mWebView.selectText();
20628974d281fa5c96bf50d5f5bac665cae44568f6e8Cary Clark            }
20638974d281fa5c96bf50d5f5bac665cae44568f6e8Cary Clark            return false;
20648974d281fa5c96bf50d5f5bac665cae44568f6e8Cary Clark        }
20658974d281fa5c96bf50d5f5bac665cae44568f6e8Cary Clark
20668974d281fa5c96bf50d5f5bac665cae44568f6e8Cary Clark        public SelectText(WebView webView) {
20678974d281fa5c96bf50d5f5bac665cae44568f6e8Cary Clark            mWebView = webView;
20688974d281fa5c96bf50d5f5bac665cae44568f6e8Cary Clark        }
20698974d281fa5c96bf50d5f5bac665cae44568f6e8Cary Clark
20708974d281fa5c96bf50d5f5bac665cae44568f6e8Cary Clark    }
20718974d281fa5c96bf50d5f5bac665cae44568f6e8Cary Clark
20728233facddcc51865d612a919d450db6954aa48e3Michael Kolb    /********************** TODO: UI stuff *****************************/
20738233facddcc51865d612a919d450db6954aa48e3Michael Kolb
20748233facddcc51865d612a919d450db6954aa48e3Michael Kolb    // these methods have been copied, they still need to be cleaned up
20758233facddcc51865d612a919d450db6954aa48e3Michael Kolb
20768233facddcc51865d612a919d450db6954aa48e3Michael Kolb    /****************** tabs ***************************************************/
20778233facddcc51865d612a919d450db6954aa48e3Michael Kolb
20788233facddcc51865d612a919d450db6954aa48e3Michael Kolb    // basic tab interactions:
20798233facddcc51865d612a919d450db6954aa48e3Michael Kolb
20808233facddcc51865d612a919d450db6954aa48e3Michael Kolb    // it is assumed that tabcontrol already knows about the tab
20818233facddcc51865d612a919d450db6954aa48e3Michael Kolb    protected void addTab(Tab tab) {
20828233facddcc51865d612a919d450db6954aa48e3Michael Kolb        mUi.addTab(tab);
20838233facddcc51865d612a919d450db6954aa48e3Michael Kolb    }
20848233facddcc51865d612a919d450db6954aa48e3Michael Kolb
20858233facddcc51865d612a919d450db6954aa48e3Michael Kolb    protected void removeTab(Tab tab) {
20868233facddcc51865d612a919d450db6954aa48e3Michael Kolb        mUi.removeTab(tab);
20878233facddcc51865d612a919d450db6954aa48e3Michael Kolb        mTabControl.removeTab(tab);
2088378a41055fab6c521cdc1d9b2cfeefff2af19e7cJohn Reck        mCrashRecoveryHandler.backupState();
20898233facddcc51865d612a919d450db6954aa48e3Michael Kolb    }
20908233facddcc51865d612a919d450db6954aa48e3Michael Kolb
2091f205560dacc8a85f0443ca1949a68962404321e8Michael Kolb    @Override
2092f205560dacc8a85f0443ca1949a68962404321e8Michael Kolb    public void setActiveTab(Tab tab) {
2093cd424e99aa19d00933e6540a95805042659f596fMichael Kolb        // monkey protection against delayed start
2094cd424e99aa19d00933e6540a95805042659f596fMichael Kolb        if (tab != null) {
2095cd424e99aa19d00933e6540a95805042659f596fMichael Kolb            mTabControl.setCurrentTab(tab);
2096cd424e99aa19d00933e6540a95805042659f596fMichael Kolb            // the tab is guaranteed to have a webview after setCurrentTab
2097cd424e99aa19d00933e6540a95805042659f596fMichael Kolb            mUi.setActiveTab(tab);
2098cd424e99aa19d00933e6540a95805042659f596fMichael Kolb        }
20998233facddcc51865d612a919d450db6954aa48e3Michael Kolb    }
21008233facddcc51865d612a919d450db6954aa48e3Michael Kolb
21018233facddcc51865d612a919d450db6954aa48e3Michael Kolb    protected void closeEmptyChildTab() {
21028233facddcc51865d612a919d450db6954aa48e3Michael Kolb        Tab current = mTabControl.getCurrentTab();
21038233facddcc51865d612a919d450db6954aa48e3Michael Kolb        if (current != null
21048233facddcc51865d612a919d450db6954aa48e3Michael Kolb                && current.getWebView().copyBackForwardList().getSize() == 0) {
2105c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb            Tab parent = current.getParent();
21068233facddcc51865d612a919d450db6954aa48e3Michael Kolb            if (parent != null) {
2107c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb                switchToTab(parent);
21088233facddcc51865d612a919d450db6954aa48e3Michael Kolb                closeTab(current);
21098233facddcc51865d612a919d450db6954aa48e3Michael Kolb            }
21108233facddcc51865d612a919d450db6954aa48e3Michael Kolb        }
21118233facddcc51865d612a919d450db6954aa48e3Michael Kolb    }
21128233facddcc51865d612a919d450db6954aa48e3Michael Kolb
211326b183292dc087b16af10f482744c3bb30e1f163John Reck    protected void reuseTab(Tab appTab, UrlData urlData) {
21148233facddcc51865d612a919d450db6954aa48e3Michael Kolb        // Dismiss the subwindow if applicable.
21158233facddcc51865d612a919d450db6954aa48e3Michael Kolb        dismissSubWindow(appTab);
21168233facddcc51865d612a919d450db6954aa48e3Michael Kolb        // Since we might kill the WebView, remove it from the
21178233facddcc51865d612a919d450db6954aa48e3Michael Kolb        // content view first.
21188233facddcc51865d612a919d450db6954aa48e3Michael Kolb        mUi.detachTab(appTab);
21198233facddcc51865d612a919d450db6954aa48e3Michael Kolb        // Recreate the main WebView after destroying the old one.
212030c714c853a4239e72ab1e238ce2a92472d06ab0John Reck        mTabControl.recreateWebView(appTab);
21218233facddcc51865d612a919d450db6954aa48e3Michael Kolb        // TODO: analyze why the remove and add are necessary
21228233facddcc51865d612a919d450db6954aa48e3Michael Kolb        mUi.attachTab(appTab);
21238233facddcc51865d612a919d450db6954aa48e3Michael Kolb        if (mTabControl.getCurrentTab() != appTab) {
2124c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb            switchToTab(appTab);
212530c714c853a4239e72ab1e238ce2a92472d06ab0John Reck            loadUrlDataIn(appTab, urlData);
21268233facddcc51865d612a919d450db6954aa48e3Michael Kolb        } else {
21278233facddcc51865d612a919d450db6954aa48e3Michael Kolb            // If the tab was the current tab, we have to attach
21288233facddcc51865d612a919d450db6954aa48e3Michael Kolb            // it to the view system again.
21298233facddcc51865d612a919d450db6954aa48e3Michael Kolb            setActiveTab(appTab);
213030c714c853a4239e72ab1e238ce2a92472d06ab0John Reck            loadUrlDataIn(appTab, urlData);
21318233facddcc51865d612a919d450db6954aa48e3Michael Kolb        }
21328233facddcc51865d612a919d450db6954aa48e3Michael Kolb    }
21338233facddcc51865d612a919d450db6954aa48e3Michael Kolb
21348233facddcc51865d612a919d450db6954aa48e3Michael Kolb    // Remove the sub window if it exists. Also called by TabControl when the
21358233facddcc51865d612a919d450db6954aa48e3Michael Kolb    // user clicks the 'X' to dismiss a sub window.
21368233facddcc51865d612a919d450db6954aa48e3Michael Kolb    public void dismissSubWindow(Tab tab) {
21378233facddcc51865d612a919d450db6954aa48e3Michael Kolb        removeSubWindow(tab);
21388233facddcc51865d612a919d450db6954aa48e3Michael Kolb        // dismiss the subwindow. This will destroy the WebView.
21398233facddcc51865d612a919d450db6954aa48e3Michael Kolb        tab.dismissSubWindow();
21408233facddcc51865d612a919d450db6954aa48e3Michael Kolb        getCurrentTopWebView().requestFocus();
21418233facddcc51865d612a919d450db6954aa48e3Michael Kolb    }
21428233facddcc51865d612a919d450db6954aa48e3Michael Kolb
21438233facddcc51865d612a919d450db6954aa48e3Michael Kolb    @Override
21448233facddcc51865d612a919d450db6954aa48e3Michael Kolb    public void removeSubWindow(Tab t) {
21458233facddcc51865d612a919d450db6954aa48e3Michael Kolb        if (t.getSubWebView() != null) {
21468233facddcc51865d612a919d450db6954aa48e3Michael Kolb            mUi.removeSubWindow(t.getSubViewContainer());
21478233facddcc51865d612a919d450db6954aa48e3Michael Kolb        }
21488233facddcc51865d612a919d450db6954aa48e3Michael Kolb    }
21498233facddcc51865d612a919d450db6954aa48e3Michael Kolb
21508233facddcc51865d612a919d450db6954aa48e3Michael Kolb    @Override
21518233facddcc51865d612a919d450db6954aa48e3Michael Kolb    public void attachSubWindow(Tab tab) {
21528233facddcc51865d612a919d450db6954aa48e3Michael Kolb        if (tab.getSubWebView() != null) {
21538233facddcc51865d612a919d450db6954aa48e3Michael Kolb            mUi.attachSubWindow(tab.getSubViewContainer());
21548233facddcc51865d612a919d450db6954aa48e3Michael Kolb            getCurrentTopWebView().requestFocus();
21558233facddcc51865d612a919d450db6954aa48e3Michael Kolb        }
21568233facddcc51865d612a919d450db6954aa48e3Michael Kolb    }
21578233facddcc51865d612a919d450db6954aa48e3Michael Kolb
215829721c2c6cc7f79a52962556c4431b71bb3ce46eMathew Inwood    private Tab showPreloadedTab(final UrlData urlData) {
215929721c2c6cc7f79a52962556c4431b71bb3ce46eMathew Inwood        if (!urlData.isPreloaded()) {
216029721c2c6cc7f79a52962556c4431b71bb3ce46eMathew Inwood            return null;
216129721c2c6cc7f79a52962556c4431b71bb3ce46eMathew Inwood        }
216229721c2c6cc7f79a52962556c4431b71bb3ce46eMathew Inwood        final PreloadedTabControl tabControl = urlData.getPreloadedTab();
216329721c2c6cc7f79a52962556c4431b71bb3ce46eMathew Inwood        final String sbQuery = urlData.getSearchBoxQueryToSubmit();
216429721c2c6cc7f79a52962556c4431b71bb3ce46eMathew Inwood        if (sbQuery != null) {
216529721c2c6cc7f79a52962556c4431b71bb3ce46eMathew Inwood            if (!tabControl.searchBoxSubmit(sbQuery, urlData.mUrl, urlData.mHeaders)) {
216629721c2c6cc7f79a52962556c4431b71bb3ce46eMathew Inwood                // Could not submit query. Fallback to regular tab creation
216729721c2c6cc7f79a52962556c4431b71bb3ce46eMathew Inwood                tabControl.destroy();
216829721c2c6cc7f79a52962556c4431b71bb3ce46eMathew Inwood                return null;
216929721c2c6cc7f79a52962556c4431b71bb3ce46eMathew Inwood            }
217029721c2c6cc7f79a52962556c4431b71bb3ce46eMathew Inwood        }
217129721c2c6cc7f79a52962556c4431b71bb3ce46eMathew Inwood        Tab t = tabControl.getTab();
217229721c2c6cc7f79a52962556c4431b71bb3ce46eMathew Inwood        mTabControl.addPreloadedTab(t);
217329721c2c6cc7f79a52962556c4431b71bb3ce46eMathew Inwood        addTab(t);
217429721c2c6cc7f79a52962556c4431b71bb3ce46eMathew Inwood        setActiveTab(t);
217529721c2c6cc7f79a52962556c4431b71bb3ce46eMathew Inwood        return t;
217629721c2c6cc7f79a52962556c4431b71bb3ce46eMathew Inwood    }
217729721c2c6cc7f79a52962556c4431b71bb3ce46eMathew Inwood
21787bcafde2ba532941c1eb8c9022eebd5398aeae2aMichael Kolb    // open a non inconito tab with the given url data
21797bcafde2ba532941c1eb8c9022eebd5398aeae2aMichael Kolb    // and set as active tab
21807bcafde2ba532941c1eb8c9022eebd5398aeae2aMichael Kolb    public Tab openTab(UrlData urlData) {
218129721c2c6cc7f79a52962556c4431b71bb3ce46eMathew Inwood        Tab tab = showPreloadedTab(urlData);
218229721c2c6cc7f79a52962556c4431b71bb3ce46eMathew Inwood        if (tab == null) {
218329721c2c6cc7f79a52962556c4431b71bb3ce46eMathew Inwood            tab = createNewTab(false, true, true);
21841461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb            if ((tab != null) && !urlData.isEmpty()) {
21851461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb                loadUrlDataIn(tab, urlData);
21861461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb            }
218718eb377badf8e6f9ea2925bcb7e978facf3171d9Michael Kolb        }
218829721c2c6cc7f79a52962556c4431b71bb3ce46eMathew Inwood        return tab;
21898233facddcc51865d612a919d450db6954aa48e3Michael Kolb    }
21908233facddcc51865d612a919d450db6954aa48e3Michael Kolb
21917bcafde2ba532941c1eb8c9022eebd5398aeae2aMichael Kolb    @Override
21927bcafde2ba532941c1eb8c9022eebd5398aeae2aMichael Kolb    public Tab openTabToHomePage() {
21937bcafde2ba532941c1eb8c9022eebd5398aeae2aMichael Kolb        return openTab(mSettings.getHomePage(), false, true, false);
21948233facddcc51865d612a919d450db6954aa48e3Michael Kolb    }
21958233facddcc51865d612a919d450db6954aa48e3Michael Kolb
21968233facddcc51865d612a919d450db6954aa48e3Michael Kolb    @Override
2197519d22840ea587988214a625dc8106e1302ac4a9Michael Kolb    public Tab openIncognitoTab() {
2198519d22840ea587988214a625dc8106e1302ac4a9Michael Kolb        return openTab(INCOGNITO_URI, true, true, false);
2199519d22840ea587988214a625dc8106e1302ac4a9Michael Kolb    }
2200519d22840ea587988214a625dc8106e1302ac4a9Michael Kolb
2201519d22840ea587988214a625dc8106e1302ac4a9Michael Kolb    @Override
22027bcafde2ba532941c1eb8c9022eebd5398aeae2aMichael Kolb    public Tab openTab(String url, boolean incognito, boolean setActive,
22037bcafde2ba532941c1eb8c9022eebd5398aeae2aMichael Kolb            boolean useCurrent) {
22045949c661b51295148706d53a03b41df2eb840ae3John Reck        return openTab(url, incognito, setActive, useCurrent, null);
22055949c661b51295148706d53a03b41df2eb840ae3John Reck    }
22065949c661b51295148706d53a03b41df2eb840ae3John Reck
22075949c661b51295148706d53a03b41df2eb840ae3John Reck    @Override
22085949c661b51295148706d53a03b41df2eb840ae3John Reck    public Tab openTab(String url, Tab parent, boolean setActive,
22095949c661b51295148706d53a03b41df2eb840ae3John Reck            boolean useCurrent) {
22105949c661b51295148706d53a03b41df2eb840ae3John Reck        return openTab(url, (parent != null) && parent.isPrivateBrowsingEnabled(),
22115949c661b51295148706d53a03b41df2eb840ae3John Reck                setActive, useCurrent, parent);
22125949c661b51295148706d53a03b41df2eb840ae3John Reck    }
22135949c661b51295148706d53a03b41df2eb840ae3John Reck
22145949c661b51295148706d53a03b41df2eb840ae3John Reck    public Tab openTab(String url, boolean incognito, boolean setActive,
22155949c661b51295148706d53a03b41df2eb840ae3John Reck            boolean useCurrent, Tab parent) {
22167bcafde2ba532941c1eb8c9022eebd5398aeae2aMichael Kolb        Tab tab = createNewTab(incognito, setActive, useCurrent);
22177bcafde2ba532941c1eb8c9022eebd5398aeae2aMichael Kolb        if (tab != null) {
22185949c661b51295148706d53a03b41df2eb840ae3John Reck            if (parent != null && parent != tab) {
22195949c661b51295148706d53a03b41df2eb840ae3John Reck                parent.addChildTab(tab);
22205949c661b51295148706d53a03b41df2eb840ae3John Reck            }
2221519d22840ea587988214a625dc8106e1302ac4a9Michael Kolb            if (url != null) {
222226b183292dc087b16af10f482744c3bb30e1f163John Reck                loadUrl(tab, url);
2223519d22840ea587988214a625dc8106e1302ac4a9Michael Kolb            }
2224a4261fd53fef2b311e733fcfee4be3a9967ad967Michael Kolb        }
22257bcafde2ba532941c1eb8c9022eebd5398aeae2aMichael Kolb        return tab;
2226a4261fd53fef2b311e733fcfee4be3a9967ad967Michael Kolb    }
2227a4261fd53fef2b311e733fcfee4be3a9967ad967Michael Kolb
22287bcafde2ba532941c1eb8c9022eebd5398aeae2aMichael Kolb    // this method will attempt to create a new tab
22297bcafde2ba532941c1eb8c9022eebd5398aeae2aMichael Kolb    // incognito: private browsing tab
22307bcafde2ba532941c1eb8c9022eebd5398aeae2aMichael Kolb    // setActive: ste tab as current tab
22317bcafde2ba532941c1eb8c9022eebd5398aeae2aMichael Kolb    // useCurrent: if no new tab can be created, return current tab
22327bcafde2ba532941c1eb8c9022eebd5398aeae2aMichael Kolb    private Tab createNewTab(boolean incognito, boolean setActive,
22337bcafde2ba532941c1eb8c9022eebd5398aeae2aMichael Kolb            boolean useCurrent) {
22347bcafde2ba532941c1eb8c9022eebd5398aeae2aMichael Kolb        Tab tab = null;
2235a4261fd53fef2b311e733fcfee4be3a9967ad967Michael Kolb        if (mTabControl.canCreateNewTab()) {
22367bcafde2ba532941c1eb8c9022eebd5398aeae2aMichael Kolb            tab = mTabControl.createNewTab(incognito);
2237a4261fd53fef2b311e733fcfee4be3a9967ad967Michael Kolb            addTab(tab);
22387bcafde2ba532941c1eb8c9022eebd5398aeae2aMichael Kolb            if (setActive) {
22397bcafde2ba532941c1eb8c9022eebd5398aeae2aMichael Kolb                setActiveTab(tab);
22407bcafde2ba532941c1eb8c9022eebd5398aeae2aMichael Kolb            }
2241843510fb4f36a9a834c69d8773156db20ca3d740Michael Kolb        } else {
22427bcafde2ba532941c1eb8c9022eebd5398aeae2aMichael Kolb            if (useCurrent) {
22437bcafde2ba532941c1eb8c9022eebd5398aeae2aMichael Kolb                tab = mTabControl.getCurrentTab();
224426b183292dc087b16af10f482744c3bb30e1f163John Reck                reuseTab(tab, null);
22457bcafde2ba532941c1eb8c9022eebd5398aeae2aMichael Kolb            } else {
22467bcafde2ba532941c1eb8c9022eebd5398aeae2aMichael Kolb                mUi.showMaxTabsWarning();
22477bcafde2ba532941c1eb8c9022eebd5398aeae2aMichael Kolb            }
22488233facddcc51865d612a919d450db6954aa48e3Michael Kolb        }
22497bcafde2ba532941c1eb8c9022eebd5398aeae2aMichael Kolb        return tab;
22508233facddcc51865d612a919d450db6954aa48e3Michael Kolb    }
22518233facddcc51865d612a919d450db6954aa48e3Michael Kolb
22522bc8042224be51966d748b870768ec1b376a1621John Reck    @Override
22532bc8042224be51966d748b870768ec1b376a1621John Reck    public SnapshotTab createNewSnapshotTab(long snapshotId, boolean setActive) {
22542bc8042224be51966d748b870768ec1b376a1621John Reck        SnapshotTab tab = null;
22552bc8042224be51966d748b870768ec1b376a1621John Reck        if (mTabControl.canCreateNewTab()) {
22562bc8042224be51966d748b870768ec1b376a1621John Reck            tab = mTabControl.createSnapshotTab(snapshotId);
22572bc8042224be51966d748b870768ec1b376a1621John Reck            addTab(tab);
22582bc8042224be51966d748b870768ec1b376a1621John Reck            if (setActive) {
22592bc8042224be51966d748b870768ec1b376a1621John Reck                setActiveTab(tab);
22602bc8042224be51966d748b870768ec1b376a1621John Reck            }
22612bc8042224be51966d748b870768ec1b376a1621John Reck        } else {
22622bc8042224be51966d748b870768ec1b376a1621John Reck            mUi.showMaxTabsWarning();
2263d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck        }
2264d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck        return tab;
2265d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck    }
2266d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck
22678233facddcc51865d612a919d450db6954aa48e3Michael Kolb    /**
2268c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb     * @param tab the tab to switch to
22698233facddcc51865d612a919d450db6954aa48e3Michael Kolb     * @return boolean True if we successfully switched to a different tab.  If
22708233facddcc51865d612a919d450db6954aa48e3Michael Kolb     *                 the indexth tab is null, or if that tab is the same as
22718233facddcc51865d612a919d450db6954aa48e3Michael Kolb     *                 the current one, return false.
22728233facddcc51865d612a919d450db6954aa48e3Michael Kolb     */
22738233facddcc51865d612a919d450db6954aa48e3Michael Kolb    @Override
2274c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb    public boolean switchToTab(Tab tab) {
227514ee8fbf5a647152d9a106b054b206be68c11e03Michael Kolb        // hide combo view if open
227614ee8fbf5a647152d9a106b054b206be68c11e03Michael Kolb        removeComboView();
22778233facddcc51865d612a919d450db6954aa48e3Michael Kolb        Tab currentTab = mTabControl.getCurrentTab();
22788233facddcc51865d612a919d450db6954aa48e3Michael Kolb        if (tab == null || tab == currentTab) {
22798233facddcc51865d612a919d450db6954aa48e3Michael Kolb            return false;
22808233facddcc51865d612a919d450db6954aa48e3Michael Kolb        }
22818233facddcc51865d612a919d450db6954aa48e3Michael Kolb        setActiveTab(tab);
22828233facddcc51865d612a919d450db6954aa48e3Michael Kolb        return true;
22838233facddcc51865d612a919d450db6954aa48e3Michael Kolb    }
22848233facddcc51865d612a919d450db6954aa48e3Michael Kolb
22858233facddcc51865d612a919d450db6954aa48e3Michael Kolb    @Override
22868233facddcc51865d612a919d450db6954aa48e3Michael Kolb    public void closeCurrentTab() {
228714ee8fbf5a647152d9a106b054b206be68c11e03Michael Kolb        // hide combo view if open
228814ee8fbf5a647152d9a106b054b206be68c11e03Michael Kolb        removeComboView();
22898233facddcc51865d612a919d450db6954aa48e3Michael Kolb        if (mTabControl.getTabCount() == 1) {
2290958b24285bba0163bc4121a3fc0fb116aa563ed9John Reck            mActivity.finish();
22918233facddcc51865d612a919d450db6954aa48e3Michael Kolb            return;
22928233facddcc51865d612a919d450db6954aa48e3Michael Kolb        }
2293c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb        final Tab current = mTabControl.getCurrentTab();
2294c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb        final int pos = mTabControl.getCurrentPosition();
2295c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb        Tab newTab = current.getParent();
2296c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb        if (newTab == null) {
2297c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb            newTab = mTabControl.getTab(pos + 1);
2298c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb            if (newTab == null) {
2299c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb                newTab = mTabControl.getTab(pos - 1);
23008233facddcc51865d612a919d450db6954aa48e3Michael Kolb            }
23018233facddcc51865d612a919d450db6954aa48e3Michael Kolb        }
2302c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb        if (switchToTab(newTab)) {
23038233facddcc51865d612a919d450db6954aa48e3Michael Kolb            // Close window
23048233facddcc51865d612a919d450db6954aa48e3Michael Kolb            closeTab(current);
23058233facddcc51865d612a919d450db6954aa48e3Michael Kolb        }
23068233facddcc51865d612a919d450db6954aa48e3Michael Kolb    }
23078233facddcc51865d612a919d450db6954aa48e3Michael Kolb
23088233facddcc51865d612a919d450db6954aa48e3Michael Kolb    /**
23098233facddcc51865d612a919d450db6954aa48e3Michael Kolb     * Close the tab, remove its associated title bar, and adjust mTabControl's
23108233facddcc51865d612a919d450db6954aa48e3Michael Kolb     * current tab to a valid value.
23118233facddcc51865d612a919d450db6954aa48e3Michael Kolb     */
23128233facddcc51865d612a919d450db6954aa48e3Michael Kolb    @Override
23138233facddcc51865d612a919d450db6954aa48e3Michael Kolb    public void closeTab(Tab tab) {
231414ee8fbf5a647152d9a106b054b206be68c11e03Michael Kolb        // hide combo view if open
231514ee8fbf5a647152d9a106b054b206be68c11e03Michael Kolb        removeComboView();
23162d59c32ee3fc1ed92d57609998f0430ad7695317Michael Kolb        removeTab(tab);
23178233facddcc51865d612a919d450db6954aa48e3Michael Kolb    }
23188233facddcc51865d612a919d450db6954aa48e3Michael Kolb
23198233facddcc51865d612a919d450db6954aa48e3Michael Kolb    // Called when loading from context menu or LOAD_URL message
232026b183292dc087b16af10f482744c3bb30e1f163John Reck    protected void loadUrlFromContext(String url) {
232126b183292dc087b16af10f482744c3bb30e1f163John Reck        Tab tab = getCurrentTab();
232226b183292dc087b16af10f482744c3bb30e1f163John Reck        WebView view = tab != null ? tab.getWebView() : null;
23238233facddcc51865d612a919d450db6954aa48e3Michael Kolb        // In case the user enters nothing.
232426b183292dc087b16af10f482744c3bb30e1f163John Reck        if (url != null && url.length() != 0 && tab != null && view != null) {
23258233facddcc51865d612a919d450db6954aa48e3Michael Kolb            url = UrlUtils.smartUrlFilter(url);
23268233facddcc51865d612a919d450db6954aa48e3Michael Kolb            if (!view.getWebViewClient().shouldOverrideUrlLoading(view, url)) {
232726b183292dc087b16af10f482744c3bb30e1f163John Reck                loadUrl(tab, url);
23288233facddcc51865d612a919d450db6954aa48e3Michael Kolb            }
23298233facddcc51865d612a919d450db6954aa48e3Michael Kolb        }
23308233facddcc51865d612a919d450db6954aa48e3Michael Kolb    }
23318233facddcc51865d612a919d450db6954aa48e3Michael Kolb
23328233facddcc51865d612a919d450db6954aa48e3Michael Kolb    /**
23338233facddcc51865d612a919d450db6954aa48e3Michael Kolb     * Load the URL into the given WebView and update the title bar
23348233facddcc51865d612a919d450db6954aa48e3Michael Kolb     * to reflect the new load.  Call this instead of WebView.loadUrl
23358233facddcc51865d612a919d450db6954aa48e3Michael Kolb     * directly.
23368233facddcc51865d612a919d450db6954aa48e3Michael Kolb     * @param view The WebView used to load url.
23378233facddcc51865d612a919d450db6954aa48e3Michael Kolb     * @param url The URL to load.
23388233facddcc51865d612a919d450db6954aa48e3Michael Kolb     */
233971e5142e4237a0f9d51a93504da36b778e8b79e4John Reck    @Override
234071e5142e4237a0f9d51a93504da36b778e8b79e4John Reck    public void loadUrl(Tab tab, String url) {
234126b183292dc087b16af10f482744c3bb30e1f163John Reck        loadUrl(tab, url, null);
234226b183292dc087b16af10f482744c3bb30e1f163John Reck    }
234326b183292dc087b16af10f482744c3bb30e1f163John Reck
234426b183292dc087b16af10f482744c3bb30e1f163John Reck    protected void loadUrl(Tab tab, String url, Map<String, String> headers) {
234526b183292dc087b16af10f482744c3bb30e1f163John Reck        if (tab != null) {
234626b183292dc087b16af10f482744c3bb30e1f163John Reck            dismissSubWindow(tab);
234726b183292dc087b16af10f482744c3bb30e1f163John Reck            tab.loadUrl(url, headers);
234826b183292dc087b16af10f482744c3bb30e1f163John Reck        }
23498233facddcc51865d612a919d450db6954aa48e3Michael Kolb    }
23508233facddcc51865d612a919d450db6954aa48e3Michael Kolb
23518233facddcc51865d612a919d450db6954aa48e3Michael Kolb    /**
23528233facddcc51865d612a919d450db6954aa48e3Michael Kolb     * Load UrlData into a Tab and update the title bar to reflect the new
23538233facddcc51865d612a919d450db6954aa48e3Michael Kolb     * load.  Call this instead of UrlData.loadIn directly.
23548233facddcc51865d612a919d450db6954aa48e3Michael Kolb     * @param t The Tab used to load.
23558233facddcc51865d612a919d450db6954aa48e3Michael Kolb     * @param data The UrlData being loaded.
23568233facddcc51865d612a919d450db6954aa48e3Michael Kolb     */
23578233facddcc51865d612a919d450db6954aa48e3Michael Kolb    protected void loadUrlDataIn(Tab t, UrlData data) {
235826b183292dc087b16af10f482744c3bb30e1f163John Reck        if (data != null) {
235926b183292dc087b16af10f482744c3bb30e1f163John Reck            if (data.mVoiceIntent != null) {
236026b183292dc087b16af10f482744c3bb30e1f163John Reck                t.activateVoiceSearchMode(data.mVoiceIntent);
23611461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb            } else if (data.isPreloaded()) {
23621461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb                // this isn't called for preloaded tabs
236326b183292dc087b16af10f482744c3bb30e1f163John Reck            } else {
236426b183292dc087b16af10f482744c3bb30e1f163John Reck                loadUrl(t, data.mUrl, data.mHeaders);
236526b183292dc087b16af10f482744c3bb30e1f163John Reck            }
236626b183292dc087b16af10f482744c3bb30e1f163John Reck        }
23678233facddcc51865d612a919d450db6954aa48e3Michael Kolb    }
23688233facddcc51865d612a919d450db6954aa48e3Michael Kolb
236930c714c853a4239e72ab1e238ce2a92472d06ab0John Reck    @Override
237030c714c853a4239e72ab1e238ce2a92472d06ab0John Reck    public void onUserCanceledSsl(Tab tab) {
237130c714c853a4239e72ab1e238ce2a92472d06ab0John Reck        // TODO: Figure out the "right" behavior
2372ef654f1dd80f55609060005342fc4f2cde62990cJohn Reck        if (tab.canGoBack()) {
2373ef654f1dd80f55609060005342fc4f2cde62990cJohn Reck            tab.goBack();
237430c714c853a4239e72ab1e238ce2a92472d06ab0John Reck        } else {
2375ef654f1dd80f55609060005342fc4f2cde62990cJohn Reck            tab.loadUrl(mSettings.getHomePage(), null);
237630c714c853a4239e72ab1e238ce2a92472d06ab0John Reck        }
23778233facddcc51865d612a919d450db6954aa48e3Michael Kolb    }
23788233facddcc51865d612a919d450db6954aa48e3Michael Kolb
23798233facddcc51865d612a919d450db6954aa48e3Michael Kolb    void goBackOnePageOrQuit() {
23808233facddcc51865d612a919d450db6954aa48e3Michael Kolb        Tab current = mTabControl.getCurrentTab();
23818233facddcc51865d612a919d450db6954aa48e3Michael Kolb        if (current == null) {
23828233facddcc51865d612a919d450db6954aa48e3Michael Kolb            /*
23838233facddcc51865d612a919d450db6954aa48e3Michael Kolb             * Instead of finishing the activity, simply push this to the back
23848233facddcc51865d612a919d450db6954aa48e3Michael Kolb             * of the stack and let ActivityManager to choose the foreground
23858233facddcc51865d612a919d450db6954aa48e3Michael Kolb             * activity. As BrowserActivity is singleTask, it will be always the
23868233facddcc51865d612a919d450db6954aa48e3Michael Kolb             * root of the task. So we can use either true or false for
23878233facddcc51865d612a919d450db6954aa48e3Michael Kolb             * moveTaskToBack().
23888233facddcc51865d612a919d450db6954aa48e3Michael Kolb             */
23898233facddcc51865d612a919d450db6954aa48e3Michael Kolb            mActivity.moveTaskToBack(true);
23908233facddcc51865d612a919d450db6954aa48e3Michael Kolb            return;
23918233facddcc51865d612a919d450db6954aa48e3Michael Kolb        }
2392ef654f1dd80f55609060005342fc4f2cde62990cJohn Reck        if (current.canGoBack()) {
2393ef654f1dd80f55609060005342fc4f2cde62990cJohn Reck            current.goBack();
23948233facddcc51865d612a919d450db6954aa48e3Michael Kolb        } else {
23958233facddcc51865d612a919d450db6954aa48e3Michael Kolb            // Check to see if we are closing a window that was created by
23968233facddcc51865d612a919d450db6954aa48e3Michael Kolb            // another window. If so, we switch back to that window.
2397c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb            Tab parent = current.getParent();
23988233facddcc51865d612a919d450db6954aa48e3Michael Kolb            if (parent != null) {
2399c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb                switchToTab(parent);
24008233facddcc51865d612a919d450db6954aa48e3Michael Kolb                // Now we close the other tab
24018233facddcc51865d612a919d450db6954aa48e3Michael Kolb                closeTab(current);
24028233facddcc51865d612a919d450db6954aa48e3Michael Kolb            } else {
24038233facddcc51865d612a919d450db6954aa48e3Michael Kolb                /*
24048233facddcc51865d612a919d450db6954aa48e3Michael Kolb                 * Instead of finishing the activity, simply push this to the back
24058233facddcc51865d612a919d450db6954aa48e3Michael Kolb                 * of the stack and let ActivityManager to choose the foreground
24068233facddcc51865d612a919d450db6954aa48e3Michael Kolb                 * activity. As BrowserActivity is singleTask, it will be always the
24078233facddcc51865d612a919d450db6954aa48e3Michael Kolb                 * root of the task. So we can use either true or false for
24088233facddcc51865d612a919d450db6954aa48e3Michael Kolb                 * moveTaskToBack().
24098233facddcc51865d612a919d450db6954aa48e3Michael Kolb                 */
24108233facddcc51865d612a919d450db6954aa48e3Michael Kolb                mActivity.moveTaskToBack(true);
24118233facddcc51865d612a919d450db6954aa48e3Michael Kolb            }
24128233facddcc51865d612a919d450db6954aa48e3Michael Kolb        }
24138233facddcc51865d612a919d450db6954aa48e3Michael Kolb    }
24148233facddcc51865d612a919d450db6954aa48e3Michael Kolb
24158233facddcc51865d612a919d450db6954aa48e3Michael Kolb    /**
24168233facddcc51865d612a919d450db6954aa48e3Michael Kolb     * Feed the previously stored results strings to the BrowserProvider so that
24178233facddcc51865d612a919d450db6954aa48e3Michael Kolb     * the SearchDialog will show them instead of the standard searches.
24188233facddcc51865d612a919d450db6954aa48e3Michael Kolb     * @param result String to show on the editable line of the SearchDialog.
24198233facddcc51865d612a919d450db6954aa48e3Michael Kolb     */
24208233facddcc51865d612a919d450db6954aa48e3Michael Kolb    @Override
24218233facddcc51865d612a919d450db6954aa48e3Michael Kolb    public void showVoiceSearchResults(String result) {
24228233facddcc51865d612a919d450db6954aa48e3Michael Kolb        ContentProviderClient client = mActivity.getContentResolver()
24238233facddcc51865d612a919d450db6954aa48e3Michael Kolb                .acquireContentProviderClient(Browser.BOOKMARKS_URI);
24248233facddcc51865d612a919d450db6954aa48e3Michael Kolb        ContentProvider prov = client.getLocalContentProvider();
24258233facddcc51865d612a919d450db6954aa48e3Michael Kolb        BrowserProvider bp = (BrowserProvider) prov;
24268233facddcc51865d612a919d450db6954aa48e3Michael Kolb        bp.setQueryResults(mTabControl.getCurrentTab().getVoiceSearchResults());
24278233facddcc51865d612a919d450db6954aa48e3Michael Kolb        client.release();
24288233facddcc51865d612a919d450db6954aa48e3Michael Kolb
24298233facddcc51865d612a919d450db6954aa48e3Michael Kolb        Bundle bundle = createGoogleSearchSourceBundle(
24308233facddcc51865d612a919d450db6954aa48e3Michael Kolb                GOOGLE_SEARCH_SOURCE_SEARCHKEY);
24318233facddcc51865d612a919d450db6954aa48e3Michael Kolb        bundle.putBoolean(SearchManager.CONTEXT_IS_VOICE, true);
24328233facddcc51865d612a919d450db6954aa48e3Michael Kolb        startSearch(result, false, bundle, false);
24338233facddcc51865d612a919d450db6954aa48e3Michael Kolb    }
24348233facddcc51865d612a919d450db6954aa48e3Michael Kolb
24358233facddcc51865d612a919d450db6954aa48e3Michael Kolb    private void startSearch(String initialQuery, boolean selectInitialQuery,
24368233facddcc51865d612a919d450db6954aa48e3Michael Kolb            Bundle appSearchData, boolean globalSearch) {
24378233facddcc51865d612a919d450db6954aa48e3Michael Kolb        if (appSearchData == null) {
24388233facddcc51865d612a919d450db6954aa48e3Michael Kolb            appSearchData = createGoogleSearchSourceBundle(
24398233facddcc51865d612a919d450db6954aa48e3Michael Kolb                    GOOGLE_SEARCH_SOURCE_TYPE);
24408233facddcc51865d612a919d450db6954aa48e3Michael Kolb        }
24418233facddcc51865d612a919d450db6954aa48e3Michael Kolb
24428233facddcc51865d612a919d450db6954aa48e3Michael Kolb        SearchEngine searchEngine = mSettings.getSearchEngine();
24438233facddcc51865d612a919d450db6954aa48e3Michael Kolb        if (searchEngine != null && !searchEngine.supportsVoiceSearch()) {
24448233facddcc51865d612a919d450db6954aa48e3Michael Kolb            appSearchData.putBoolean(SearchManager.DISABLE_VOICE_SEARCH, true);
24458233facddcc51865d612a919d450db6954aa48e3Michael Kolb        }
24468233facddcc51865d612a919d450db6954aa48e3Michael Kolb        mActivity.startSearch(initialQuery, selectInitialQuery, appSearchData,
24478233facddcc51865d612a919d450db6954aa48e3Michael Kolb                globalSearch);
24488233facddcc51865d612a919d450db6954aa48e3Michael Kolb    }
24498233facddcc51865d612a919d450db6954aa48e3Michael Kolb
24508233facddcc51865d612a919d450db6954aa48e3Michael Kolb    private Bundle createGoogleSearchSourceBundle(String source) {
24518233facddcc51865d612a919d450db6954aa48e3Michael Kolb        Bundle bundle = new Bundle();
24528233facddcc51865d612a919d450db6954aa48e3Michael Kolb        bundle.putString(Search.SOURCE, source);
24538233facddcc51865d612a919d450db6954aa48e3Michael Kolb        return bundle;
24548233facddcc51865d612a919d450db6954aa48e3Michael Kolb    }
24558233facddcc51865d612a919d450db6954aa48e3Michael Kolb
24568233facddcc51865d612a919d450db6954aa48e3Michael Kolb    /**
24570035fadb375ff0b549b84605eb9aea150d31677aMichael Kolb     * helper method for key handler
24580035fadb375ff0b549b84605eb9aea150d31677aMichael Kolb     * returns the current tab if it can't advance
24590035fadb375ff0b549b84605eb9aea150d31677aMichael Kolb     */
2460c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb    private Tab getNextTab() {
2461c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb        return mTabControl.getTab(Math.min(mTabControl.getTabCount() - 1,
2462c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb                mTabControl.getCurrentPosition() + 1));
24630035fadb375ff0b549b84605eb9aea150d31677aMichael Kolb    }
24640035fadb375ff0b549b84605eb9aea150d31677aMichael Kolb
24650035fadb375ff0b549b84605eb9aea150d31677aMichael Kolb    /**
24660035fadb375ff0b549b84605eb9aea150d31677aMichael Kolb     * helper method for key handler
24670035fadb375ff0b549b84605eb9aea150d31677aMichael Kolb     * returns the current tab if it can't advance
24680035fadb375ff0b549b84605eb9aea150d31677aMichael Kolb     */
2469c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb    private Tab getPrevTab() {
2470c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb        return  mTabControl.getTab(Math.max(0,
2471c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb                mTabControl.getCurrentPosition() - 1));
24720035fadb375ff0b549b84605eb9aea150d31677aMichael Kolb    }
24730035fadb375ff0b549b84605eb9aea150d31677aMichael Kolb
24740035fadb375ff0b549b84605eb9aea150d31677aMichael Kolb    /**
24758233facddcc51865d612a919d450db6954aa48e3Michael Kolb     * handle key events in browser
24768233facddcc51865d612a919d450db6954aa48e3Michael Kolb     *
24778233facddcc51865d612a919d450db6954aa48e3Michael Kolb     * @param keyCode
24788233facddcc51865d612a919d450db6954aa48e3Michael Kolb     * @param event
24798233facddcc51865d612a919d450db6954aa48e3Michael Kolb     * @return true if handled, false to pass to super
24808233facddcc51865d612a919d450db6954aa48e3Michael Kolb     */
24818233facddcc51865d612a919d450db6954aa48e3Michael Kolb    boolean onKeyDown(int keyCode, KeyEvent event) {
2482160bbb9565b63302c88b032e4653f8268553175fCary Clark        boolean noModifiers = event.hasNoModifiers();
24838233facddcc51865d612a919d450db6954aa48e3Michael Kolb        // Even if MENU is already held down, we need to call to super to open
24848233facddcc51865d612a919d450db6954aa48e3Michael Kolb        // the IME on long press.
24852814a362c21ac219410d9b54e1bd3e8152b845c7Michael Kolb        if (KeyEvent.KEYCODE_MENU == keyCode) {
24864bd767d2f4ce166a44687170c6af18e242447205Michael Kolb            if (mOptionsMenuHandler != null) {
24874bd767d2f4ce166a44687170c6af18e242447205Michael Kolb                return false;
24884bd767d2f4ce166a44687170c6af18e242447205Michael Kolb            } else {
24894bd767d2f4ce166a44687170c6af18e242447205Michael Kolb                event.startTracking();
24904bd767d2f4ce166a44687170c6af18e242447205Michael Kolb                return true;
24914bd767d2f4ce166a44687170c6af18e242447205Michael Kolb            }
24922814a362c21ac219410d9b54e1bd3e8152b845c7Michael Kolb        }
2493dc2ee1bfb50b7bec0cf3215e3d298b246dc71101Michael Kolb        if (!noModifiers
2494dc2ee1bfb50b7bec0cf3215e3d298b246dc71101Michael Kolb                && ((KeyEvent.KEYCODE_MENU == keyCode)
2495dc2ee1bfb50b7bec0cf3215e3d298b246dc71101Michael Kolb                        || (KeyEvent.KEYCODE_CTRL_LEFT == keyCode)
2496dc2ee1bfb50b7bec0cf3215e3d298b246dc71101Michael Kolb                        || (KeyEvent.KEYCODE_CTRL_RIGHT == keyCode))) {
24978233facddcc51865d612a919d450db6954aa48e3Michael Kolb            mMenuIsDown = true;
24988233facddcc51865d612a919d450db6954aa48e3Michael Kolb            return false;
24998233facddcc51865d612a919d450db6954aa48e3Michael Kolb        }
25008233facddcc51865d612a919d450db6954aa48e3Michael Kolb
25018ff8c66a4b2351add40d391a9bd5ea91e840c5f6Cary Clark        WebView webView = getCurrentTopWebView();
2502ef654f1dd80f55609060005342fc4f2cde62990cJohn Reck        Tab tab = getCurrentTab();
2503ef654f1dd80f55609060005342fc4f2cde62990cJohn Reck        if (webView == null || tab == null) return false;
25048ff8c66a4b2351add40d391a9bd5ea91e840c5f6Cary Clark
2505160bbb9565b63302c88b032e4653f8268553175fCary Clark        boolean ctrl = event.hasModifiers(KeyEvent.META_CTRL_ON);
2506160bbb9565b63302c88b032e4653f8268553175fCary Clark        boolean shift = event.hasModifiers(KeyEvent.META_SHIFT_ON);
25078ff8c66a4b2351add40d391a9bd5ea91e840c5f6Cary Clark
25088233facddcc51865d612a919d450db6954aa48e3Michael Kolb        switch(keyCode) {
25090035fadb375ff0b549b84605eb9aea150d31677aMichael Kolb            case KeyEvent.KEYCODE_TAB:
25100035fadb375ff0b549b84605eb9aea150d31677aMichael Kolb                if (event.isCtrlPressed()) {
25110035fadb375ff0b549b84605eb9aea150d31677aMichael Kolb                    if (event.isShiftPressed()) {
25120035fadb375ff0b549b84605eb9aea150d31677aMichael Kolb                        // prev tab
2513c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb                        switchToTab(getPrevTab());
25140035fadb375ff0b549b84605eb9aea150d31677aMichael Kolb                    } else {
25150035fadb375ff0b549b84605eb9aea150d31677aMichael Kolb                        // next tab
2516c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb                        switchToTab(getNextTab());
25170035fadb375ff0b549b84605eb9aea150d31677aMichael Kolb                    }
25180035fadb375ff0b549b84605eb9aea150d31677aMichael Kolb                    return true;
25190035fadb375ff0b549b84605eb9aea150d31677aMichael Kolb                }
25200035fadb375ff0b549b84605eb9aea150d31677aMichael Kolb                break;
25218233facddcc51865d612a919d450db6954aa48e3Michael Kolb            case KeyEvent.KEYCODE_SPACE:
25228233facddcc51865d612a919d450db6954aa48e3Michael Kolb                // WebView/WebTextView handle the keys in the KeyDown. As
25238233facddcc51865d612a919d450db6954aa48e3Michael Kolb                // the Activity's shortcut keys are only handled when WebView
25248233facddcc51865d612a919d450db6954aa48e3Michael Kolb                // doesn't, have to do it in onKeyDown instead of onKeyUp.
2525160bbb9565b63302c88b032e4653f8268553175fCary Clark                if (shift) {
25268233facddcc51865d612a919d450db6954aa48e3Michael Kolb                    pageUp();
2527160bbb9565b63302c88b032e4653f8268553175fCary Clark                } else if (noModifiers) {
25288233facddcc51865d612a919d450db6954aa48e3Michael Kolb                    pageDown();
25298233facddcc51865d612a919d450db6954aa48e3Michael Kolb                }
25308233facddcc51865d612a919d450db6954aa48e3Michael Kolb                return true;
25318233facddcc51865d612a919d450db6954aa48e3Michael Kolb            case KeyEvent.KEYCODE_BACK:
2532160bbb9565b63302c88b032e4653f8268553175fCary Clark                if (!noModifiers) break;
2533e6bf4abbb12a83fc0256d98d9d5cb36ee326f1ceJohn Reck                event.startTracking();
2534e6bf4abbb12a83fc0256d98d9d5cb36ee326f1ceJohn Reck                return true;
25358ff8c66a4b2351add40d391a9bd5ea91e840c5f6Cary Clark            case KeyEvent.KEYCODE_DPAD_LEFT:
25368ff8c66a4b2351add40d391a9bd5ea91e840c5f6Cary Clark                if (ctrl) {
2537ef654f1dd80f55609060005342fc4f2cde62990cJohn Reck                    tab.goBack();
25388ff8c66a4b2351add40d391a9bd5ea91e840c5f6Cary Clark                    return true;
25398ff8c66a4b2351add40d391a9bd5ea91e840c5f6Cary Clark                }
25408ff8c66a4b2351add40d391a9bd5ea91e840c5f6Cary Clark                break;
25418ff8c66a4b2351add40d391a9bd5ea91e840c5f6Cary Clark            case KeyEvent.KEYCODE_DPAD_RIGHT:
25428ff8c66a4b2351add40d391a9bd5ea91e840c5f6Cary Clark                if (ctrl) {
2543ef654f1dd80f55609060005342fc4f2cde62990cJohn Reck                    tab.goForward();
25448ff8c66a4b2351add40d391a9bd5ea91e840c5f6Cary Clark                    return true;
25458ff8c66a4b2351add40d391a9bd5ea91e840c5f6Cary Clark                }
25468ff8c66a4b2351add40d391a9bd5ea91e840c5f6Cary Clark                break;
25478ff8c66a4b2351add40d391a9bd5ea91e840c5f6Cary Clark            case KeyEvent.KEYCODE_A:
25488ff8c66a4b2351add40d391a9bd5ea91e840c5f6Cary Clark                if (ctrl) {
25498ff8c66a4b2351add40d391a9bd5ea91e840c5f6Cary Clark                    webView.selectAll();
25508ff8c66a4b2351add40d391a9bd5ea91e840c5f6Cary Clark                    return true;
25518ff8c66a4b2351add40d391a9bd5ea91e840c5f6Cary Clark                }
25528ff8c66a4b2351add40d391a9bd5ea91e840c5f6Cary Clark                break;
2553a418306e08e008da99cef929c48e05d2a101ceafMichael Kolb//          case KeyEvent.KEYCODE_B:    // menu
25548ff8c66a4b2351add40d391a9bd5ea91e840c5f6Cary Clark            case KeyEvent.KEYCODE_C:
25558ff8c66a4b2351add40d391a9bd5ea91e840c5f6Cary Clark                if (ctrl) {
25568ff8c66a4b2351add40d391a9bd5ea91e840c5f6Cary Clark                    webView.copySelection();
25578ff8c66a4b2351add40d391a9bd5ea91e840c5f6Cary Clark                    return true;
25588ff8c66a4b2351add40d391a9bd5ea91e840c5f6Cary Clark                }
25598ff8c66a4b2351add40d391a9bd5ea91e840c5f6Cary Clark                break;
2560a418306e08e008da99cef929c48e05d2a101ceafMichael Kolb//          case KeyEvent.KEYCODE_D:    // menu
25618ff8c66a4b2351add40d391a9bd5ea91e840c5f6Cary Clark//          case KeyEvent.KEYCODE_E:    // in Chrome: puts '?' in URL bar
2562a418306e08e008da99cef929c48e05d2a101ceafMichael Kolb//          case KeyEvent.KEYCODE_F:    // menu
25638ff8c66a4b2351add40d391a9bd5ea91e840c5f6Cary Clark//          case KeyEvent.KEYCODE_G:    // in Chrome: finds next match
2564a418306e08e008da99cef929c48e05d2a101ceafMichael Kolb//          case KeyEvent.KEYCODE_H:    // menu
25658ff8c66a4b2351add40d391a9bd5ea91e840c5f6Cary Clark//          case KeyEvent.KEYCODE_I:    // unused
2566a418306e08e008da99cef929c48e05d2a101ceafMichael Kolb//          case KeyEvent.KEYCODE_J:    // menu
25678ff8c66a4b2351add40d391a9bd5ea91e840c5f6Cary Clark//          case KeyEvent.KEYCODE_K:    // in Chrome: puts '?' in URL bar
2568a418306e08e008da99cef929c48e05d2a101ceafMichael Kolb//          case KeyEvent.KEYCODE_L:    // menu
25698ff8c66a4b2351add40d391a9bd5ea91e840c5f6Cary Clark//          case KeyEvent.KEYCODE_M:    // unused
25708ff8c66a4b2351add40d391a9bd5ea91e840c5f6Cary Clark//          case KeyEvent.KEYCODE_N:    // in Chrome: new window
25718ff8c66a4b2351add40d391a9bd5ea91e840c5f6Cary Clark//          case KeyEvent.KEYCODE_O:    // in Chrome: open file
25728ff8c66a4b2351add40d391a9bd5ea91e840c5f6Cary Clark//          case KeyEvent.KEYCODE_P:    // in Chrome: print page
25738ff8c66a4b2351add40d391a9bd5ea91e840c5f6Cary Clark//          case KeyEvent.KEYCODE_Q:    // unused
2574dc2ee1bfb50b7bec0cf3215e3d298b246dc71101Michael Kolb//          case KeyEvent.KEYCODE_R:
25758ff8c66a4b2351add40d391a9bd5ea91e840c5f6Cary Clark//          case KeyEvent.KEYCODE_S:    // in Chrome: saves page
25768ff8c66a4b2351add40d391a9bd5ea91e840c5f6Cary Clark            case KeyEvent.KEYCODE_T:
2577dc2ee1bfb50b7bec0cf3215e3d298b246dc71101Michael Kolb                // we can't use the ctrl/shift flags, they check for
2578dc2ee1bfb50b7bec0cf3215e3d298b246dc71101Michael Kolb                // exclusive use of a modifier
2579dc2ee1bfb50b7bec0cf3215e3d298b246dc71101Michael Kolb                if (event.isCtrlPressed()) {
25808ff8c66a4b2351add40d391a9bd5ea91e840c5f6Cary Clark                    if (event.isShiftPressed()) {
2581519d22840ea587988214a625dc8106e1302ac4a9Michael Kolb                        openIncognitoTab();
25828ff8c66a4b2351add40d391a9bd5ea91e840c5f6Cary Clark                    } else {
25838ff8c66a4b2351add40d391a9bd5ea91e840c5f6Cary Clark                        openTabToHomePage();
25848ff8c66a4b2351add40d391a9bd5ea91e840c5f6Cary Clark                    }
25858ff8c66a4b2351add40d391a9bd5ea91e840c5f6Cary Clark                    return true;
25868ff8c66a4b2351add40d391a9bd5ea91e840c5f6Cary Clark                }
25878ff8c66a4b2351add40d391a9bd5ea91e840c5f6Cary Clark                break;
25888ff8c66a4b2351add40d391a9bd5ea91e840c5f6Cary Clark//          case KeyEvent.KEYCODE_U:    // in Chrome: opens source of page
25898ff8c66a4b2351add40d391a9bd5ea91e840c5f6Cary Clark//          case KeyEvent.KEYCODE_V:    // text view intercepts to paste
25901a2eba437d354885e8f55d34e59200cd091f90b0Michael Kolb            case KeyEvent.KEYCODE_W:    // in Chrome: close tab
25911a2eba437d354885e8f55d34e59200cd091f90b0Michael Kolb                if (ctrl) {
25921a2eba437d354885e8f55d34e59200cd091f90b0Michael Kolb                    closeCurrentTab();
25931a2eba437d354885e8f55d34e59200cd091f90b0Michael Kolb                    return true;
25941a2eba437d354885e8f55d34e59200cd091f90b0Michael Kolb                }
25951a2eba437d354885e8f55d34e59200cd091f90b0Michael Kolb                break;
25968ff8c66a4b2351add40d391a9bd5ea91e840c5f6Cary Clark//          case KeyEvent.KEYCODE_X:    // text view intercepts to cut
25978ff8c66a4b2351add40d391a9bd5ea91e840c5f6Cary Clark//          case KeyEvent.KEYCODE_Y:    // unused
25988ff8c66a4b2351add40d391a9bd5ea91e840c5f6Cary Clark//          case KeyEvent.KEYCODE_Z:    // unused
25998233facddcc51865d612a919d450db6954aa48e3Michael Kolb        }
2600dc2ee1bfb50b7bec0cf3215e3d298b246dc71101Michael Kolb        // it is a regular key and webview is not null
2601dc2ee1bfb50b7bec0cf3215e3d298b246dc71101Michael Kolb         return mUi.dispatchKey(keyCode, event);
26028233facddcc51865d612a919d450db6954aa48e3Michael Kolb    }
26038233facddcc51865d612a919d450db6954aa48e3Michael Kolb
2604e6bf4abbb12a83fc0256d98d9d5cb36ee326f1ceJohn Reck    boolean onKeyLongPress(int keyCode, KeyEvent event) {
2605e6bf4abbb12a83fc0256d98d9d5cb36ee326f1ceJohn Reck        switch(keyCode) {
2606e6bf4abbb12a83fc0256d98d9d5cb36ee326f1ceJohn Reck        case KeyEvent.KEYCODE_BACK:
2607e6bf4abbb12a83fc0256d98d9d5cb36ee326f1ceJohn Reck            if (mUi.showsWeb()) {
2608e6bf4abbb12a83fc0256d98d9d5cb36ee326f1ceJohn Reck                bookmarksOrHistoryPicker(true);
2609e6bf4abbb12a83fc0256d98d9d5cb36ee326f1ceJohn Reck                return true;
2610e6bf4abbb12a83fc0256d98d9d5cb36ee326f1ceJohn Reck            }
2611e6bf4abbb12a83fc0256d98d9d5cb36ee326f1ceJohn Reck            break;
2612e6bf4abbb12a83fc0256d98d9d5cb36ee326f1ceJohn Reck        }
2613e6bf4abbb12a83fc0256d98d9d5cb36ee326f1ceJohn Reck        return false;
2614e6bf4abbb12a83fc0256d98d9d5cb36ee326f1ceJohn Reck    }
2615e6bf4abbb12a83fc0256d98d9d5cb36ee326f1ceJohn Reck
26168233facddcc51865d612a919d450db6954aa48e3Michael Kolb    boolean onKeyUp(int keyCode, KeyEvent event) {
26172814a362c21ac219410d9b54e1bd3e8152b845c7Michael Kolb        if (KeyEvent.KEYCODE_MENU == keyCode) {
26182814a362c21ac219410d9b54e1bd3e8152b845c7Michael Kolb            mMenuIsDown = false;
26192814a362c21ac219410d9b54e1bd3e8152b845c7Michael Kolb            if (event.isTracking() && !event.isCanceled()) {
26204bd767d2f4ce166a44687170c6af18e242447205Michael Kolb                return onMenuKey();
26212814a362c21ac219410d9b54e1bd3e8152b845c7Michael Kolb            }
26222814a362c21ac219410d9b54e1bd3e8152b845c7Michael Kolb        }
2623160bbb9565b63302c88b032e4653f8268553175fCary Clark        if (!event.hasNoModifiers()) return false;
26248233facddcc51865d612a919d450db6954aa48e3Michael Kolb        switch(keyCode) {
26258233facddcc51865d612a919d450db6954aa48e3Michael Kolb            case KeyEvent.KEYCODE_BACK:
26268233facddcc51865d612a919d450db6954aa48e3Michael Kolb                if (event.isTracking() && !event.isCanceled()) {
26278233facddcc51865d612a919d450db6954aa48e3Michael Kolb                    onBackKey();
26288233facddcc51865d612a919d450db6954aa48e3Michael Kolb                    return true;
26298233facddcc51865d612a919d450db6954aa48e3Michael Kolb                }
26308233facddcc51865d612a919d450db6954aa48e3Michael Kolb                break;
26318233facddcc51865d612a919d450db6954aa48e3Michael Kolb        }
26328233facddcc51865d612a919d450db6954aa48e3Michael Kolb        return false;
26338233facddcc51865d612a919d450db6954aa48e3Michael Kolb    }
26348233facddcc51865d612a919d450db6954aa48e3Michael Kolb
26358233facddcc51865d612a919d450db6954aa48e3Michael Kolb    public boolean isMenuDown() {
26368233facddcc51865d612a919d450db6954aa48e3Michael Kolb        return mMenuIsDown;
26378233facddcc51865d612a919d450db6954aa48e3Michael Kolb    }
26388233facddcc51865d612a919d450db6954aa48e3Michael Kolb
26398029a777106fa6fb911ee1d58402b0de768a583aBen Murdoch    public void setupAutoFill(Message message) {
26408029a777106fa6fb911ee1d58402b0de768a583aBen Murdoch        // Open the settings activity at the AutoFill profile fragment so that
26418029a777106fa6fb911ee1d58402b0de768a583aBen Murdoch        // the user can create a new profile. When they return, we will dispatch
26428029a777106fa6fb911ee1d58402b0de768a583aBen Murdoch        // the message so that we can autofill the form using their new profile.
26438029a777106fa6fb911ee1d58402b0de768a583aBen Murdoch        Intent intent = new Intent(mActivity, BrowserPreferencesPage.class);
26448029a777106fa6fb911ee1d58402b0de768a583aBen Murdoch        intent.putExtra(PreferenceActivity.EXTRA_SHOW_FRAGMENT,
26458029a777106fa6fb911ee1d58402b0de768a583aBen Murdoch                AutoFillSettingsFragment.class.getName());
26468029a777106fa6fb911ee1d58402b0de768a583aBen Murdoch        mAutoFillSetupMessage = message;
26478029a777106fa6fb911ee1d58402b0de768a583aBen Murdoch        mActivity.startActivityForResult(intent, AUTOFILL_SETUP);
26488029a777106fa6fb911ee1d58402b0de768a583aBen Murdoch    }
2649b3417f0a68a1efc64604ea354ae7f856ce79cb16John Reck
2650b3417f0a68a1efc64604ea354ae7f856ce79cb16John Reck    @Override
2651b3417f0a68a1efc64604ea354ae7f856ce79cb16John Reck    public void registerOptionsMenuHandler(OptionsMenuHandler handler) {
2652b3417f0a68a1efc64604ea354ae7f856ce79cb16John Reck        mOptionsMenuHandler = handler;
2653b3417f0a68a1efc64604ea354ae7f856ce79cb16John Reck    }
2654b3417f0a68a1efc64604ea354ae7f856ce79cb16John Reck
2655b3417f0a68a1efc64604ea354ae7f856ce79cb16John Reck    @Override
2656b3417f0a68a1efc64604ea354ae7f856ce79cb16John Reck    public void unregisterOptionsMenuHandler(OptionsMenuHandler handler) {
2657b3417f0a68a1efc64604ea354ae7f856ce79cb16John Reck        if (mOptionsMenuHandler == handler) {
2658b3417f0a68a1efc64604ea354ae7f856ce79cb16John Reck            mOptionsMenuHandler = null;
2659b3417f0a68a1efc64604ea354ae7f856ce79cb16John Reck        }
2660b3417f0a68a1efc64604ea354ae7f856ce79cb16John Reck    }
2661b3417f0a68a1efc64604ea354ae7f856ce79cb16John Reck
26625119edd5744cfc6d3a8ed480a8853586c737bed4Narayan Kamath    @Override
26635119edd5744cfc6d3a8ed480a8853586c737bed4Narayan Kamath    public void registerDropdownChangeListener(DropdownChangeListener d) {
26645119edd5744cfc6d3a8ed480a8853586c737bed4Narayan Kamath        mUi.registerDropdownChangeListener(d);
26655119edd5744cfc6d3a8ed480a8853586c737bed4Narayan Kamath    }
2666fbc579af4749526882c764cd176a167205306fe9Michael Kolb
2667fbc579af4749526882c764cd176a167205306fe9Michael Kolb    public boolean onSearchRequested() {
2668fbc579af4749526882c764cd176a167205306fe9Michael Kolb        mUi.editUrl(false);
2669fbc579af4749526882c764cd176a167205306fe9Michael Kolb        return true;
2670fbc579af4749526882c764cd176a167205306fe9Michael Kolb    }
2671fbc579af4749526882c764cd176a167205306fe9Michael Kolb
26728233facddcc51865d612a919d450db6954aa48e3Michael Kolb}
2673