BrowserActivity.java revision 8ce956c6076a89aae85856f35b94bad7fc8fa1f1
10c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project/*
20c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project * Copyright (C) 2006 The Android Open Source Project
30c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project *
40c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
50c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project * you may not use this file except in compliance with the License.
60c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project * You may obtain a copy of the License at
70c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project *
80c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
90c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project *
100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project * Unless required by applicable law or agreed to in writing, software
110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project * See the License for the specific language governing permissions and
140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project * limitations under the License.
150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project */
160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectpackage com.android.browser;
180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
19ed217745066c160f785626e9a15ebe70af5e25e4Michael Kolbimport android.app.ActionBar;
200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.app.Activity;
210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.app.AlertDialog;
220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.app.ProgressDialog;
230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.app.SearchManager;
240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.content.ActivityNotFoundException;
250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.content.BroadcastReceiver;
2680f32627140aefe828ad539f66fc439d1580bae7Dianne Hackbornimport android.content.ClipboardManager;
270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.content.ComponentName;
2858d56c6b5052faa86083965132cd51b1a9594d0eLeon Scrogginsimport android.content.ContentProvider;
2958d56c6b5052faa86083965132cd51b1a9594d0eLeon Scrogginsimport android.content.ContentProviderClient;
300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.content.ContentResolver;
31b6b7f9ef3b4ed220063f555d8b7c205210a61a04Leon Scrogginsimport android.content.ContentUris;
320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.content.ContentValues;
330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.content.Context;
340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.content.DialogInterface;
350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.content.Intent;
360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.content.IntentFilter;
37b4da0ad0351996f639b50f9f29b123a9b5c24fd0Grace Klobaimport android.content.pm.PackageInfo;
380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.content.pm.PackageManager;
390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.content.pm.ResolveInfo;
400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.content.res.Configuration;
410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.content.res.Resources;
420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.database.Cursor;
430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.graphics.Bitmap;
44540035dfd1347c78eeec10ec0847e18fcc50ef36Andrei Popescuimport android.graphics.BitmapFactory;
450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.graphics.Canvas;
460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.graphics.Picture;
473bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scrogginsimport android.graphics.PixelFormat;
480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.graphics.drawable.Drawable;
490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.net.ConnectivityManager;
5056199cc25e7ee0455ec2a8099098b66b8554f677Andrei Popescuimport android.net.NetworkInfo;
510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.net.Uri;
520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.net.WebAddress;
530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.net.http.SslCertificate;
540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.net.http.SslError;
550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.os.AsyncTask;
560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.os.Bundle;
570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.os.Debug;
580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.os.Environment;
590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.os.Handler;
600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.os.Message;
610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.os.PowerManager;
620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.os.Process;
630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.os.SystemClock;
640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.provider.Browser;
658ce956c6076a89aae85856f35b94bad7fc8fa1f1Jeff Hamiltonimport android.provider.BrowserContract;
665e335a381a0cd66e94117b202c1f34f5cb29c9b8Cary Clarkimport android.provider.ContactsContract;
67a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolbimport android.provider.ContactsContract.Intents.Insert;
680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.provider.Downloads;
690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.provider.MediaStore;
70a1cc3fdce19a336c251297c61cd83ac6cf767cd1Leon Scrogginsimport android.speech.RecognizerResultsIntent;
710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.text.TextUtils;
720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.text.format.DateFormat;
730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.util.Log;
74385effd3192a16b737a7d4fbe4fc71c6cf467627Dianne Hackbornimport android.util.Patterns;
758e4fbf1b26c2cc05a56ba2d4e7d1eda7d1574e91Leon Scroggins IIIimport android.view.ActionMode;
760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.view.ContextMenu;
77a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolbimport android.view.ContextMenu.ContextMenuInfo;
780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.view.Gravity;
790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.view.KeyEvent;
800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.view.LayoutInflater;
810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.view.Menu;
820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.view.MenuInflater;
830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.view.MenuItem;
84a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolbimport android.view.MenuItem.OnMenuItemClickListener;
850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.view.View;
860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.view.ViewGroup;
870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.view.Window;
880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.view.WindowManager;
892b34599c39d2c04c242d2a0ed755705fc414541dSvetoslav Ganovimport android.view.accessibility.AccessibilityManager;
900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.webkit.CookieManager;
910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.webkit.CookieSyncManager;
920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.webkit.DownloadListener;
930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.webkit.HttpAuthHandler;
94b4da0ad0351996f639b50f9f29b123a9b5c24fd0Grace Klobaimport android.webkit.PluginManager;
950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.webkit.SslErrorHandler;
960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.webkit.URLUtil;
97cb6cc864e53f7d916622daf3b2cec133b36d6a55Leon Clarkeimport android.webkit.ValueCallback;
980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.webkit.WebChromeClient;
990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.webkit.WebHistoryItem;
1000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.webkit.WebIconDatabase;
1010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.webkit.WebView;
1020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.widget.EditText;
1030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.widget.FrameLayout;
1040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.widget.LinearLayout;
1050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.widget.TextView;
1060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.widget.Toast;
1070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
108a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolbimport com.android.browser.ScrollWebView.ScrollListener;
10910d1cca0c208d1f9db23893a8515685e04cfe224Bjorn Bringertimport com.android.common.Search;
1101fe13a5230e319df42b21939a14d127bd9bf3856Leon Scrogginsimport com.android.common.speech.LoggingEvents;
1115ee906c089567bca705e18561357510d7b55cb5aDan Egnor
112b6b7f9ef3b4ed220063f555d8b7c205210a61a04Leon Scrogginsimport java.io.ByteArrayOutputStream;
1130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport java.io.File;
1144f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdochimport java.io.IOException;
1154f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdochimport java.io.InputStream;
1160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport java.net.MalformedURLException;
1179918943559193e3e047a1c18442e2cdb0fe22b15Dianne Hackbornimport java.net.URISyntaxException;
1180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport java.net.URL;
1190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport java.net.URLEncoder;
1200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport java.util.Date;
1210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport java.util.HashMap;
12230995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescuimport java.util.HashSet;
12300f54c589fd38431efd42ea2a551a49e64d595d5Grace Klobaimport java.util.Iterator;
12430995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescuimport java.util.List;
125068e48b469f5abca53ee3da38f933cf2c25c93b8Grace Klobaimport java.util.Map;
12630995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescuimport java.util.Set;
127fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolbimport java.util.Vector;
1280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport java.util.regex.Matcher;
1290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport java.util.regex.Pattern;
1300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
1310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectpublic class BrowserActivity extends Activity
13298d5fce7c687cfcc956b10d44946d31f39b6dc15Shimeng (Simon) Wang    implements View.OnCreateContextMenuListener, DownloadListener {
1330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
13431a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort    /* Define some aliases to make these debugging flags easier to refer to.
13531a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort     * This file imports android.provider.Browser, so we can't just refer to "Browser.DEBUG".
13631a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort     */
13731a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort    private final static boolean DEBUG = com.android.browser.Browser.DEBUG;
13831a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort    private final static boolean LOGV_ENABLED = com.android.browser.Browser.LOGV_ENABLED;
13931a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort    private final static boolean LOGD_ENABLED = com.android.browser.Browser.LOGD_ENABLED;
14031a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort
141565505b1a2c1d3099496af5910760087602e994aSatish Sampath    // These are single-character shortcuts for searching popular sources.
142565505b1a2c1d3099496af5910760087602e994aSatish Sampath    private static final int SHORTCUT_INVALID = 0;
143565505b1a2c1d3099496af5910760087602e994aSatish Sampath    private static final int SHORTCUT_GOOGLE_SEARCH = 1;
144565505b1a2c1d3099496af5910760087602e994aSatish Sampath    private static final int SHORTCUT_WIKIPEDIA_SEARCH = 2;
145565505b1a2c1d3099496af5910760087602e994aSatish Sampath    private static final int SHORTCUT_DICTIONARY_SEARCH = 3;
146565505b1a2c1d3099496af5910760087602e994aSatish Sampath    private static final int SHORTCUT_GOOGLE_MOBILE_LOCAL_SEARCH = 4;
147565505b1a2c1d3099496af5910760087602e994aSatish Sampath
148a977124eb29b195127fd161120ebbc58b255fb48Cary Clark    private static class ClearThumbnails extends AsyncTask<File, Void, Void> {
1490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        @Override
1500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public Void doInBackground(File... files) {
1510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (files != null) {
1520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                for (File f : files) {
153d6be1758b38d5b066ff10b6af906aa66c63670cdCary Clark                    if (!f.delete()) {
154d6be1758b38d5b066ff10b6af906aa66c63670cdCary Clark                      Log.e(LOGTAG, f.getPath() + " was not deleted");
155d6be1758b38d5b066ff10b6af906aa66c63670cdCary Clark                    }
1560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
1570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
1580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return null;
1590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
1600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
1610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
1623bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    /**
1633bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     * This layout holds everything you see below the status bar, including the
1643bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     * error console, the custom view container, and the webviews.
1653bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     */
1663bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    private FrameLayout mBrowserFrameLayout;
16781db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins
168d746a94137a87ffcc1fcefdac9a3764c3bc3f5cdLeon Scroggins    private boolean mXLargeScreenSize;
169d746a94137a87ffcc1fcefdac9a3764c3bc3f5cdLeon Scroggins
17022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    @Override
17122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    public void onCreate(Bundle icicle) {
17231a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort        if (LOGV_ENABLED) {
1730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Log.v(LOGTAG, this + " onStart");
1740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
1750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        super.onCreate(icicle);
1760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // test the browser in OpenGL
1770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // requestWindowFeature(Window.FEATURE_OPENGL);
1780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
179d334bf564b72416e77e707d25f8c55cfe1d85709Mike Reed        // enable this to test the browser in 32bit
180d334bf564b72416e77e707d25f8c55cfe1d85709Mike Reed        if (false) {
181d334bf564b72416e77e707d25f8c55cfe1d85709Mike Reed            getWindow().setFormat(PixelFormat.RGBX_8888);
182d334bf564b72416e77e707d25f8c55cfe1d85709Mike Reed            BitmapFactory.setDefaultConfig(Bitmap.Config.ARGB_8888);
183d334bf564b72416e77e707d25f8c55cfe1d85709Mike Reed        }
184d334bf564b72416e77e707d25f8c55cfe1d85709Mike Reed
1852b34599c39d2c04c242d2a0ed755705fc414541dSvetoslav Ganov        if (AccessibilityManager.getInstance(this).isEnabled()) {
1862b34599c39d2c04c242d2a0ed755705fc414541dSvetoslav Ganov            setDefaultKeyMode(DEFAULT_KEYS_DISABLE);
1872b34599c39d2c04c242d2a0ed755705fc414541dSvetoslav Ganov        } else {
1882b34599c39d2c04c242d2a0ed755705fc414541dSvetoslav Ganov            setDefaultKeyMode(DEFAULT_KEYS_SEARCH_LOCAL);
1892b34599c39d2c04c242d2a0ed755705fc414541dSvetoslav Ganov        }
1900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
1910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mResolver = getContentResolver();
1920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
1930923d69a8ca45222cabd82a80eaa88da9f132e9aGrace Kloba        // If this was a web search request, pass it on to the default web
1940923d69a8ca45222cabd82a80eaa88da9f132e9aGrace Kloba        // search provider and finish this activity.
1950923d69a8ca45222cabd82a80eaa88da9f132e9aGrace Kloba        if (handleWebSearchIntent(getIntent())) {
1960923d69a8ca45222cabd82a80eaa88da9f132e9aGrace Kloba            finish();
1970923d69a8ca45222cabd82a80eaa88da9f132e9aGrace Kloba            return;
1980923d69a8ca45222cabd82a80eaa88da9f132e9aGrace Kloba        }
1990923d69a8ca45222cabd82a80eaa88da9f132e9aGrace Kloba
2000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mSecLockIcon = Resources.getSystem().getDrawable(
2010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                android.R.drawable.ic_secure);
2020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mMixLockIcon = Resources.getSystem().getDrawable(
2030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                android.R.drawable.ic_partial_secure);
2040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
205ed217745066c160f785626e9a15ebe70af5e25e4Michael Kolb        // Create the tab control and our initial tab
206ed217745066c160f785626e9a15ebe70af5e25e4Michael Kolb        mTabControl = new TabControl(this);
207ed217745066c160f785626e9a15ebe70af5e25e4Michael Kolb
208ed217745066c160f785626e9a15ebe70af5e25e4Michael Kolb        mXLargeScreenSize = (getResources().getConfiguration().screenLayout
209ed217745066c160f785626e9a15ebe70af5e25e4Michael Kolb                & Configuration.SCREENLAYOUT_SIZE_MASK)
210ed217745066c160f785626e9a15ebe70af5e25e4Michael Kolb                == Configuration.SCREENLAYOUT_SIZE_XLARGE;
211ed217745066c160f785626e9a15ebe70af5e25e4Michael Kolb
21281db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins        FrameLayout frameLayout = (FrameLayout) getWindow().getDecorView()
21381db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins                .findViewById(com.android.internal.R.id.content);
2143bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins        mBrowserFrameLayout = (FrameLayout) LayoutInflater.from(this)
2153bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                .inflate(R.layout.custom_screen, null);
2163bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins        mContentView = (FrameLayout) mBrowserFrameLayout.findViewById(
2173bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                R.id.main_content);
2183bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins        mErrorConsoleContainer = (LinearLayout) mBrowserFrameLayout
2193bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                .findViewById(R.id.error_console);
2203bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins        mCustomViewContainer = (FrameLayout) mBrowserFrameLayout
2213bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                .findViewById(R.id.fullscreen_custom_content);
2223bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins        frameLayout.addView(mBrowserFrameLayout, COVER_SCREEN_PARAMS);
223e0a3666b5c0dca7352895fa8b9b4fbb2237df721Michael Kolb
224d746a94137a87ffcc1fcefdac9a3764c3bc3f5cdLeon Scroggins        if (mXLargeScreenSize) {
225a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb            mTitleBar = new TitleBarXLarge(this);
226a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb            mTitleBar.setProgress(100);
227a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb            mFakeTitleBar = new TitleBarXLarge(this);
228ed217745066c160f785626e9a15ebe70af5e25e4Michael Kolb            ActionBar actionBar = getActionBar();
229a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb            mTabBar = new TabBar(this, mTabControl, (TitleBarXLarge) mFakeTitleBar);
230ed217745066c160f785626e9a15ebe70af5e25e4Michael Kolb            actionBar.setCustomNavigationMode(mTabBar);
231d746a94137a87ffcc1fcefdac9a3764c3bc3f5cdLeon Scroggins        } else {
232571b3762a5eb9e492283e0a1e437edd209fdc0deLeon Scroggins            mTitleBar = new TitleBar(this);
233d746a94137a87ffcc1fcefdac9a3764c3bc3f5cdLeon Scroggins            // mTitleBar will be always be shown in the fully loaded mode on
234d746a94137a87ffcc1fcefdac9a3764c3bc3f5cdLeon Scroggins            // phone
235d746a94137a87ffcc1fcefdac9a3764c3bc3f5cdLeon Scroggins            mTitleBar.setProgress(100);
236d746a94137a87ffcc1fcefdac9a3764c3bc3f5cdLeon Scroggins            mFakeTitleBar = new TitleBar(this);
237d746a94137a87ffcc1fcefdac9a3764c3bc3f5cdLeon Scroggins        }
2380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
2390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Open the icon database and retain all the bookmark urls for favicons
2400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        retainIconsOnStartup();
2410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
2420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Keep a settings instance handy.
2430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mSettings = BrowserSettings.getInstance();
2440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mSettings.setTabControl(mTabControl);
2450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
2460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
2470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "Browser");
2480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
2496adacc90222a3293bc631ef88ee5613e23b2d4c0Patrick Scott        // Find out if the network is currently up.
2506adacc90222a3293bc631ef88ee5613e23b2d4c0Patrick Scott        ConnectivityManager cm = (ConnectivityManager) getSystemService(
2516adacc90222a3293bc631ef88ee5613e23b2d4c0Patrick Scott                Context.CONNECTIVITY_SERVICE);
2526adacc90222a3293bc631ef88ee5613e23b2d4c0Patrick Scott        NetworkInfo info = cm.getActiveNetworkInfo();
2536adacc90222a3293bc631ef88ee5613e23b2d4c0Patrick Scott        if (info != null) {
2546adacc90222a3293bc631ef88ee5613e23b2d4c0Patrick Scott            mIsNetworkUp = info.isAvailable();
2556adacc90222a3293bc631ef88ee5613e23b2d4c0Patrick Scott        }
2566adacc90222a3293bc631ef88ee5613e23b2d4c0Patrick Scott
257a34f686112fb4f9fbea00b8c2c47153d34e93e41Grace Kloba        /* enables registration for changes in network status from
258a34f686112fb4f9fbea00b8c2c47153d34e93e41Grace Kloba           http stack */
259a34f686112fb4f9fbea00b8c2c47153d34e93e41Grace Kloba        mNetworkStateChangedFilter = new IntentFilter();
260a34f686112fb4f9fbea00b8c2c47153d34e93e41Grace Kloba        mNetworkStateChangedFilter.addAction(
261a34f686112fb4f9fbea00b8c2c47153d34e93e41Grace Kloba                ConnectivityManager.CONNECTIVITY_ACTION);
262a34f686112fb4f9fbea00b8c2c47153d34e93e41Grace Kloba        mNetworkStateIntentReceiver = new BroadcastReceiver() {
263a34f686112fb4f9fbea00b8c2c47153d34e93e41Grace Kloba                @Override
264a34f686112fb4f9fbea00b8c2c47153d34e93e41Grace Kloba                public void onReceive(Context context, Intent intent) {
265a34f686112fb4f9fbea00b8c2c47153d34e93e41Grace Kloba                    if (intent.getAction().equals(
266a34f686112fb4f9fbea00b8c2c47153d34e93e41Grace Kloba                            ConnectivityManager.CONNECTIVITY_ACTION)) {
267e4c98469644d3fa2689cf6658b1999add13c7e0eAndrei Popescu
268e4c98469644d3fa2689cf6658b1999add13c7e0eAndrei Popescu                        NetworkInfo info = intent.getParcelableExtra(
269e4c98469644d3fa2689cf6658b1999add13c7e0eAndrei Popescu                                ConnectivityManager.EXTRA_NETWORK_INFO);
270e4c98469644d3fa2689cf6658b1999add13c7e0eAndrei Popescu                        String typeName = info.getTypeName();
271e4c98469644d3fa2689cf6658b1999add13c7e0eAndrei Popescu                        String subtypeName = info.getSubtypeName();
272e4c98469644d3fa2689cf6658b1999add13c7e0eAndrei Popescu                        sendNetworkType(typeName.toLowerCase(),
273e4c98469644d3fa2689cf6658b1999add13c7e0eAndrei Popescu                                (subtypeName != null ? subtypeName.toLowerCase() : ""));
274e4c98469644d3fa2689cf6658b1999add13c7e0eAndrei Popescu
275e4c98469644d3fa2689cf6658b1999add13c7e0eAndrei Popescu                        onNetworkToggle(info.isAvailable());
276a34f686112fb4f9fbea00b8c2c47153d34e93e41Grace Kloba                    }
277a34f686112fb4f9fbea00b8c2c47153d34e93e41Grace Kloba                }
278a34f686112fb4f9fbea00b8c2c47153d34e93e41Grace Kloba            };
279a34f686112fb4f9fbea00b8c2c47153d34e93e41Grace Kloba
280615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba        IntentFilter filter = new IntentFilter(Intent.ACTION_PACKAGE_ADDED);
281615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba        filter.addAction(Intent.ACTION_PACKAGE_REMOVED);
282615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba        filter.addDataScheme("package");
283615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba        mPackageInstallationReceiver = new BroadcastReceiver() {
284615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba            @Override
285615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba            public void onReceive(Context context, Intent intent) {
286615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                final String action = intent.getAction();
287615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                final String packageName = intent.getData()
288615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                        .getSchemeSpecificPart();
289615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                final boolean replacing = intent.getBooleanExtra(
290615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                        Intent.EXTRA_REPLACING, false);
291615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                if (Intent.ACTION_PACKAGE_REMOVED.equals(action) && replacing) {
292615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                    // if it is replacing, refreshPlugins() when adding
293615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                    return;
294615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                }
29530995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu
29630995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu                if (sGoogleApps.contains(packageName)) {
29730995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu                    BrowserActivity.this.packageChanged(packageName,
29830995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu                            Intent.ACTION_PACKAGE_ADDED.equals(action));
29930995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu                }
30030995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu
301615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                PackageManager pm = BrowserActivity.this.getPackageManager();
302615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                PackageInfo pkgInfo = null;
303615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                try {
304615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                    pkgInfo = pm.getPackageInfo(packageName,
305615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                            PackageManager.GET_PERMISSIONS);
306615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                } catch (PackageManager.NameNotFoundException e) {
307615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                    return;
308615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                }
309615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                if (pkgInfo != null) {
310615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                    String permissions[] = pkgInfo.requestedPermissions;
311615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                    if (permissions == null) {
312615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                        return;
313615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                    }
314615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                    boolean permissionOk = false;
315615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                    for (String permit : permissions) {
316615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                        if (PluginManager.PLUGIN_PERMISSION.equals(permit)) {
317615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                            permissionOk = true;
318615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                            break;
319615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                        }
320615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                    }
321615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                    if (permissionOk) {
322615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                        PluginManager.getInstance(BrowserActivity.this)
323e56a0f21b2c1483e1854d31050bbcb10693dc0e2Grace Kloba                                .refreshPlugins(true);
324615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                    }
325615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                }
326615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba            }
327615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba        };
328615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba        registerReceiver(mPackageInstallationReceiver, filter);
329615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba
3300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (!mTabControl.restoreState(icicle)) {
3310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // clear up the thumbnail directory if we can't restore the state as
3320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // none of the files in the directory are referenced any more.
3330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            new ClearThumbnails().execute(
3340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    mTabControl.getThumbnailDir().listFiles());
335aab3f09b5c2d39b19067e57635614080b2403a46Grace Kloba            // there is no quit on Android. But if we can't restore the state,
336aab3f09b5c2d39b19067e57635614080b2403a46Grace Kloba            // we can treat it as a new Browser, remove the old session cookies.
337aab3f09b5c2d39b19067e57635614080b2403a46Grace Kloba            CookieManager.getInstance().removeSessionCookie();
3380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            final Intent intent = getIntent();
3390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            final Bundle extra = intent.getExtras();
3400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Create an initial tab.
3410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // If the intent is ACTION_VIEW and data is not null, the Browser is
3420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // invoked to view the content by another application. In this case,
3430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // the tab will be close when exit.
34425ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima            UrlData urlData = getUrlDataFromIntent(intent);
34525ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima
34658d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins            String action = intent.getAction();
34722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            final Tab t = mTabControl.createNewTab(
34858d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins                    (Intent.ACTION_VIEW.equals(action) &&
34958d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins                    intent.getData() != null)
350a1cc3fdce19a336c251297c61cd83ac6cf767cd1Leon Scroggins                    || RecognizerResultsIntent.ACTION_VOICE_SEARCH_RESULTS
351a1cc3fdce19a336c251297c61cd83ac6cf767cd1Leon Scroggins                    .equals(action),
352f0f03954b3092296c58dcb040e2dabd1696dd5c4Elliott Slaughter                    intent.getStringExtra(Browser.EXTRA_APPLICATION_ID),
353f0f03954b3092296c58dcb040e2dabd1696dd5c4Elliott Slaughter                    urlData.mUrl, false);
3540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mTabControl.setCurrentTab(t);
3550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            attachTabToContentView(t);
3560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            WebView webView = t.getWebView();
3570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (extra != null) {
3580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                int scale = extra.getInt(Browser.INITIAL_ZOOM_LEVEL, 0);
3590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (scale > 0 && scale <= 1000) {
3600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    webView.setInitialScale(scale);
3610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
3620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
3630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
36425ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima            if (urlData.isEmpty()) {
36598d5fce7c687cfcc956b10d44946d31f39b6dc15Shimeng (Simon) Wang                loadUrl(webView, mSettings.getHomePage());
3660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } else {
3679d53da05812f959745810a33bb4e06b273393c42Patrick Scott                loadUrlDataIn(t, urlData);
3680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
3690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
3700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // TabControl.restoreState() will create a new tab even if
3711f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins            // restoring the state fails.
3720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            attachTabToContentView(mTabControl.getCurrentTab());
3730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
374615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba
375b4b83182219908210d4554466367736692faf6ceCary Clark        // Delete old thumbnails to save space
376b4b83182219908210d4554466367736692faf6ceCary Clark        File dir = mTabControl.getThumbnailDir();
377b4b83182219908210d4554466367736692faf6ceCary Clark        if (dir.exists()) {
378b4b83182219908210d4554466367736692faf6ceCary Clark            for (String child : dir.list()) {
379b4b83182219908210d4554466367736692faf6ceCary Clark                File f = new File(dir, child);
380b4b83182219908210d4554466367736692faf6ceCary Clark                f.delete();
381b4b83182219908210d4554466367736692faf6ceCary Clark            }
382b4b83182219908210d4554466367736692faf6ceCary Clark        }
383b4b83182219908210d4554466367736692faf6ceCary Clark
384b3c02da4553b1a629b16377970fdabae28394c94Feng Qian        // Read JavaScript flags if it exists.
385b3c02da4553b1a629b16377970fdabae28394c94Feng Qian        String jsFlags = mSettings.getJsFlags();
386b3c02da4553b1a629b16377970fdabae28394c94Feng Qian        if (jsFlags.trim().length() != 0) {
387b3c02da4553b1a629b16377970fdabae28394c94Feng Qian            mTabControl.getCurrentWebView().setJsFlags(jsFlags);
388b3c02da4553b1a629b16377970fdabae28394c94Feng Qian        }
38930995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu        // Work out which packages are installed on the system.
39030995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu        getInstalledPackages();
391a7611811e0d744a7220b7bf80c8f795af5ea53edBjorn Bringert
392a7611811e0d744a7220b7bf80c8f795af5ea53edBjorn Bringert        // Start watching the default geolocation permissions
393a7611811e0d744a7220b7bf80c8f795af5ea53edBjorn Bringert        mSystemAllowGeolocationOrigins
394a7611811e0d744a7220b7bf80c8f795af5ea53edBjorn Bringert                = new SystemAllowGeolocationOrigins(getApplicationContext());
395a7611811e0d744a7220b7bf80c8f795af5ea53edBjorn Bringert        mSystemAllowGeolocationOrigins.start();
3960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
3970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
398a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb    ScrollListener getScrollListener() {
399a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb        return mTabBar;
400a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb    }
401a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb
40258d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    /**
40358d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins     * Feed the previously stored results strings to the BrowserProvider so that
40458d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins     * the SearchDialog will show them instead of the standard searches.
40558d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins     * @param result String to show on the editable line of the SearchDialog.
40658d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins     */
40758d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    /* package */ void showVoiceSearchResults(String result) {
40858d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        ContentProviderClient client = mResolver.acquireContentProviderClient(
40958d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins                Browser.BOOKMARKS_URI);
41058d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        ContentProvider prov = client.getLocalContentProvider();
41158d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        BrowserProvider bp = (BrowserProvider) prov;
41258d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        bp.setQueryResults(mTabControl.getCurrentTab().getVoiceSearchResults());
41358d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        client.release();
41458d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins
415fbb3f15f725e890837431f402b43e802045a4f3fLeon Scroggins        Bundle bundle = createGoogleSearchSourceBundle(
416fbb3f15f725e890837431f402b43e802045a4f3fLeon Scroggins                GOOGLE_SEARCH_SOURCE_SEARCHKEY);
417fbb3f15f725e890837431f402b43e802045a4f3fLeon Scroggins        bundle.putBoolean(SearchManager.CONTEXT_IS_VOICE, true);
418fbb3f15f725e890837431f402b43e802045a4f3fLeon Scroggins        startSearch(result, false, bundle, false);
41958d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    }
42058d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins
4210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    @Override
4220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    protected void onNewIntent(Intent intent) {
42322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        Tab current = mTabControl.getCurrentTab();
4240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // When a tab is closed on exit, the current tab index is set to -1.
4250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Reset before proceed as Browser requires the current tab to be set.
4260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (current == null) {
4270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Try to reset the tab in case the index was incorrect.
4280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            current = mTabControl.getTab(0);
4290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (current == null) {
4300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // No tabs at all so just ignore this intent.
4310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                return;
4320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
4330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mTabControl.setCurrentTab(current);
4340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            attachTabToContentView(current);
4350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            resetTitleAndIcon(current.getWebView());
4360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
4370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final String action = intent.getAction();
4380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final int flags = intent.getFlags();
4390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (Intent.ACTION_MAIN.equals(action) ||
4400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                (flags & Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY) != 0) {
4410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // just resume the browser
4420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
4430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
444b8a844da0049965b3cef5739dbab19c7ac766762Leon Scroggins        // In case the SearchDialog is open.
445b8a844da0049965b3cef5739dbab19c7ac766762Leon Scroggins        ((SearchManager) getSystemService(Context.SEARCH_SERVICE))
446b8a844da0049965b3cef5739dbab19c7ac766762Leon Scroggins                .stopSearch();
447a1cc3fdce19a336c251297c61cd83ac6cf767cd1Leon Scroggins        boolean activateVoiceSearch = RecognizerResultsIntent
448a1cc3fdce19a336c251297c61cd83ac6cf767cd1Leon Scroggins                .ACTION_VOICE_SEARCH_RESULTS.equals(action);
4490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (Intent.ACTION_VIEW.equals(action)
4500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                || Intent.ACTION_SEARCH.equals(action)
4510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                || MediaStore.INTENT_ACTION_MEDIA_SEARCH.equals(action)
45258d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins                || Intent.ACTION_WEB_SEARCH.equals(action)
45358d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins                || activateVoiceSearch) {
4543b18ce37c13fce7212948df90a012d7011924a6eLeon Scroggins            if (current.isInVoiceSearchMode()) {
4553b18ce37c13fce7212948df90a012d7011924a6eLeon Scroggins                String title = current.getVoiceDisplayTitle();
4563b18ce37c13fce7212948df90a012d7011924a6eLeon Scroggins                if (title != null && title.equals(intent.getStringExtra(
4573b18ce37c13fce7212948df90a012d7011924a6eLeon Scroggins                        SearchManager.QUERY))) {
4583b18ce37c13fce7212948df90a012d7011924a6eLeon Scroggins                    // The user submitted the same search as the last voice
4593b18ce37c13fce7212948df90a012d7011924a6eLeon Scroggins                    // search, so do nothing.
4603b18ce37c13fce7212948df90a012d7011924a6eLeon Scroggins                    return;
4613b18ce37c13fce7212948df90a012d7011924a6eLeon Scroggins                }
4621fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins                if (Intent.ACTION_SEARCH.equals(action)
4631fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins                        && current.voiceSearchSourceIsGoogle()) {
4641fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins                    Intent logIntent = new Intent(
4651fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins                            LoggingEvents.ACTION_LOG_EVENT);
4661fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins                    logIntent.putExtra(LoggingEvents.EXTRA_EVENT,
4671fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins                            LoggingEvents.VoiceSearch.QUERY_UPDATED);
4681fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins                    logIntent.putExtra(
4691fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins                            LoggingEvents.VoiceSearch.EXTRA_QUERY_UPDATED_VALUE,
4701fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins                            intent.getDataString());
4711fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins                    sendBroadcast(logIntent);
4721fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins                    // Note, onPageStarted will revert the voice title bar
4731fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins                    // When http://b/issue?id=2379215 is fixed, we should update
4741fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins                    // the title bar here.
4751fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins                }
4763b18ce37c13fce7212948df90a012d7011924a6eLeon Scroggins            }
477565505b1a2c1d3099496af5910760087602e994aSatish Sampath            // If this was a search request (e.g. search query directly typed into the address bar),
478565505b1a2c1d3099496af5910760087602e994aSatish Sampath            // pass it on to the default web search provider.
479565505b1a2c1d3099496af5910760087602e994aSatish Sampath            if (handleWebSearchIntent(intent)) {
480565505b1a2c1d3099496af5910760087602e994aSatish Sampath                return;
481565505b1a2c1d3099496af5910760087602e994aSatish Sampath            }
482565505b1a2c1d3099496af5910760087602e994aSatish Sampath
48325ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima            UrlData urlData = getUrlDataFromIntent(intent);
48425ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima            if (urlData.isEmpty()) {
48525ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima                urlData = new UrlData(mSettings.getHomePage());
4860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
48725ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima
488cc63403643786905262f505ab5266d8e80b9924cGrace Kloba            final String appId = intent
489cc63403643786905262f505ab5266d8e80b9924cGrace Kloba                    .getStringExtra(Browser.EXTRA_APPLICATION_ID);
4904720868afa09efffadd845019f2d8268ae3f2c78Leon Scroggins            if ((Intent.ACTION_VIEW.equals(action)
4914720868afa09efffadd845019f2d8268ae3f2c78Leon Scroggins                    // If a voice search has no appId, it means that it came
4924720868afa09efffadd845019f2d8268ae3f2c78Leon Scroggins                    // from the browser.  In that case, reuse the current tab.
4934720868afa09efffadd845019f2d8268ae3f2c78Leon Scroggins                    || (activateVoiceSearch && appId != null))
494cc63403643786905262f505ab5266d8e80b9924cGrace Kloba                    && !getPackageName().equals(appId)
495cc63403643786905262f505ab5266d8e80b9924cGrace Kloba                    && (flags & Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT) != 0) {
49622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                Tab appTab = mTabControl.getTabFromId(appId);
497f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                if (appTab != null) {
498f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    Log.i(LOGTAG, "Reusing tab for " + appId);
499f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    // Dismiss the subwindow if applicable.
500f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    dismissSubWindow(appTab);
501f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    // Since we might kill the WebView, remove it from the
502f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    // content view first.
503f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    removeTabFromContentView(appTab);
504f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    // Recreate the main WebView after destroying the old one.
505f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    // If the WebView has the same original url and is on that
506f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    // page, it can be reused.
507f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    boolean needsLoad =
5086eac63e78d43d04e31c4d16830c44c4d9df82639Leon Scroggins                            mTabControl.recreateWebView(appTab, urlData);
509bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch
510f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    if (current != appTab) {
5111f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                        switchToTab(mTabControl.getTabIndex(appTab));
5121f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                        if (needsLoad) {
5139d53da05812f959745810a33bb4e06b273393c42Patrick Scott                            loadUrlDataIn(appTab, urlData);
5141f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                        }
515f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    } else {
5161f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                        // If the tab was the current tab, we have to attach
5171f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                        // it to the view system again.
5181f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                        attachTabToContentView(appTab);
5191f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                        if (needsLoad) {
5209d53da05812f959745810a33bb4e06b273393c42Patrick Scott                            loadUrlDataIn(appTab, urlData);
521f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                        }
522f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    }
523f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    return;
524cd11589fc3930906d4b9b7dd18aa52a9f1eb0c8aPatrick Scott                } else {
525cd11589fc3930906d4b9b7dd18aa52a9f1eb0c8aPatrick Scott                    // No matching application tab, try to find a regular tab
526cd11589fc3930906d4b9b7dd18aa52a9f1eb0c8aPatrick Scott                    // with a matching url.
527cd11589fc3930906d4b9b7dd18aa52a9f1eb0c8aPatrick Scott                    appTab = mTabControl.findUnusedTabWithUrl(urlData.mUrl);
52825515f8bd458a2471d13d876cfb0e18d8ff2a00fLeon Scroggins                    if (appTab != null) {
52925515f8bd458a2471d13d876cfb0e18d8ff2a00fLeon Scroggins                        if (current != appTab) {
53025515f8bd458a2471d13d876cfb0e18d8ff2a00fLeon Scroggins                            switchToTab(mTabControl.getTabIndex(appTab));
53125515f8bd458a2471d13d876cfb0e18d8ff2a00fLeon Scroggins                        }
53225515f8bd458a2471d13d876cfb0e18d8ff2a00fLeon Scroggins                        // Otherwise, we are already viewing the correct tab.
533cd11589fc3930906d4b9b7dd18aa52a9f1eb0c8aPatrick Scott                    } else {
534cd11589fc3930906d4b9b7dd18aa52a9f1eb0c8aPatrick Scott                        // if FLAG_ACTIVITY_BROUGHT_TO_FRONT flag is on, the url
535cd11589fc3930906d4b9b7dd18aa52a9f1eb0c8aPatrick Scott                        // will be opened in a new tab unless we have reached
536cd11589fc3930906d4b9b7dd18aa52a9f1eb0c8aPatrick Scott                        // MAX_TABS. Then the url will be opened in the current
537cd11589fc3930906d4b9b7dd18aa52a9f1eb0c8aPatrick Scott                        // tab. If a new tab is created, it will have "true" for
538cd11589fc3930906d4b9b7dd18aa52a9f1eb0c8aPatrick Scott                        // exit on close.
5391f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                        openTabAndShow(urlData, true, appId);
540cd11589fc3930906d4b9b7dd18aa52a9f1eb0c8aPatrick Scott                    }
541f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                }
5420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } else {
543638d3f45791a31d0b290e180b93bad49576eb6d3Grace Kloba                if (!urlData.isEmpty()
544638d3f45791a31d0b290e180b93bad49576eb6d3Grace Kloba                        && urlData.mUrl.startsWith("about:debug")) {
545638d3f45791a31d0b290e180b93bad49576eb6d3Grace Kloba                    if ("about:debug.dom".equals(urlData.mUrl)) {
546638d3f45791a31d0b290e180b93bad49576eb6d3Grace Kloba                        current.getWebView().dumpDomTree(false);
547638d3f45791a31d0b290e180b93bad49576eb6d3Grace Kloba                    } else if ("about:debug.dom.file".equals(urlData.mUrl)) {
548638d3f45791a31d0b290e180b93bad49576eb6d3Grace Kloba                        current.getWebView().dumpDomTree(true);
549638d3f45791a31d0b290e180b93bad49576eb6d3Grace Kloba                    } else if ("about:debug.render".equals(urlData.mUrl)) {
550638d3f45791a31d0b290e180b93bad49576eb6d3Grace Kloba                        current.getWebView().dumpRenderTree(false);
551638d3f45791a31d0b290e180b93bad49576eb6d3Grace Kloba                    } else if ("about:debug.render.file".equals(urlData.mUrl)) {
552638d3f45791a31d0b290e180b93bad49576eb6d3Grace Kloba                        current.getWebView().dumpRenderTree(true);
553638d3f45791a31d0b290e180b93bad49576eb6d3Grace Kloba                    } else if ("about:debug.display".equals(urlData.mUrl)) {
554638d3f45791a31d0b290e180b93bad49576eb6d3Grace Kloba                        current.getWebView().dumpDisplayTree();
5559b78e1d1e0bd819ae03df5594d4a56519e5d87c7Mike Reed                    } else if (urlData.mUrl.startsWith("about:debug.drag")) {
5569b78e1d1e0bd819ae03df5594d4a56519e5d87c7Mike Reed                        int index = urlData.mUrl.codePointAt(16) - '0';
5579b78e1d1e0bd819ae03df5594d4a56519e5d87c7Mike Reed                        if (index <= 0 || index > 9) {
5589b78e1d1e0bd819ae03df5594d4a56519e5d87c7Mike Reed                            current.getWebView().setDragTracker(null);
5599b78e1d1e0bd819ae03df5594d4a56519e5d87c7Mike Reed                        } else {
5609b78e1d1e0bd819ae03df5594d4a56519e5d87c7Mike Reed                            current.getWebView().setDragTracker(new MeshTracker(index));
5619b78e1d1e0bd819ae03df5594d4a56519e5d87c7Mike Reed                        }
562638d3f45791a31d0b290e180b93bad49576eb6d3Grace Kloba                    } else {
563638d3f45791a31d0b290e180b93bad49576eb6d3Grace Kloba                        mSettings.toggleDebugSettings();
564638d3f45791a31d0b290e180b93bad49576eb6d3Grace Kloba                    }
5650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    return;
5660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
5671f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                // Get rid of the subwindow if it exists
5681f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                dismissSubWindow(current);
5698588d15a7c0b87049469fd80f9c53eb274cd837bLeon Scroggins                // If the current Tab is being used as an application tab,
5708588d15a7c0b87049469fd80f9c53eb274cd837bLeon Scroggins                // remove the association, since the new Intent means that it is
5718588d15a7c0b87049469fd80f9c53eb274cd837bLeon Scroggins                // no longer associated with that application.
5728588d15a7c0b87049469fd80f9c53eb274cd837bLeon Scroggins                current.setAppId(null);
5739d53da05812f959745810a33bb4e06b273393c42Patrick Scott                loadUrlDataIn(current, urlData);
5740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
5750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
5760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
5770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
578565505b1a2c1d3099496af5910760087602e994aSatish Sampath    private int parseUrlShortcut(String url) {
579565505b1a2c1d3099496af5910760087602e994aSatish Sampath        if (url == null) return SHORTCUT_INVALID;
580565505b1a2c1d3099496af5910760087602e994aSatish Sampath
581565505b1a2c1d3099496af5910760087602e994aSatish Sampath        // FIXME: quick search, need to be customized by setting
582565505b1a2c1d3099496af5910760087602e994aSatish Sampath        if (url.length() > 2 && url.charAt(1) == ' ') {
583565505b1a2c1d3099496af5910760087602e994aSatish Sampath            switch (url.charAt(0)) {
584565505b1a2c1d3099496af5910760087602e994aSatish Sampath            case 'g': return SHORTCUT_GOOGLE_SEARCH;
585565505b1a2c1d3099496af5910760087602e994aSatish Sampath            case 'w': return SHORTCUT_WIKIPEDIA_SEARCH;
586565505b1a2c1d3099496af5910760087602e994aSatish Sampath            case 'd': return SHORTCUT_DICTIONARY_SEARCH;
587565505b1a2c1d3099496af5910760087602e994aSatish Sampath            case 'l': return SHORTCUT_GOOGLE_MOBILE_LOCAL_SEARCH;
588565505b1a2c1d3099496af5910760087602e994aSatish Sampath            }
589565505b1a2c1d3099496af5910760087602e994aSatish Sampath        }
590565505b1a2c1d3099496af5910760087602e994aSatish Sampath        return SHORTCUT_INVALID;
591565505b1a2c1d3099496af5910760087602e994aSatish Sampath    }
592565505b1a2c1d3099496af5910760087602e994aSatish Sampath
593565505b1a2c1d3099496af5910760087602e994aSatish Sampath    /**
594565505b1a2c1d3099496af5910760087602e994aSatish Sampath     * Launches the default web search activity with the query parameters if the given intent's data
595565505b1a2c1d3099496af5910760087602e994aSatish Sampath     * are identified as plain search terms and not URLs/shortcuts.
596565505b1a2c1d3099496af5910760087602e994aSatish Sampath     * @return true if the intent was handled and web search activity was launched, false if not.
597565505b1a2c1d3099496af5910760087602e994aSatish Sampath     */
598565505b1a2c1d3099496af5910760087602e994aSatish Sampath    private boolean handleWebSearchIntent(Intent intent) {
599565505b1a2c1d3099496af5910760087602e994aSatish Sampath        if (intent == null) return false;
600565505b1a2c1d3099496af5910760087602e994aSatish Sampath
601565505b1a2c1d3099496af5910760087602e994aSatish Sampath        String url = null;
602565505b1a2c1d3099496af5910760087602e994aSatish Sampath        final String action = intent.getAction();
603a1cc3fdce19a336c251297c61cd83ac6cf767cd1Leon Scroggins        if (RecognizerResultsIntent.ACTION_VOICE_SEARCH_RESULTS.equals(
604a1cc3fdce19a336c251297c61cd83ac6cf767cd1Leon Scroggins                action)) {
60558d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins            return false;
60658d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        }
607565505b1a2c1d3099496af5910760087602e994aSatish Sampath        if (Intent.ACTION_VIEW.equals(action)) {
6081e70505659dd9bf0f7e03bce787ba880f9b7a8aaGrace Kloba            Uri data = intent.getData();
6091e70505659dd9bf0f7e03bce787ba880f9b7a8aaGrace Kloba            if (data != null) url = data.toString();
610565505b1a2c1d3099496af5910760087602e994aSatish Sampath        } else if (Intent.ACTION_SEARCH.equals(action)
611565505b1a2c1d3099496af5910760087602e994aSatish Sampath                || MediaStore.INTENT_ACTION_MEDIA_SEARCH.equals(action)
612565505b1a2c1d3099496af5910760087602e994aSatish Sampath                || Intent.ACTION_WEB_SEARCH.equals(action)) {
613565505b1a2c1d3099496af5910760087602e994aSatish Sampath            url = intent.getStringExtra(SearchManager.QUERY);
614565505b1a2c1d3099496af5910760087602e994aSatish Sampath        }
6150485170e03e079eb61b9dd52fc2c98da02fa7b2cBjorn Bringert        return handleWebSearchRequest(url, intent.getBundleExtra(SearchManager.APP_DATA),
6160485170e03e079eb61b9dd52fc2c98da02fa7b2cBjorn Bringert                intent.getStringExtra(SearchManager.EXTRA_DATA_KEY));
617565505b1a2c1d3099496af5910760087602e994aSatish Sampath    }
618565505b1a2c1d3099496af5910760087602e994aSatish Sampath
619565505b1a2c1d3099496af5910760087602e994aSatish Sampath    /**
620565505b1a2c1d3099496af5910760087602e994aSatish Sampath     * Launches the default web search activity with the query parameters if the given url string
621565505b1a2c1d3099496af5910760087602e994aSatish Sampath     * was identified as plain search terms and not URL/shortcut.
622565505b1a2c1d3099496af5910760087602e994aSatish Sampath     * @return true if the request was handled and web search activity was launched, false if not.
623565505b1a2c1d3099496af5910760087602e994aSatish Sampath     */
6240485170e03e079eb61b9dd52fc2c98da02fa7b2cBjorn Bringert    private boolean handleWebSearchRequest(String inUrl, Bundle appData, String extraData) {
625565505b1a2c1d3099496af5910760087602e994aSatish Sampath        if (inUrl == null) return false;
626565505b1a2c1d3099496af5910760087602e994aSatish Sampath
627565505b1a2c1d3099496af5910760087602e994aSatish Sampath        // In general, we shouldn't modify URL from Intent.
628565505b1a2c1d3099496af5910760087602e994aSatish Sampath        // But currently, we get the user-typed URL from search box as well.
629565505b1a2c1d3099496af5910760087602e994aSatish Sampath        String url = fixUrl(inUrl).trim();
630565505b1a2c1d3099496af5910760087602e994aSatish Sampath
631565505b1a2c1d3099496af5910760087602e994aSatish Sampath        // URLs and site specific search shortcuts are handled by the regular flow of control, so
632565505b1a2c1d3099496af5910760087602e994aSatish Sampath        // return early.
6335ee906c089567bca705e18561357510d7b55cb5aDan Egnor        if (Patterns.WEB_URL.matcher(url).matches()
634bc5b9f358a2b75bf3a104b9f5cd477ad2f6f740fSatish Sampath                || ACCEPTED_URI_SCHEMA.matcher(url).matches()
635565505b1a2c1d3099496af5910760087602e994aSatish Sampath                || parseUrlShortcut(url) != SHORTCUT_INVALID) {
636565505b1a2c1d3099496af5910760087602e994aSatish Sampath            return false;
637565505b1a2c1d3099496af5910760087602e994aSatish Sampath        }
638565505b1a2c1d3099496af5910760087602e994aSatish Sampath
6398d06e36fe80f516e04ad33ff8b446720e36cabfdLeon Scroggins        final ContentResolver cr = mResolver;
6408d06e36fe80f516e04ad33ff8b446720e36cabfdLeon Scroggins        final String newUrl = url;
641f0f03954b3092296c58dcb040e2dabd1696dd5c4Elliott Slaughter        if (!mTabControl.getCurrentWebView().isPrivateBrowsingEnabled()) {
642f0f03954b3092296c58dcb040e2dabd1696dd5c4Elliott Slaughter            new AsyncTask<Void, Void, Void>() {
643f0f03954b3092296c58dcb040e2dabd1696dd5c4Elliott Slaughter                @Override
644f0f03954b3092296c58dcb040e2dabd1696dd5c4Elliott Slaughter                protected Void doInBackground(Void... unused) {
645f0f03954b3092296c58dcb040e2dabd1696dd5c4Elliott Slaughter                        Browser.updateVisitedHistory(cr, newUrl, false);
646f0f03954b3092296c58dcb040e2dabd1696dd5c4Elliott Slaughter                        Browser.addSearchUrl(cr, newUrl);
647f0f03954b3092296c58dcb040e2dabd1696dd5c4Elliott Slaughter                    return null;
648f0f03954b3092296c58dcb040e2dabd1696dd5c4Elliott Slaughter                }
649f0f03954b3092296c58dcb040e2dabd1696dd5c4Elliott Slaughter            }.execute();
650f0f03954b3092296c58dcb040e2dabd1696dd5c4Elliott Slaughter        }
651565505b1a2c1d3099496af5910760087602e994aSatish Sampath
652565505b1a2c1d3099496af5910760087602e994aSatish Sampath        Intent intent = new Intent(Intent.ACTION_WEB_SEARCH);
653565505b1a2c1d3099496af5910760087602e994aSatish Sampath        intent.addCategory(Intent.CATEGORY_DEFAULT);
654565505b1a2c1d3099496af5910760087602e994aSatish Sampath        intent.putExtra(SearchManager.QUERY, url);
65515e9f2dc92cf1621f95071b3c740f46079aa0f3bSatish Sampath        if (appData != null) {
65615e9f2dc92cf1621f95071b3c740f46079aa0f3bSatish Sampath            intent.putExtra(SearchManager.APP_DATA, appData);
65715e9f2dc92cf1621f95071b3c740f46079aa0f3bSatish Sampath        }
6580485170e03e079eb61b9dd52fc2c98da02fa7b2cBjorn Bringert        if (extraData != null) {
6590485170e03e079eb61b9dd52fc2c98da02fa7b2cBjorn Bringert            intent.putExtra(SearchManager.EXTRA_DATA_KEY, extraData);
6600485170e03e079eb61b9dd52fc2c98da02fa7b2cBjorn Bringert        }
661cc63403643786905262f505ab5266d8e80b9924cGrace Kloba        intent.putExtra(Browser.EXTRA_APPLICATION_ID, getPackageName());
662565505b1a2c1d3099496af5910760087602e994aSatish Sampath        startActivity(intent);
663565505b1a2c1d3099496af5910760087602e994aSatish Sampath
664565505b1a2c1d3099496af5910760087602e994aSatish Sampath        return true;
665565505b1a2c1d3099496af5910760087602e994aSatish Sampath    }
666565505b1a2c1d3099496af5910760087602e994aSatish Sampath
66725ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima    private UrlData getUrlDataFromIntent(Intent intent) {
66858d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        String url = "";
669068e48b469f5abca53ee3da38f933cf2c25c93b8Grace Kloba        Map<String, String> headers = null;
6700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (intent != null) {
6710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            final String action = intent.getAction();
6720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (Intent.ACTION_VIEW.equals(action)) {
6730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                url = smartUrlFilter(intent.getData());
6740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (url != null && url.startsWith("content:")) {
6750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    /* Append mimetype so webview knows how to display */
6760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    String mimeType = intent.resolveType(getContentResolver());
6770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    if (mimeType != null) {
6780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        url += "?" + mimeType;
6790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
6800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
681068e48b469f5abca53ee3da38f933cf2c25c93b8Grace Kloba                if (url != null && url.startsWith("http")) {
68200f54c589fd38431efd42ea2a551a49e64d595d5Grace Kloba                    final Bundle pairs = intent
68300f54c589fd38431efd42ea2a551a49e64d595d5Grace Kloba                            .getBundleExtra(Browser.EXTRA_HEADERS);
6842d508edbf54ea74cd4e89be8b622b1cbd587464aGrace Kloba                    if (pairs != null && !pairs.isEmpty()) {
68500f54c589fd38431efd42ea2a551a49e64d595d5Grace Kloba                        Iterator<String> iter = pairs.keySet().iterator();
686068e48b469f5abca53ee3da38f933cf2c25c93b8Grace Kloba                        headers = new HashMap<String, String>();
68700f54c589fd38431efd42ea2a551a49e64d595d5Grace Kloba                        while (iter.hasNext()) {
68800f54c589fd38431efd42ea2a551a49e64d595d5Grace Kloba                            String key = iter.next();
68900f54c589fd38431efd42ea2a551a49e64d595d5Grace Kloba                            headers.put(key, pairs.getString(key));
690068e48b469f5abca53ee3da38f933cf2c25c93b8Grace Kloba                        }
691068e48b469f5abca53ee3da38f933cf2c25c93b8Grace Kloba                    }
69225ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima                }
6930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } else if (Intent.ACTION_SEARCH.equals(action)
6940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    || MediaStore.INTENT_ACTION_MEDIA_SEARCH.equals(action)
6950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    || Intent.ACTION_WEB_SEARCH.equals(action)) {
6960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                url = intent.getStringExtra(SearchManager.QUERY);
6970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (url != null) {
6980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    mLastEnteredUrl = url;
6990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // In general, we shouldn't modify URL from Intent.
7000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // But currently, we get the user-typed URL from search box as well.
7010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    url = fixUrl(url);
7020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    url = smartUrlFilter(url);
7038d06e36fe80f516e04ad33ff8b446720e36cabfdLeon Scroggins                    final ContentResolver cr = mResolver;
7048d06e36fe80f516e04ad33ff8b446720e36cabfdLeon Scroggins                    final String newUrl = url;
7058d06e36fe80f516e04ad33ff8b446720e36cabfdLeon Scroggins                    new AsyncTask<Void, Void, Void>() {
706e0a3666b5c0dca7352895fa8b9b4fbb2237df721Michael Kolb                        @Override
7078d06e36fe80f516e04ad33ff8b446720e36cabfdLeon Scroggins                        protected Void doInBackground(Void... unused) {
7088d06e36fe80f516e04ad33ff8b446720e36cabfdLeon Scroggins                            Browser.updateVisitedHistory(cr, newUrl, false);
7098d06e36fe80f516e04ad33ff8b446720e36cabfdLeon Scroggins                            return null;
7108d06e36fe80f516e04ad33ff8b446720e36cabfdLeon Scroggins                        }
7118d06e36fe80f516e04ad33ff8b446720e36cabfdLeon Scroggins                    }.execute();
7120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    String searchSource = "&source=android-" + GOOGLE_SEARCH_SOURCE_SUGGEST + "&";
7130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    if (url.contains(searchSource)) {
7140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        String source = null;
7150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        final Bundle appData = intent.getBundleExtra(SearchManager.APP_DATA);
7160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        if (appData != null) {
71710d1cca0c208d1f9db23893a8515685e04cfe224Bjorn Bringert                            source = appData.getString(Search.SOURCE);
7180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }
7190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        if (TextUtils.isEmpty(source)) {
7200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            source = GOOGLE_SEARCH_SOURCE_UNKNOWN;
7210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }
7220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        url = url.replace(searchSource, "&source=android-"+source+"&");
7230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
7240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
7250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
7260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
72758d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        return new UrlData(url, headers, intent);
7280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
72958d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    /* package */ void showVoiceTitleBar(String title) {
73058d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        mTitleBar.setInVoiceMode(true);
73158d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        mTitleBar.setDisplayTitle(title);
732a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb        mFakeTitleBar.setInVoiceMode(true);
733a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb        mFakeTitleBar.setDisplayTitle(title);
73458d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    }
73558d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    /* package */ void revertVoiceTitleBar() {
73658d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        mTitleBar.setInVoiceMode(false);
737003a5ddf3a7ff1b30bfd82cddc8da49cb9fedf15Leon Scroggins        mTitleBar.setDisplayTitle(mUrl);
738a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb        mFakeTitleBar.setInVoiceMode(false);
739a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb        mFakeTitleBar.setDisplayTitle(mUrl);
74058d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    }
7410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /* package */ static String fixUrl(String inUrl) {
742652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark        // FIXME: Converting the url to lower case
743652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark        // duplicates functionality in smartUrlFilter().
744652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark        // However, changing all current callers of fixUrl to
745652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark        // call smartUrlFilter in addition may have unwanted
746652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark        // consequences, and is deferred for now.
747652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark        int colon = inUrl.indexOf(':');
748652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark        boolean allLower = true;
749652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark        for (int index = 0; index < colon; index++) {
750652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark            char ch = inUrl.charAt(index);
751652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark            if (!Character.isLetter(ch)) {
752652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark                break;
753652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark            }
754652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark            allLower &= Character.isLowerCase(ch);
755652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark            if (index == colon - 1 && !allLower) {
756652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark                inUrl = inUrl.substring(0, colon).toLowerCase()
757652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark                        + inUrl.substring(colon);
758652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark            }
759652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark        }
7600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (inUrl.startsWith("http://") || inUrl.startsWith("https://"))
7610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return inUrl;
7620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (inUrl.startsWith("http:") ||
7630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                inUrl.startsWith("https:")) {
7640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (inUrl.startsWith("http:/") || inUrl.startsWith("https:/")) {
7650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                inUrl = inUrl.replaceFirst("/", "//");
7660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } else inUrl = inUrl.replaceFirst(":", "://");
7670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
7680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return inUrl;
7690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
7700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
77122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    @Override
77222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    protected void onResume() {
7730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        super.onResume();
77431a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort        if (LOGV_ENABLED) {
7750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Log.v(LOGTAG, "BrowserActivity.onResume: this=" + this);
7760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
7770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
7780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (!mActivityInPause) {
7790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Log.e(LOGTAG, "BrowserActivity is already resumed.");
7800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
7810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
7820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
7837bfa63b55644fbf2da1fe6a24b3be0267529202cMike Reed        mTabControl.resumeCurrentTab();
7840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mActivityInPause = false;
7857bfa63b55644fbf2da1fe6a24b3be0267529202cMike Reed        resumeWebViewTimers();
7860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
7870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mWakeLock.isHeld()) {
7880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mHandler.removeMessages(RELEASE_WAKELOCK);
7890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mWakeLock.release();
7900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
7910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
7920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        registerReceiver(mNetworkStateIntentReceiver,
7930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                         mNetworkStateChangedFilter);
7940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebView.enablePlatformNotifications();
7950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
7960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
7973bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    /**
7983bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     * Since the actual title bar is embedded in the WebView, and removing it
799fe87bd3a3897e4bad65bb3d284659ae2f4e57570Leon Scroggins     * would change its appearance, use a different TitleBar to show overlayed
800fe87bd3a3897e4bad65bb3d284659ae2f4e57570Leon Scroggins     * at the top of the screen, when the menu is open or the page is loading.
8013bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     */
802a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb    private TitleBarBase mFakeTitleBar;
8033bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins
8043bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    /**
8053bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     * Keeps track of whether the options menu is open.  This is important in
8063bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     * determining whether to show or hide the title bar overlay.
8073bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     */
8083bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    private boolean mOptionsMenuOpen;
8093bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins
8103bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    /**
8113bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     * Only meaningful when mOptionsMenuOpen is true.  This variable keeps track
8123bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     * of whether the configuration has changed.  The first onMenuOpened call
8133bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     * after a configuration change is simply a reopening of the same menu
8143bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     * (i.e. mIconView did not change).
8153bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     */
8163bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    private boolean mConfigChanged;
8173bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins
8183bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    /**
8193bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     * Whether or not the options menu is in its smaller, icon menu form.  When
8203bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     * true, we want the title bar overlay to be up.  When false, we do not.
8213bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     * Only meaningful if mOptionsMenuOpen is true.
8223bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     */
8233bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    private boolean mIconView;
8243bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins
825a81a764063d2f849fba0cbc3039f86e67c2960ddLeon Scroggins    @Override
826a81a764063d2f849fba0cbc3039f86e67c2960ddLeon Scroggins    public boolean onMenuOpened(int featureId, Menu menu) {
8273bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins        if (Window.FEATURE_OPTIONS_PANEL == featureId) {
8283bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins            if (mOptionsMenuOpen) {
8293bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                if (mConfigChanged) {
8303bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                    // We do not need to make any changes to the state of the
8313bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                    // title bar, since the only thing that happened was a
8323bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                    // change in orientation
8333bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                    mConfigChanged = false;
8343bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                } else {
8353bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                    if (mIconView) {
8363bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                        // Switching the menu to expanded view, so hide the
8373bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                        // title bar.
8383bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                        hideFakeTitleBar();
8393bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                        mIconView = false;
8403bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                    } else {
8413bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                        // Switching the menu back to icon view, so show the
8423bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                        // title bar once again.
8433bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                        showFakeTitleBar();
8443bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                        mIconView = true;
8453bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                    }
8463bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                }
8473bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins            } else {
8483bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                // The options menu is closed, so open it, and show the title
8493bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                showFakeTitleBar();
8503bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                mOptionsMenuOpen = true;
8513bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                mConfigChanged = false;
8523bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                mIconView = true;
8533bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins            }
8543bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins        }
855a81a764063d2f849fba0cbc3039f86e67c2960ddLeon Scroggins        return true;
856a81a764063d2f849fba0cbc3039f86e67c2960ddLeon Scroggins    }
857a81a764063d2f849fba0cbc3039f86e67c2960ddLeon Scroggins
858a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb    void showFakeTitleBar() {
859a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb        if (!isFakeTitleBarShowing() && mActiveTabsPage == null && !mActivityInPause) {
860847c25b877f1c912fe54ba7d3890df7ed3798e47Grace Kloba            WebView mainView = mTabControl.getCurrentWebView();
861847c25b877f1c912fe54ba7d3890df7ed3798e47Grace Kloba            // if there is no current WebView, don't show the faked title bar;
86265190702c53f2d3ceb8e3c88d707bd6ff874034cGrace Kloba            if (mainView == null) {
863a04645545690d9f637ccae4d043a5a1b8478a832Cary Clark                return;
864a04645545690d9f637ccae4d043a5a1b8478a832Cary Clark            }
86579e36d97b67bf06b1e0c0edf773882e93a3293e4Leon Scroggins            // Do not need to check for null, since the current tab will have
86679e36d97b67bf06b1e0c0edf773882e93a3293e4Leon Scroggins            // at least a main WebView, or we would have returned above.
8678e4fbf1b26c2cc05a56ba2d4e7d1eda7d1574e91Leon Scroggins III            if (isInCustomActionMode()) {
8688e4fbf1b26c2cc05a56ba2d4e7d1eda7d1574e91Leon Scroggins III                // Do not show the fake title bar, while a custom ActionMode
8698e4fbf1b26c2cc05a56ba2d4e7d1eda7d1574e91Leon Scroggins III                // (i.e. find or select) is showing.
87079e36d97b67bf06b1e0c0edf773882e93a3293e4Leon Scroggins                return;
87179e36d97b67bf06b1e0c0edf773882e93a3293e4Leon Scroggins            }
872a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb            if (mXLargeScreenSize) {
873a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb                mContentView.addView(mFakeTitleBar);
874a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb                mTabBar.onShowTitleBar();
875a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb            } else {
876a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb                WindowManager manager = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
877a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb
878a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb                // Add the title bar to the window manager so it can receive
879a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb                // touches
880a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb                // while the menu is up
881a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb                WindowManager.LayoutParams params =
882a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb                        new WindowManager.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
883a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb                                ViewGroup.LayoutParams.WRAP_CONTENT,
884a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb                                WindowManager.LayoutParams.TYPE_APPLICATION,
885a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb                                WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
886a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb                                PixelFormat.TRANSLUCENT);
887a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb                params.gravity = Gravity.TOP;
888a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb                boolean atTop = mainView.getScrollY() == 0;
889a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb                params.windowAnimations = atTop ? 0 : R.style.TitleBar;
890a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb                manager.addView(mFakeTitleBar, params);
891a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb            }
8923bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins        }
8933bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    }
8943bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins
8953bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    @Override
8963bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    public void onOptionsMenuClosed(Menu menu) {
8973bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins        mOptionsMenuOpen = false;
898a27ff19e24cb1c9fef5624dbc4554548349b5b31Leon Scroggins        if (!mInLoad) {
899a27ff19e24cb1c9fef5624dbc4554548349b5b31Leon Scroggins            hideFakeTitleBar();
900a27ff19e24cb1c9fef5624dbc4554548349b5b31Leon Scroggins        } else if (!mIconView) {
901a27ff19e24cb1c9fef5624dbc4554548349b5b31Leon Scroggins            // The page is currently loading, and we are in expanded mode, so
902a27ff19e24cb1c9fef5624dbc4554548349b5b31Leon Scroggins            // we were not showing the menu.  Show it once again.  It will be
903a27ff19e24cb1c9fef5624dbc4554548349b5b31Leon Scroggins            // removed when the page finishes.
904a27ff19e24cb1c9fef5624dbc4554548349b5b31Leon Scroggins            showFakeTitleBar();
905a27ff19e24cb1c9fef5624dbc4554548349b5b31Leon Scroggins        }
9063bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    }
90722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
908a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb    void stopScrolling() {
909a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb        ((ScrollWebView) mTabControl.getCurrentWebView()).stopScroll();
910a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb    }
911a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb
912a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb    void hideFakeTitleBar() {
913a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb        if (!isFakeTitleBarShowing()) return;
914a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb        if (mXLargeScreenSize) {
915a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb            mContentView.removeView(mFakeTitleBar);
916a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb            mTabBar.onHideTitleBar();
917a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb        } else {
918a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb            WindowManager.LayoutParams params =
919a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb                    (WindowManager.LayoutParams) mFakeTitleBar.getLayoutParams();
920a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb            WebView mainView = mTabControl.getCurrentWebView();
921a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb            // Although we decided whether or not to animate based on the
922a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb            // current
923a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb            // scroll position, the scroll position may have changed since the
924a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb            // fake title bar was displayed. Make sure it has the appropriate
925a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb            // animation/lack thereof before removing.
926a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb            params.windowAnimations =
927a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb                    mainView != null && mainView.getScrollY() == 0 ? 0 : R.style.TitleBar;
928a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb            WindowManager manager = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
929a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb            manager.updateViewLayout(mFakeTitleBar, params);
930a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb            manager.removeView(mFakeTitleBar);
931a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb        }
932a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb    }
933a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb
934a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb    boolean isFakeTitleBarShowing() {
935a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb        return (mFakeTitleBar.getParent() != null);
9363bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    }
9373bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins
9380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
939c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins     * Special method for the fake title bar to call when displaying its context
940c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins     * menu, since it is in its own Window, and its parent does not show a
941c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins     * context menu.
942c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins     */
943c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins    /* package */ void showTitleBarContextMenu() {
94465f4a3ce9e5c4a5227bbcbb995e5e15f1f85d3d7Cary Clark        if (null == mTitleBar.getParent()) {
94565f4a3ce9e5c4a5227bbcbb995e5e15f1f85d3d7Cary Clark            return;
94665f4a3ce9e5c4a5227bbcbb995e5e15f1f85d3d7Cary Clark        }
947c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins        openContextMenu(mTitleBar);
948c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins    }
949c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins
950b2b19f501ee05448ca81bddaaca70e9b2f51cb54Leon Scroggins    @Override
951b2b19f501ee05448ca81bddaaca70e9b2f51cb54Leon Scroggins    public void onContextMenuClosed(Menu menu) {
952b2b19f501ee05448ca81bddaaca70e9b2f51cb54Leon Scroggins        super.onContextMenuClosed(menu);
953b2b19f501ee05448ca81bddaaca70e9b2f51cb54Leon Scroggins        if (mInLoad) {
954b2b19f501ee05448ca81bddaaca70e9b2f51cb54Leon Scroggins            showFakeTitleBar();
955b2b19f501ee05448ca81bddaaca70e9b2f51cb54Leon Scroggins        }
956b2b19f501ee05448ca81bddaaca70e9b2f51cb54Leon Scroggins    }
957b2b19f501ee05448ca81bddaaca70e9b2f51cb54Leon Scroggins
958c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins    /**
9590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *  onSaveInstanceState(Bundle map)
9600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *  onSaveInstanceState is called right before onStop(). The map contains
9610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *  the saved state.
9620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
96322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    @Override
96422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    protected void onSaveInstanceState(Bundle outState) {
96531a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort        if (LOGV_ENABLED) {
9660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Log.v(LOGTAG, "BrowserActivity.onSaveInstanceState: this=" + this);
9670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
9680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // the default implementation requires each view to have an id. As the
9690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // browser handles the state itself and it doesn't use id for the views,
9700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // don't call the default implementation. Otherwise it will trigger the
9710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // warning like this, "couldn't save which view has focus because the
9720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // focused view XXX has no id".
9730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
9740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Save all the tabs
9750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mTabControl.saveState(outState);
9760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
9770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
97822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    @Override
97922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    protected void onPause() {
9800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        super.onPause();
9810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
9820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mActivityInPause) {
9830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Log.e(LOGTAG, "BrowserActivity is already paused.");
9840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
9850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
9860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
9877bfa63b55644fbf2da1fe6a24b3be0267529202cMike Reed        mTabControl.pauseCurrentTab();
9880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mActivityInPause = true;
9897bfa63b55644fbf2da1fe6a24b3be0267529202cMike Reed        if (mTabControl.getCurrentIndex() >= 0 && !pauseWebViewTimers()) {
9900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mWakeLock.acquire();
9910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mHandler.sendMessageDelayed(mHandler
9920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    .obtainMessage(RELEASE_WAKELOCK), WAKELOCK_TIMEOUT);
9930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
9940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
995a2ab6a7dc0f7023c1d7ebb1cbad397c5dc3d6453Leon Scroggins        // FIXME: This removes the active tabs page and resets the menu to
996a2ab6a7dc0f7023c1d7ebb1cbad397c5dc3d6453Leon Scroggins        // MAIN_MENU.  A better solution might be to do this work in onNewIntent
997a2ab6a7dc0f7023c1d7ebb1cbad397c5dc3d6453Leon Scroggins        // but then we would need to save it in onSaveInstanceState and restore
998a2ab6a7dc0f7023c1d7ebb1cbad397c5dc3d6453Leon Scroggins        // it in onCreate/onRestoreInstanceState
999a2ab6a7dc0f7023c1d7ebb1cbad397c5dc3d6453Leon Scroggins        if (mActiveTabsPage != null) {
1000a2ab6a7dc0f7023c1d7ebb1cbad397c5dc3d6453Leon Scroggins            removeActiveTabPage(true);
1001a2ab6a7dc0f7023c1d7ebb1cbad397c5dc3d6453Leon Scroggins        }
1002a2ab6a7dc0f7023c1d7ebb1cbad397c5dc3d6453Leon Scroggins
10030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        cancelStopToast();
10040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
10050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // unregister network state listener
10060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        unregisterReceiver(mNetworkStateIntentReceiver);
10070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebView.disablePlatformNotifications();
10080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
10090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
101022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    @Override
101122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    protected void onDestroy() {
101231a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort        if (LOGV_ENABLED) {
10130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Log.v(LOGTAG, "BrowserActivity.onDestroy: this=" + this);
10140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
10150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        super.onDestroy();
10160923d69a8ca45222cabd82a80eaa88da9f132e9aGrace Kloba
10178d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins        if (mUploadMessage != null) {
10188d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins            mUploadMessage.onReceiveValue(null);
10198d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins            mUploadMessage = null;
10208d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins        }
10218d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins
10220923d69a8ca45222cabd82a80eaa88da9f132e9aGrace Kloba        if (mTabControl == null) return;
10230923d69a8ca45222cabd82a80eaa88da9f132e9aGrace Kloba
10241fc98a322e9df6b0e797c26de6b2cb23d69ad5d3Grace Kloba        // Remove the fake title bar if it is there
10251fc98a322e9df6b0e797c26de6b2cb23d69ad5d3Grace Kloba        hideFakeTitleBar();
10261fc98a322e9df6b0e797c26de6b2cb23d69ad5d3Grace Kloba
10270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Remove the current tab and sub window
102822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        Tab t = mTabControl.getCurrentTab();
1029fb5e77fac7b8b311fe72827183f8988f5ee92a5fPatrick Scott        if (t != null) {
1030fb5e77fac7b8b311fe72827183f8988f5ee92a5fPatrick Scott            dismissSubWindow(t);
1031fb5e77fac7b8b311fe72827183f8988f5ee92a5fPatrick Scott            removeTabFromContentView(t);
1032fb5e77fac7b8b311fe72827183f8988f5ee92a5fPatrick Scott        }
10330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Destroy all the tabs
10340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mTabControl.destroy();
10350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebIconDatabase.getInstance().close();
10360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
1037b4da0ad0351996f639b50f9f29b123a9b5c24fd0Grace Kloba        unregisterReceiver(mPackageInstallationReceiver);
1038a7611811e0d744a7220b7bf80c8f795af5ea53edBjorn Bringert
1039a7611811e0d744a7220b7bf80c8f795af5ea53edBjorn Bringert        // Stop watching the default geolocation permissions
1040a7611811e0d744a7220b7bf80c8f795af5ea53edBjorn Bringert        mSystemAllowGeolocationOrigins.stop();
1041a7611811e0d744a7220b7bf80c8f795af5ea53edBjorn Bringert        mSystemAllowGeolocationOrigins = null;
10420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
10430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
10440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    @Override
10450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public void onConfigurationChanged(Configuration newConfig) {
10463bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins        mConfigChanged = true;
10470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        super.onConfigurationChanged(newConfig);
10480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
10490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mPageInfoDialog != null) {
10500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mPageInfoDialog.dismiss();
10510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            showPageInfo(
10520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mPageInfoView,
1053c7b92f811dfa3572578ddc6714c98a03936d9ce5Leon Scroggins                mPageInfoFromShowSSLCertificateOnError);
10540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
10550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mSSLCertificateDialog != null) {
10560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mSSLCertificateDialog.dismiss();
10570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            showSSLCertificate(
10580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mSSLCertificateView);
10590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
10600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mSSLCertificateOnErrorDialog != null) {
10610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mSSLCertificateOnErrorDialog.dismiss();
10620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            showSSLCertificateOnError(
10630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mSSLCertificateOnErrorView,
10640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mSSLCertificateOnErrorHandler,
10650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mSSLCertificateOnErrorError);
10660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
10670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mHttpAuthenticationDialog != null) {
10680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            String title = ((TextView) mHttpAuthenticationDialog
10690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    .findViewById(com.android.internal.R.id.alertTitle)).getText()
10700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    .toString();
10710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            String name = ((TextView) mHttpAuthenticationDialog
10720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    .findViewById(R.id.username_edit)).getText().toString();
10730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            String password = ((TextView) mHttpAuthenticationDialog
10740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    .findViewById(R.id.password_edit)).getText().toString();
10750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            int focusId = mHttpAuthenticationDialog.getCurrentFocus()
10760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    .getId();
10770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mHttpAuthenticationDialog.dismiss();
10780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            showHttpAuthentication(mHttpAuthHandler, null, null, title,
10790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    name, password, focusId);
10800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
10810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
10820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
108322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    @Override
108422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    public void onLowMemory() {
10850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        super.onLowMemory();
10860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mTabControl.freeMemory();
10870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
10880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
1089ff4d92ca529f8b77db67d0aea5d9988d5e390211Cary Clark    private void resumeWebViewTimers() {
109022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        Tab tab = mTabControl.getCurrentTab();
1091ff4d92ca529f8b77db67d0aea5d9988d5e390211Cary Clark        if (tab == null) return; // monkey can trigger this
109222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        boolean inLoad = tab.inLoad();
109322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if ((!mActivityInPause && !inLoad) || (mActivityInPause && inLoad)) {
10940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            CookieSyncManager.getInstance().startSync();
109522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            WebView w = tab.getWebView();
10960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (w != null) {
10970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                w.resumeTimers();
10980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
10990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
11000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
11010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
11027bfa63b55644fbf2da1fe6a24b3be0267529202cMike Reed    private boolean pauseWebViewTimers() {
110322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        Tab tab = mTabControl.getCurrentTab();
110422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        boolean inLoad = tab.inLoad();
110522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mActivityInPause && !inLoad) {
11060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            CookieSyncManager.getInstance().stopSync();
11070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            WebView w = mTabControl.getCurrentWebView();
11080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (w != null) {
11090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                w.pauseTimers();
11100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
11110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return true;
11120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
11130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return false;
11140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
11150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
11160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
11170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Open the icon database and retain all the icons for visited sites.
11180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void retainIconsOnStartup() {
11190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final WebIconDatabase db = WebIconDatabase.getInstance();
11200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        db.open(getDir("icons", 0).getPath());
11212c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins        Cursor c = null;
11220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        try {
11232c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins            c = Browser.getAllBookmarks(mResolver);
11242c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins            if (c.moveToFirst()) {
11252c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins                int urlIndex = c.getColumnIndex(Browser.BookmarkColumns.URL);
11262c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins                do {
11272c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins                    String url = c.getString(urlIndex);
11282c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins                    db.retainIconForPageUrl(url);
11292c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins                } while (c.moveToNext());
11300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
11310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } catch (IllegalStateException e) {
11320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Log.e(LOGTAG, "retainIconsOnStartup", e);
11332c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins        } finally {
11342c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins            if (c!= null) c.close();
11350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
11360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
11370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
11380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Helper method for getting the top window.
11390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    WebView getTopWindow() {
11400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return mTabControl.getCurrentTopWebView();
11410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
11420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
114322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    TabControl getTabControl() {
114422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return mTabControl;
114522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
114622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
11470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    @Override
11480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public boolean onCreateOptionsMenu(Menu menu) {
11490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        super.onCreateOptionsMenu(menu);
11500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
11510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        MenuInflater inflater = getMenuInflater();
11520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        inflater.inflate(R.menu.browser, menu);
11530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mMenu = menu;
11540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        updateInLoadMenuItems();
11550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return true;
11560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
11570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
11580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
11590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * As the menu can be open when loading state changes
11600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * we must manually update the state of the stop/reload menu
11610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * item
11620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
11630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void updateInLoadMenuItems() {
11640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mMenu == null) {
11650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
11660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
1167e0a3666b5c0dca7352895fa8b9b4fbb2237df721Michael Kolb        MenuItem dest = mMenu.findItem(R.id.stop_reload_menu_id);
11680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        MenuItem src = mInLoad ?
11690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mMenu.findItem(R.id.stop_menu_id):
1170e0a3666b5c0dca7352895fa8b9b4fbb2237df721Michael Kolb                mMenu.findItem(R.id.reload_menu_id);
1171e0a3666b5c0dca7352895fa8b9b4fbb2237df721Michael Kolb        if (src != null) {
1172e0a3666b5c0dca7352895fa8b9b4fbb2237df721Michael Kolb            dest.setIcon(src.getIcon());
1173e0a3666b5c0dca7352895fa8b9b4fbb2237df721Michael Kolb            dest.setTitle(src.getTitle());
1174e0a3666b5c0dca7352895fa8b9b4fbb2237df721Michael Kolb        }
11750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
11760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
11770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    @Override
11780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public boolean onContextItemSelected(MenuItem item) {
11790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // chording is not an issue with context menus, but we use the same
11800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // options selector, so set mCanChord to true so we can access them.
11810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mCanChord = true;
11820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        int id = item.getItemId();
118396afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins        boolean result = true;
11840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        switch (id) {
1185c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins            // For the context menu from the title bar
1186c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins            case R.id.title_bar_copy_page_url:
118796afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                Tab currentTab = mTabControl.getCurrentTab();
118896afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                if (null == currentTab) {
118996afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                    result = false;
119096afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                    break;
1191c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins                }
119296afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                WebView mainView = currentTab.getWebView();
119396afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                if (null == mainView) {
119496afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                    result = false;
119596afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                    break;
1196c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins                }
119796afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                copy(mainView.getUrl());
1198c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins                break;
11990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // -- Browser context menu
12000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.open_context_menu_id:
12010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.bookmark_context_menu_id:
12020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.save_link_context_menu_id:
12030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.share_link_context_menu_id:
12040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.copy_link_context_menu_id:
1205c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins                final WebView webView = getTopWindow();
1206c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins                if (null == webView) {
120796afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                    result = false;
120896afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                    break;
1209c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins                }
1210c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins                final HashMap hrefMap = new HashMap();
1211c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins                hrefMap.put("webview", webView);
1212c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins                final Message msg = mHandler.obtainMessage(
1213c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins                        FOCUS_NODE_HREF, id, 0, hrefMap);
12140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                webView.requestFocusNodeHref(msg);
12150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
12160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
12170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            default:
12180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // For other context menus
121996afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                result = onOptionsItemSelected(item);
12200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
12210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mCanChord = false;
122296afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins        return result;
12230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
12240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
12250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private Bundle createGoogleSearchSourceBundle(String source) {
12260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        Bundle bundle = new Bundle();
122710d1cca0c208d1f9db23893a8515685e04cfe224Bjorn Bringert        bundle.putString(Search.SOURCE, source);
12280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return bundle;
12290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
12300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
12318ad299270a97dfa3f9bcb956096bc152498fb727Leon Scroggins    /* package */ void editUrl() {
123268579393973f745fc65a2781061af9bb8f2d7020Leon Scroggins        if (mOptionsMenuOpen) closeOptionsMenu();
12335bbe98025a2c606a35c91b826760020890daadb1Leon Scroggins        String url = (getTopWindow() == null) ? null : getTopWindow().getUrl();
123483f473462fcd7869031a423c02b957c6e938a2f6Grace Kloba        startSearch(mSettings.getHomePage().equals(url) ? null : url, true,
12358ad299270a97dfa3f9bcb956096bc152498fb727Leon Scroggins                null, false);
12360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
12370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
12388ad299270a97dfa3f9bcb956096bc152498fb727Leon Scroggins    /**
12398ad299270a97dfa3f9bcb956096bc152498fb727Leon Scroggins     * Overriding this to insert a local information bundle
12408ad299270a97dfa3f9bcb956096bc152498fb727Leon Scroggins     */
12410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    @Override
12420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public void startSearch(String initialQuery, boolean selectInitialQuery,
12430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Bundle appSearchData, boolean globalSearch) {
12440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (appSearchData == null) {
12450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            appSearchData = createGoogleSearchSourceBundle(GOOGLE_SEARCH_SOURCE_TYPE);
12460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
12470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        super.startSearch(initialQuery, selectInitialQuery, appSearchData, globalSearch);
12480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
12490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
12501f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins    /**
12511f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins     * Switch tabs.  Called by the TitleBarSet when sliding the title bar
12521f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins     * results in changing tabs.
1253160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins     * @param index Index of the tab to change to, as defined by
1254160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins     *              mTabControl.getTabIndex(Tab t).
1255160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins     * @return boolean True if we successfully switched to a different tab.  If
1256160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins     *                 the indexth tab is null, or if that tab is the same as
1257160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins     *                 the current one, return false.
12581f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins     */
1259160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins    /* package */ boolean switchToTab(int index) {
126022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        Tab tab = mTabControl.getTab(index);
126122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        Tab currentTab = mTabControl.getCurrentTab();
12621f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins        if (tab == null || tab == currentTab) {
1263160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins            return false;
12641f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins        }
12651f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins        if (currentTab != null) {
12661f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins            // currentTab may be null if it was just removed.  In that case,
12671f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins            // we do not need to remove it
12681f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins            removeTabFromContentView(currentTab);
12691f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins        }
12701f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins        mTabControl.setCurrentTab(tab);
12711f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins        attachTabToContentView(tab);
1272eb6eef4c45df2d65c3e70660493a147a2be405e3Grace Kloba        resetTitleIconAndProgress();
1273eb6eef4c45df2d65c3e70660493a147a2be405e3Grace Kloba        updateLockIconToLatest();
1274160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins        return true;
12751f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins    }
12761f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins
127722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /* package */ Tab openTabToHomePage() {
12780a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins        return openTabAndShow(mSettings.getHomePage(), false, null);
12790a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins    }
12800a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins
12811f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins    /* package */ void closeCurrentWindow() {
128222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        final Tab current = mTabControl.getCurrentTab();
1283160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins        if (mTabControl.getTabCount() == 1) {
1284304442375719effd41dbd53ae62de7a8d0cec7d9Leon Scroggins            // This is the last tab.  Open a new one, with the home
1285304442375719effd41dbd53ae62de7a8d0cec7d9Leon Scroggins            // page and close the current one.
128622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            openTabToHomePage();
1287160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins            closeTab(current);
1288160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins            return;
1289160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins        }
129022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        final Tab parent = current.getParentTab();
12911f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins        int indexToShow = -1;
12921f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins        if (parent != null) {
12931f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins            indexToShow = mTabControl.getTabIndex(parent);
12941f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins        } else {
1295160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins            final int currentIndex = mTabControl.getCurrentIndex();
1296160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins            // Try to move to the tab to the right
1297160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins            indexToShow = currentIndex + 1;
1298160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins            if (indexToShow > mTabControl.getTabCount() - 1) {
1299160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins                // Try to move to the tab to the left
1300160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins                indexToShow = currentIndex - 1;
13011f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins            }
13021f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins        }
1303160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins        if (switchToTab(indexToShow)) {
1304160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins            // Close window
1305160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins            closeTab(current);
1306160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins        }
13071f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins    }
13081f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins
13090a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins    private ActiveTabsPage mActiveTabsPage;
13100a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins
13110a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins    /**
13120a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins     * Remove the active tabs page.
13130a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins     * @param needToAttach If true, the active tabs page did not attach a tab
13140a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins     *                     to the content view, so we need to do that here.
13150a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins     */
13160a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins    /* package */ void removeActiveTabPage(boolean needToAttach) {
13170a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins        mContentView.removeView(mActiveTabsPage);
1318d746a94137a87ffcc1fcefdac9a3764c3bc3f5cdLeon Scroggins        mTitleBar.setVisibility(View.VISIBLE);
13190a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins        mActiveTabsPage = null;
13200a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins        mMenuState = R.id.MAIN_MENU;
13210a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins        if (needToAttach) {
13220a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins            attachTabToContentView(mTabControl.getCurrentTab());
13230a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins        }
13240a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins        getTopWindow().requestFocus();
13250a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins    }
13260a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins
13278e4fbf1b26c2cc05a56ba2d4e7d1eda7d1574e91Leon Scroggins III    @Override
13288e4fbf1b26c2cc05a56ba2d4e7d1eda7d1574e91Leon Scroggins III    public ActionMode onStartActionMode(ActionMode.Callback callback) {
13298e4fbf1b26c2cc05a56ba2d4e7d1eda7d1574e91Leon Scroggins III        ActionMode mode = super.onStartActionMode(callback);
13308e4fbf1b26c2cc05a56ba2d4e7d1eda7d1574e91Leon Scroggins III        if (callback instanceof FindActionModeCallback
13318e4fbf1b26c2cc05a56ba2d4e7d1eda7d1574e91Leon Scroggins III                || callback instanceof SelectActionModeCallback) {
13328e4fbf1b26c2cc05a56ba2d4e7d1eda7d1574e91Leon Scroggins III            // For find and select, hide extra title bars.  They will
13338e4fbf1b26c2cc05a56ba2d4e7d1eda7d1574e91Leon Scroggins III            // be replaced in onEndActionMode.
13348e4fbf1b26c2cc05a56ba2d4e7d1eda7d1574e91Leon Scroggins III            Tab tab = mTabControl.getCurrentTab();
13358e4fbf1b26c2cc05a56ba2d4e7d1eda7d1574e91Leon Scroggins III            if (tab.getSubWebView() == null) {
13368e4fbf1b26c2cc05a56ba2d4e7d1eda7d1574e91Leon Scroggins III                // If the find or select is being performed on the main webview,
13378e4fbf1b26c2cc05a56ba2d4e7d1eda7d1574e91Leon Scroggins III                // remove the embedded title bar.
13388e4fbf1b26c2cc05a56ba2d4e7d1eda7d1574e91Leon Scroggins III                WebView mainView = tab.getWebView();
13398e4fbf1b26c2cc05a56ba2d4e7d1eda7d1574e91Leon Scroggins III                if (mainView != null) {
13408e4fbf1b26c2cc05a56ba2d4e7d1eda7d1574e91Leon Scroggins III                    mainView.setEmbeddedTitleBar(null);
13418e4fbf1b26c2cc05a56ba2d4e7d1eda7d1574e91Leon Scroggins III                }
134201cfcdd0b77d672f5c09d98af683c6732c8250d8Cary Clark            }
13438e4fbf1b26c2cc05a56ba2d4e7d1eda7d1574e91Leon Scroggins III            hideFakeTitleBar();
13448e4fbf1b26c2cc05a56ba2d4e7d1eda7d1574e91Leon Scroggins III            mActionMode = mode;
13458e4fbf1b26c2cc05a56ba2d4e7d1eda7d1574e91Leon Scroggins III        } else {
13468e4fbf1b26c2cc05a56ba2d4e7d1eda7d1574e91Leon Scroggins III            // Do not store other ActionModes, since we are unable to determine
13478e4fbf1b26c2cc05a56ba2d4e7d1eda7d1574e91Leon Scroggins III            // when they finish.
13488e4fbf1b26c2cc05a56ba2d4e7d1eda7d1574e91Leon Scroggins III            mActionMode = null;
134901cfcdd0b77d672f5c09d98af683c6732c8250d8Cary Clark        }
13508e4fbf1b26c2cc05a56ba2d4e7d1eda7d1574e91Leon Scroggins III        return mode;
135101cfcdd0b77d672f5c09d98af683c6732c8250d8Cary Clark    }
135201cfcdd0b77d672f5c09d98af683c6732c8250d8Cary Clark
13530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    @Override
13540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public boolean onOptionsItemSelected(MenuItem item) {
1355ed217745066c160f785626e9a15ebe70af5e25e4Michael Kolb        // check the action bar button before mCanChord check, as the prepare call
1356ed217745066c160f785626e9a15ebe70af5e25e4Michael Kolb        // doesn't come for action bar buttons
1357ed217745066c160f785626e9a15ebe70af5e25e4Michael Kolb        if (item.getItemId() == R.id.newtab) {
1358ed217745066c160f785626e9a15ebe70af5e25e4Michael Kolb            bookmarksOrHistoryPicker(false, true);
1359ed217745066c160f785626e9a15ebe70af5e25e4Michael Kolb            return true;
1360ed217745066c160f785626e9a15ebe70af5e25e4Michael Kolb        }
13610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (!mCanChord) {
13620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // The user has already fired a shortcut with this hold down of the
13630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // menu key.
13640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return false;
13650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
13661f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins        if (null == getTopWindow()) {
13670d7ae0ed82e21d472cde8cf92b5657d8ee8ca0d8Leon Scroggins            return false;
13680d7ae0ed82e21d472cde8cf92b5657d8ee8ca0d8Leon Scroggins        }
13696ee9c498b8cf648f1507281ed5a1834ba3390907Grace Kloba        if (mMenuIsDown) {
13706ee9c498b8cf648f1507281ed5a1834ba3390907Grace Kloba            // The shortcut action consumes the MENU. Even if it is still down,
13716ee9c498b8cf648f1507281ed5a1834ba3390907Grace Kloba            // it won't trigger the next shortcut action. In the case of the
13726ee9c498b8cf648f1507281ed5a1834ba3390907Grace Kloba            // shortcut action triggering a new activity, like Bookmarks, we
13736ee9c498b8cf648f1507281ed5a1834ba3390907Grace Kloba            // won't get onKeyUp for MENU. So it is important to reset it here.
13746ee9c498b8cf648f1507281ed5a1834ba3390907Grace Kloba            mMenuIsDown = false;
13756ee9c498b8cf648f1507281ed5a1834ba3390907Grace Kloba        }
13760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        switch (item.getItemId()) {
13770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // -- Main menu
1378a81a764063d2f849fba0cbc3039f86e67c2960ddLeon Scroggins            case R.id.new_tab_menu_id:
13790a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins                openTabToHomePage();
1380a81a764063d2f849fba0cbc3039f86e67c2960ddLeon Scroggins                break;
1381a81a764063d2f849fba0cbc3039f86e67c2960ddLeon Scroggins
138264b80f3efd95d7b5192731e995ccde79c4c6c11fLeon Scroggins            case R.id.goto_menu_id:
13838ad299270a97dfa3f9bcb956096bc152498fb727Leon Scroggins                editUrl();
1384b3a5bedeede968b53363a6c517f92bc2484bb42dLeon Scroggins                break;
1385b3a5bedeede968b53363a6c517f92bc2484bb42dLeon Scroggins
1386b3a5bedeede968b53363a6c517f92bc2484bb42dLeon Scroggins            case R.id.bookmarks_menu_id:
138768792c84eded7f83e2f086d3efe81f9cfc07f9c3Michael Kolb                bookmarksOrHistoryPicker(false, false);
13880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
13890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
13900a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins            case R.id.active_tabs_menu_id:
13910a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins                mActiveTabsPage = new ActiveTabsPage(this, mTabControl);
13920a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins                removeTabFromContentView(mTabControl.getCurrentTab());
1393d746a94137a87ffcc1fcefdac9a3764c3bc3f5cdLeon Scroggins                mTitleBar.setVisibility(View.GONE);
139443de61666cfc98a3acc41c7161a1a8b0bdb2b72bLeon Scroggins                hideFakeTitleBar();
13950a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins                mContentView.addView(mActiveTabsPage, COVER_SCREEN_PARAMS);
13960a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins                mActiveTabsPage.requestFocus();
13970a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins                mMenuState = EMPTY_MENU;
13980a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins                break;
13990a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins
14001f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins            case R.id.add_bookmark_menu_id:
1401571b3762a5eb9e492283e0a1e437edd209fdc0deLeon Scroggins                bookmarkCurrentPage();
14020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
14030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
14040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.stop_reload_menu_id:
14050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (mInLoad) {
14060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    stopLoading();
14070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                } else {
14080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    getTopWindow().reload();
14090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
14100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
14110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
14120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.back_menu_id:
14130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                getTopWindow().goBack();
14140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
14150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
14160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.forward_menu_id:
14170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                getTopWindow().goForward();
14180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
14190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
14200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.close_menu_id:
14210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // Close the subwindow if it exists.
14220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (mTabControl.getCurrentSubWindow() != null) {
14230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    dismissSubWindow(mTabControl.getCurrentTab());
14240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    break;
14250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
14261f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                closeCurrentWindow();
14270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
14280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
14290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.homepage_menu_id:
143022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                Tab current = mTabControl.getCurrentTab();
14310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (current != null) {
14320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    dismissSubWindow(current);
143392472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins                    loadUrl(current.getWebView(), mSettings.getHomePage());
14340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
14350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
14360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
14370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.preferences_menu_id:
14380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                Intent intent = new Intent(this,
14390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        BrowserPreferencesPage.class);
1440d530494de9c182af4aff97ddd46343b32594da51Leon Scroggins                intent.putExtra(BrowserPreferencesPage.CURRENT_PAGE,
1441d530494de9c182af4aff97ddd46343b32594da51Leon Scroggins                        getTopWindow().getUrl());
14420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                startActivityForResult(intent, PREFERENCES_PAGE);
14430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
14440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
14450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.find_menu_id:
14468e4fbf1b26c2cc05a56ba2d4e7d1eda7d1574e91Leon Scroggins III                showFindDialog(null);
14470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
14480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
14490ced08c2332b6e3af5bc31a12568840e9160bb6aElliott Slaughter            case R.id.save_webarchive_menu_id:
14500ced08c2332b6e3af5bc31a12568840e9160bb6aElliott Slaughter                if (LOGD_ENABLED) {
14510ced08c2332b6e3af5bc31a12568840e9160bb6aElliott Slaughter                    Log.d(LOGTAG, "Save as Web Archive");
14520ced08c2332b6e3af5bc31a12568840e9160bb6aElliott Slaughter                }
14530ced08c2332b6e3af5bc31a12568840e9160bb6aElliott Slaughter                String directory = getExternalFilesDir(null).getAbsolutePath() + File.separator;
14540ced08c2332b6e3af5bc31a12568840e9160bb6aElliott Slaughter                getTopWindow().saveWebArchive(directory, true, new ValueCallback<String>() {
14550ced08c2332b6e3af5bc31a12568840e9160bb6aElliott Slaughter                    @Override
14560ced08c2332b6e3af5bc31a12568840e9160bb6aElliott Slaughter                    public void onReceiveValue(String value) {
14570ced08c2332b6e3af5bc31a12568840e9160bb6aElliott Slaughter                        if (value != null) {
14580ced08c2332b6e3af5bc31a12568840e9160bb6aElliott Slaughter                            Toast.makeText(BrowserActivity.this, R.string.webarchive_saved, Toast.LENGTH_SHORT).show();
14590ced08c2332b6e3af5bc31a12568840e9160bb6aElliott Slaughter                        } else {
14600ced08c2332b6e3af5bc31a12568840e9160bb6aElliott Slaughter                            Toast.makeText(BrowserActivity.this, R.string.webarchive_failed, Toast.LENGTH_SHORT).show();
14610ced08c2332b6e3af5bc31a12568840e9160bb6aElliott Slaughter                        }
14620ced08c2332b6e3af5bc31a12568840e9160bb6aElliott Slaughter                    }
14630ced08c2332b6e3af5bc31a12568840e9160bb6aElliott Slaughter                });
14640ced08c2332b6e3af5bc31a12568840e9160bb6aElliott Slaughter                break;
14650ced08c2332b6e3af5bc31a12568840e9160bb6aElliott Slaughter
14660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.page_info_menu_id:
14670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                showPageInfo(mTabControl.getCurrentTab(), false);
14680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
14690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
14700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.classic_history_menu_id:
147168792c84eded7f83e2f086d3efe81f9cfc07f9c3Michael Kolb                bookmarksOrHistoryPicker(true, false);
14720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
14730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
147496afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins            case R.id.title_bar_share_page_url:
14750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.share_page_menu_id:
147696afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                Tab currentTab = mTabControl.getCurrentTab();
147796afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                if (null == currentTab) {
147896afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                    mCanChord = false;
147996afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                    return false;
148096afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                }
148196afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                currentTab.populatePickerData();
148296afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                sharePage(this, currentTab.getTitle(),
148396afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                        currentTab.getUrl(), currentTab.getFavicon(),
148487cc65d95c80c5e3a1c343ad5177a7dc2de874f6Ben Murdoch                        createScreenshot(currentTab.getWebView(), getDesiredThumbnailWidth(this),
148587cc65d95c80c5e3a1c343ad5177a7dc2de874f6Ben Murdoch                                getDesiredThumbnailHeight(this)));
14860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
14870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
14880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.dump_nav_menu_id:
14890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                getTopWindow().debugDump();
14900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
14910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
14927a8b88b0e0f20544df5ee34b798398603261b733Andrei Popescu            case R.id.dump_counters_menu_id:
14937a8b88b0e0f20544df5ee34b798398603261b733Andrei Popescu                getTopWindow().dumpV8Counters();
14947a8b88b0e0f20544df5ee34b798398603261b733Andrei Popescu                break;
14957a8b88b0e0f20544df5ee34b798398603261b733Andrei Popescu
14960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.zoom_in_menu_id:
14970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                getTopWindow().zoomIn();
14980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
14990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
15000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.zoom_out_menu_id:
15010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                getTopWindow().zoomOut();
15020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
15030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
15040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.view_downloads_menu_id:
15050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                viewDownloads(null);
15060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
15070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
15080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.window_one_menu_id:
15090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.window_two_menu_id:
15100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.window_three_menu_id:
15110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.window_four_menu_id:
15120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.window_five_menu_id:
15130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.window_six_menu_id:
15140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.window_seven_menu_id:
15150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.window_eight_menu_id:
15160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                {
15170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    int menuid = item.getItemId();
15180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    for (int id = 0; id < WINDOW_SHORTCUT_ID_ARRAY.length; id++) {
15190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        if (WINDOW_SHORTCUT_ID_ARRAY[id] == menuid) {
152022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            Tab desiredTab = mTabControl.getTab(id);
15210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            if (desiredTab != null &&
15220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    desiredTab != mTabControl.getCurrentTab()) {
15231f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                                switchToTab(id);
15240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            }
15250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            break;
15260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }
15270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
15280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
15290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
15300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
15310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            default:
15320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (!super.onOptionsItemSelected(item)) {
15330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    return false;
15340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
15350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // Otherwise fall through.
15360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
15370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mCanChord = false;
15380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return true;
15390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
15400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
1541571b3762a5eb9e492283e0a1e437edd209fdc0deLeon Scroggins    /* package */ void bookmarkCurrentPage() {
1542571b3762a5eb9e492283e0a1e437edd209fdc0deLeon Scroggins        Intent i = new Intent(BrowserActivity.this,
1543571b3762a5eb9e492283e0a1e437edd209fdc0deLeon Scroggins                AddBookmarkPage.class);
1544571b3762a5eb9e492283e0a1e437edd209fdc0deLeon Scroggins        WebView w = getTopWindow();
1545571b3762a5eb9e492283e0a1e437edd209fdc0deLeon Scroggins        i.putExtra("url", w.getUrl());
1546571b3762a5eb9e492283e0a1e437edd209fdc0deLeon Scroggins        i.putExtra("title", w.getTitle());
1547571b3762a5eb9e492283e0a1e437edd209fdc0deLeon Scroggins        i.putExtra("touch_icon_url", w.getTouchIconUrl());
154887cc65d95c80c5e3a1c343ad5177a7dc2de874f6Ben Murdoch        i.putExtra("thumbnail", createScreenshot(w, getDesiredThumbnailWidth(this),
154987cc65d95c80c5e3a1c343ad5177a7dc2de874f6Ben Murdoch                getDesiredThumbnailHeight(this)));
1550eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch        i.putExtra("url_editable", false);
1551571b3762a5eb9e492283e0a1e437edd209fdc0deLeon Scroggins        startActivity(i);
1552571b3762a5eb9e492283e0a1e437edd209fdc0deLeon Scroggins    }
1553571b3762a5eb9e492283e0a1e437edd209fdc0deLeon Scroggins
15548e4fbf1b26c2cc05a56ba2d4e7d1eda7d1574e91Leon Scroggins III    /*
15558e4fbf1b26c2cc05a56ba2d4e7d1eda7d1574e91Leon Scroggins III     * True if a custom ActionMode (i.e. find or select) is in use.
15568e4fbf1b26c2cc05a56ba2d4e7d1eda7d1574e91Leon Scroggins III     */
15578e4fbf1b26c2cc05a56ba2d4e7d1eda7d1574e91Leon Scroggins III    private boolean isInCustomActionMode() {
15588e4fbf1b26c2cc05a56ba2d4e7d1eda7d1574e91Leon Scroggins III        return mActionMode != null;
155901cfcdd0b77d672f5c09d98af683c6732c8250d8Cary Clark    }
156001cfcdd0b77d672f5c09d98af683c6732c8250d8Cary Clark
15618e4fbf1b26c2cc05a56ba2d4e7d1eda7d1574e91Leon Scroggins III    /*
15628e4fbf1b26c2cc05a56ba2d4e7d1eda7d1574e91Leon Scroggins III     * End the current ActionMode.  Only works for find and select.
15638e4fbf1b26c2cc05a56ba2d4e7d1eda7d1574e91Leon Scroggins III     */
15648e4fbf1b26c2cc05a56ba2d4e7d1eda7d1574e91Leon Scroggins III    void endActionMode() {
15658e4fbf1b26c2cc05a56ba2d4e7d1eda7d1574e91Leon Scroggins III        if (mActionMode != null) {
15668e4fbf1b26c2cc05a56ba2d4e7d1eda7d1574e91Leon Scroggins III            mActionMode.finish();
15678e4fbf1b26c2cc05a56ba2d4e7d1eda7d1574e91Leon Scroggins III        }
156801cfcdd0b77d672f5c09d98af683c6732c8250d8Cary Clark    }
156901cfcdd0b77d672f5c09d98af683c6732c8250d8Cary Clark
1570211ba54a3052f7e68bf8af035ea1ef4e9445130cLeon Scroggins III    /*
15718e4fbf1b26c2cc05a56ba2d4e7d1eda7d1574e91Leon Scroggins III     * Called by find and select when they are finished.  Replace title bars
15728e4fbf1b26c2cc05a56ba2d4e7d1eda7d1574e91Leon Scroggins III     * as necessary.
1573211ba54a3052f7e68bf8af035ea1ef4e9445130cLeon Scroggins III     */
15748e4fbf1b26c2cc05a56ba2d4e7d1eda7d1574e91Leon Scroggins III    public void onEndActionMode() {
15758e4fbf1b26c2cc05a56ba2d4e7d1eda7d1574e91Leon Scroggins III        if (!isInCustomActionMode()) return;
1576a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb        // If the Find was being performed in the main WebView, replace the
1577a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb        // embedded title bar.
1578a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb        Tab currentTab = mTabControl.getCurrentTab();
1579a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb        if (currentTab.getSubWebView() == null) {
1580a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb            WebView mainView = currentTab.getWebView();
1581a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb            if (mainView != null) {
1582a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb                mainView.setEmbeddedTitleBar(mTitleBar);
158379e36d97b67bf06b1e0c0edf773882e93a3293e4Leon Scroggins            }
158479e36d97b67bf06b1e0c0edf773882e93a3293e4Leon Scroggins        }
158579e36d97b67bf06b1e0c0edf773882e93a3293e4Leon Scroggins        if (mInLoad) {
158679e36d97b67bf06b1e0c0edf773882e93a3293e4Leon Scroggins            // The title bar was hidden, because otherwise it would cover up the
1587a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb            // find or select dialog. Now that the dialog has been removed,
158801cfcdd0b77d672f5c09d98af683c6732c8250d8Cary Clark            // show the fake title bar once again.
158979e36d97b67bf06b1e0c0edf773882e93a3293e4Leon Scroggins            showFakeTitleBar();
159079e36d97b67bf06b1e0c0edf773882e93a3293e4Leon Scroggins        }
15918e4fbf1b26c2cc05a56ba2d4e7d1eda7d1574e91Leon Scroggins III        mActionMode = null;
15920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
15930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
15948e4fbf1b26c2cc05a56ba2d4e7d1eda7d1574e91Leon Scroggins III    private FindActionModeCallback mFindCallback;
15958e4fbf1b26c2cc05a56ba2d4e7d1eda7d1574e91Leon Scroggins III    private SelectActionModeCallback mSelectCallback;
159601cfcdd0b77d672f5c09d98af683c6732c8250d8Cary Clark
15978e4fbf1b26c2cc05a56ba2d4e7d1eda7d1574e91Leon Scroggins III    // For select and find, we keep track of the ActionMode so that
15988e4fbf1b26c2cc05a56ba2d4e7d1eda7d1574e91Leon Scroggins III    // finish() can be called as desired.
15998e4fbf1b26c2cc05a56ba2d4e7d1eda7d1574e91Leon Scroggins III    private ActionMode mActionMode;
16008e4fbf1b26c2cc05a56ba2d4e7d1eda7d1574e91Leon Scroggins III
16018e4fbf1b26c2cc05a56ba2d4e7d1eda7d1574e91Leon Scroggins III    /*
16028e4fbf1b26c2cc05a56ba2d4e7d1eda7d1574e91Leon Scroggins III     * Open the find ActionMode.
16038e4fbf1b26c2cc05a56ba2d4e7d1eda7d1574e91Leon Scroggins III     * @param text If non null, will be placed in find to be searched for.
16048e4fbf1b26c2cc05a56ba2d4e7d1eda7d1574e91Leon Scroggins III     */
16058e4fbf1b26c2cc05a56ba2d4e7d1eda7d1574e91Leon Scroggins III    public void showFindDialog(String text) {
16068e4fbf1b26c2cc05a56ba2d4e7d1eda7d1574e91Leon Scroggins III        if (null == mFindCallback) {
16078e4fbf1b26c2cc05a56ba2d4e7d1eda7d1574e91Leon Scroggins III            mFindCallback = new FindActionModeCallback(this);
16088e4fbf1b26c2cc05a56ba2d4e7d1eda7d1574e91Leon Scroggins III        }
16098e4fbf1b26c2cc05a56ba2d4e7d1eda7d1574e91Leon Scroggins III        WebView webView = getTopWindow();
16108e4fbf1b26c2cc05a56ba2d4e7d1eda7d1574e91Leon Scroggins III        webView.setFindIsUp(true);
16118e4fbf1b26c2cc05a56ba2d4e7d1eda7d1574e91Leon Scroggins III        mFindCallback.setWebView(webView);
16128e4fbf1b26c2cc05a56ba2d4e7d1eda7d1574e91Leon Scroggins III        startActionMode(mFindCallback);
16138e4fbf1b26c2cc05a56ba2d4e7d1eda7d1574e91Leon Scroggins III        if (text != null) mFindCallback.setText(text);
161401cfcdd0b77d672f5c09d98af683c6732c8250d8Cary Clark    }
161501cfcdd0b77d672f5c09d98af683c6732c8250d8Cary Clark
16168e4fbf1b26c2cc05a56ba2d4e7d1eda7d1574e91Leon Scroggins III    /*
16178e4fbf1b26c2cc05a56ba2d4e7d1eda7d1574e91Leon Scroggins III     * Show the select ActionMode.
16188e4fbf1b26c2cc05a56ba2d4e7d1eda7d1574e91Leon Scroggins III     */
161901cfcdd0b77d672f5c09d98af683c6732c8250d8Cary Clark    public void showSelectDialog() {
16208e4fbf1b26c2cc05a56ba2d4e7d1eda7d1574e91Leon Scroggins III        if (null == mSelectCallback) {
16218e4fbf1b26c2cc05a56ba2d4e7d1eda7d1574e91Leon Scroggins III            mSelectCallback = new SelectActionModeCallback(this);
162201cfcdd0b77d672f5c09d98af683c6732c8250d8Cary Clark        }
16238e4fbf1b26c2cc05a56ba2d4e7d1eda7d1574e91Leon Scroggins III        WebView webView = getTopWindow();
16248e4fbf1b26c2cc05a56ba2d4e7d1eda7d1574e91Leon Scroggins III        webView.setUpSelect();
16258e4fbf1b26c2cc05a56ba2d4e7d1eda7d1574e91Leon Scroggins III        mSelectCallback.setWebView(webView);
16268e4fbf1b26c2cc05a56ba2d4e7d1eda7d1574e91Leon Scroggins III        startActionMode(mSelectCallback);
162701cfcdd0b77d672f5c09d98af683c6732c8250d8Cary Clark    }
162801cfcdd0b77d672f5c09d98af683c6732c8250d8Cary Clark
162922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    @Override
163022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    public boolean onPrepareOptionsMenu(Menu menu) {
16310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // This happens when the user begins to hold down the menu key, so
16320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // allow them to chord to get a shortcut.
16330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mCanChord = true;
16340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Note: setVisible will decide whether an item is visible; while
16350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // setEnabled() will decide whether an item is enabled, which also means
16360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // whether the matching shortcut key will function.
16370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        super.onPrepareOptionsMenu(menu);
16380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        switch (mMenuState) {
16390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case EMPTY_MENU:
16400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (mCurrentMenuState != mMenuState) {
16410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    menu.setGroupVisible(R.id.MAIN_MENU, false);
16420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    menu.setGroupEnabled(R.id.MAIN_MENU, false);
16430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    menu.setGroupEnabled(R.id.MAIN_SHORTCUT_MENU, false);
16440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
16450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
16460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            default:
16470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (mCurrentMenuState != mMenuState) {
16480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    menu.setGroupVisible(R.id.MAIN_MENU, true);
16490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    menu.setGroupEnabled(R.id.MAIN_MENU, true);
16500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    menu.setGroupEnabled(R.id.MAIN_SHORTCUT_MENU, true);
16510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
16520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                final WebView w = getTopWindow();
16530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                boolean canGoBack = false;
16540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                boolean canGoForward = false;
16550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                boolean isHome = false;
16560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (w != null) {
16570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    canGoBack = w.canGoBack();
16580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    canGoForward = w.canGoForward();
16590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    isHome = mSettings.getHomePage().equals(w.getUrl());
16600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
16610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                final MenuItem back = menu.findItem(R.id.back_menu_id);
16620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                back.setEnabled(canGoBack);
16630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
16640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                final MenuItem home = menu.findItem(R.id.homepage_menu_id);
16650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                home.setEnabled(!isHome);
16660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
1667e0a3666b5c0dca7352895fa8b9b4fbb2237df721Michael Kolb                final MenuItem forward = menu.findItem(R.id.forward_menu_id);
1668e0a3666b5c0dca7352895fa8b9b4fbb2237df721Michael Kolb                forward.setEnabled(canGoForward);
16690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
1670ed217745066c160f785626e9a15ebe70af5e25e4Michael Kolb                if (!mXLargeScreenSize) {
1671ed217745066c160f785626e9a15ebe70af5e25e4Michael Kolb                    final MenuItem newtab = menu.findItem(R.id.new_tab_menu_id);
1672ed217745066c160f785626e9a15ebe70af5e25e4Michael Kolb                    newtab.setEnabled(mTabControl.canCreateNewTab());
1673ed217745066c160f785626e9a15ebe70af5e25e4Michael Kolb                }
1674a81a764063d2f849fba0cbc3039f86e67c2960ddLeon Scroggins
16750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // decide whether to show the share link option
16760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                PackageManager pm = getPackageManager();
16770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                Intent send = new Intent(Intent.ACTION_SEND);
16780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                send.setType("text/plain");
16790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                ResolveInfo ri = pm.resolveActivity(send, PackageManager.MATCH_DEFAULT_ONLY);
16800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.share_page_menu_id).setVisible(ri != null);
16810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
16820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                boolean isNavDump = mSettings.isNavDump();
16830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                final MenuItem nav = menu.findItem(R.id.dump_nav_menu_id);
16840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                nav.setVisible(isNavDump);
16850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                nav.setEnabled(isNavDump);
16867a8b88b0e0f20544df5ee34b798398603261b733Andrei Popescu
16877a8b88b0e0f20544df5ee34b798398603261b733Andrei Popescu                boolean showDebugSettings = mSettings.showDebugSettings();
16887a8b88b0e0f20544df5ee34b798398603261b733Andrei Popescu                final MenuItem counter = menu.findItem(R.id.dump_counters_menu_id);
16897a8b88b0e0f20544df5ee34b798398603261b733Andrei Popescu                counter.setVisible(showDebugSettings);
16907a8b88b0e0f20544df5ee34b798398603261b733Andrei Popescu                counter.setEnabled(showDebugSettings);
16917a8b88b0e0f20544df5ee34b798398603261b733Andrei Popescu
16920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
16930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
16940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mCurrentMenuState = mMenuState;
16950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return true;
16960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
16970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
16980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    @Override
16990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public void onCreateContextMenu(ContextMenu menu, View v,
17000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ContextMenuInfo menuInfo) {
1701571b3762a5eb9e492283e0a1e437edd209fdc0deLeon Scroggins        if (v instanceof TitleBarBase) {
17024e9f89b0a64395133b9160dcb4533d2dc62a424fLeon Scroggins            return;
17034e9f89b0a64395133b9160dcb4533d2dc62a424fLeon Scroggins        }
17040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebView webview = (WebView) v;
17050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebView.HitTestResult result = webview.getHitTestResult();
17060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (result == null) {
17070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
17080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
17090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
17100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        int type = result.getType();
17110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (type == WebView.HitTestResult.UNKNOWN_TYPE) {
17120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Log.w(LOGTAG,
17130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    "We should not show context menu when nothing is touched");
17140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
17150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
17160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (type == WebView.HitTestResult.EDIT_TEXT_TYPE) {
17170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // let TextView handles context menu
17180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
17190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
17200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
17210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Note, http://b/issue?id=1106666 is requesting that
17220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // an inflated menu can be used again. This is not available
17230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // yet, so inflate each time (yuk!)
17240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        MenuInflater inflater = getMenuInflater();
17250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        inflater.inflate(R.menu.browsercontext, menu);
17260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
17270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Show the correct menu group
17289e997c7c92175c8e24cef90e265cc35fd9b8710eLeon Scroggins III        final String extra = result.getExtra();
17290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        menu.setGroupVisible(R.id.PHONE_MENU,
17300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                type == WebView.HitTestResult.PHONE_TYPE);
17310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        menu.setGroupVisible(R.id.EMAIL_MENU,
17320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                type == WebView.HitTestResult.EMAIL_TYPE);
17330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        menu.setGroupVisible(R.id.GEO_MENU,
17340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                type == WebView.HitTestResult.GEO_TYPE);
17350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        menu.setGroupVisible(R.id.IMAGE_MENU,
17360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                type == WebView.HitTestResult.IMAGE_TYPE
17370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                || type == WebView.HitTestResult.SRC_IMAGE_ANCHOR_TYPE);
17380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        menu.setGroupVisible(R.id.ANCHOR_MENU,
17390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                type == WebView.HitTestResult.SRC_ANCHOR_TYPE
17400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                || type == WebView.HitTestResult.SRC_IMAGE_ANCHOR_TYPE);
17410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
17420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Setup custom handling depending on the type
17430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        switch (type) {
17440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case WebView.HitTestResult.PHONE_TYPE:
17450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.setHeaderTitle(Uri.decode(extra));
17460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.dial_context_menu_id).setIntent(
17470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new Intent(Intent.ACTION_VIEW, Uri
17480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                .parse(WebView.SCHEME_TEL + extra)));
17490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                Intent addIntent = new Intent(Intent.ACTION_INSERT_OR_EDIT);
17500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                addIntent.putExtra(Insert.PHONE, Uri.decode(extra));
17515e335a381a0cd66e94117b202c1f34f5cb29c9b8Cary Clark                addIntent.setType(ContactsContract.Contacts.CONTENT_ITEM_TYPE);
17520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.add_contact_context_menu_id).setIntent(
17530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        addIntent);
17540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.copy_phone_context_menu_id).setOnMenuItemClickListener(
17550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new Copy(extra));
17560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
17570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
17580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case WebView.HitTestResult.EMAIL_TYPE:
17590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.setHeaderTitle(extra);
17600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.email_context_menu_id).setIntent(
17610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new Intent(Intent.ACTION_VIEW, Uri
17620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                .parse(WebView.SCHEME_MAILTO + extra)));
17630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.copy_mail_context_menu_id).setOnMenuItemClickListener(
17640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new Copy(extra));
17650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
17660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
17670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case WebView.HitTestResult.GEO_TYPE:
17680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.setHeaderTitle(extra);
17690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.map_context_menu_id).setIntent(
17700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new Intent(Intent.ACTION_VIEW, Uri
17710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                .parse(WebView.SCHEME_GEO
17720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        + URLEncoder.encode(extra))));
17730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.copy_geo_context_menu_id).setOnMenuItemClickListener(
17740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new Copy(extra));
17750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
17760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
17770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case WebView.HitTestResult.SRC_ANCHOR_TYPE:
17780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case WebView.HitTestResult.SRC_IMAGE_ANCHOR_TYPE:
17790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                TextView titleView = (TextView) LayoutInflater.from(this)
17800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        .inflate(android.R.layout.browser_link_context_header,
17810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        null);
17820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                titleView.setText(extra);
17830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.setHeaderView(titleView);
17840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // decide whether to show the open link in new tab option
17859e997c7c92175c8e24cef90e265cc35fd9b8710eLeon Scroggins III                boolean showNewTab = mTabControl.canCreateNewTab();
17869e997c7c92175c8e24cef90e265cc35fd9b8710eLeon Scroggins III                MenuItem newTabItem
17879e997c7c92175c8e24cef90e265cc35fd9b8710eLeon Scroggins III                        = menu.findItem(R.id.open_newtab_context_menu_id);
17889e997c7c92175c8e24cef90e265cc35fd9b8710eLeon Scroggins III                newTabItem.setVisible(showNewTab);
17899e997c7c92175c8e24cef90e265cc35fd9b8710eLeon Scroggins III                if (showNewTab) {
17909e997c7c92175c8e24cef90e265cc35fd9b8710eLeon Scroggins III                    newTabItem.setOnMenuItemClickListener(
17919e997c7c92175c8e24cef90e265cc35fd9b8710eLeon Scroggins III                            new MenuItem.OnMenuItemClickListener() {
17929e997c7c92175c8e24cef90e265cc35fd9b8710eLeon Scroggins III                                public boolean onMenuItemClick(MenuItem item) {
17939e997c7c92175c8e24cef90e265cc35fd9b8710eLeon Scroggins III                                    final Tab parent = mTabControl.getCurrentTab();
179468792c84eded7f83e2f086d3efe81f9cfc07f9c3Michael Kolb                                    final Tab newTab = openTab(extra, false);
17959e997c7c92175c8e24cef90e265cc35fd9b8710eLeon Scroggins III                                    if (newTab != parent) {
17969e997c7c92175c8e24cef90e265cc35fd9b8710eLeon Scroggins III                                        parent.addChildTab(newTab);
17979e997c7c92175c8e24cef90e265cc35fd9b8710eLeon Scroggins III                                    }
17989e997c7c92175c8e24cef90e265cc35fd9b8710eLeon Scroggins III                                    return true;
17999e997c7c92175c8e24cef90e265cc35fd9b8710eLeon Scroggins III                                }
18009e997c7c92175c8e24cef90e265cc35fd9b8710eLeon Scroggins III                            });
18019e997c7c92175c8e24cef90e265cc35fd9b8710eLeon Scroggins III                }
1802de353621650d17a412b6ffe2cbf0366db5f11c40Ben Murdoch                menu.findItem(R.id.bookmark_context_menu_id).setVisible(
1803de353621650d17a412b6ffe2cbf0366db5f11c40Ben Murdoch                        Bookmarks.urlHasAcceptableScheme(extra));
18040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                PackageManager pm = getPackageManager();
18050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                Intent send = new Intent(Intent.ACTION_SEND);
18060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                send.setType("text/plain");
18070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                ResolveInfo ri = pm.resolveActivity(send, PackageManager.MATCH_DEFAULT_ONLY);
18080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.share_link_context_menu_id).setVisible(ri != null);
18090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (type == WebView.HitTestResult.SRC_ANCHOR_TYPE) {
18100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    break;
18110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
18120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // otherwise fall through to handle image part
18130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case WebView.HitTestResult.IMAGE_TYPE:
18140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (type == WebView.HitTestResult.IMAGE_TYPE) {
18150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    menu.setHeaderTitle(extra);
18160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
18170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.view_image_context_menu_id).setIntent(
18180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new Intent(Intent.ACTION_VIEW, Uri.parse(extra)));
18190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.download_context_menu_id).
18200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        setOnMenuItemClickListener(new Download(extra));
18214f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                menu.findItem(R.id.set_wallpaper_context_menu_id).
18224f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                        setOnMenuItemClickListener(new SetAsWallpaper(extra));
18230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
18240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
18250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            default:
18260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                Log.w(LOGTAG, "We should not get here.");
18270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
18280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
1829b2b19f501ee05448ca81bddaaca70e9b2f51cb54Leon Scroggins        hideFakeTitleBar();
18300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
18310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
18320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Attach the given tab to the content view.
1833c928c30a51eee84b40cb7045842c288c1cfafff0Grace Kloba    // this should only be called for the current tab.
183422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private void attachTabToContentView(Tab t) {
18352bc69918d97a767a02132090e58718077381ba1aSteve Block        // Attach the container that contains the main WebView and any other UI
18362bc69918d97a767a02132090e58718077381ba1aSteve Block        // associated with the tab.
1837d0119535d0c490e087be114ae8fd1639bb1945dcPatrick Scott        t.attachTabToContentView(mContentView);
1838bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch
1839bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch        if (mShouldShowErrorConsole) {
184022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            ErrorConsoleView errorConsole = t.getErrorConsole(true);
1841bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch            if (errorConsole.numberOfErrors() == 0) {
1842bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch                errorConsole.showConsole(ErrorConsoleView.SHOW_NONE);
1843bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch            } else {
1844bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch                errorConsole.showConsole(ErrorConsoleView.SHOW_MINIMIZED);
1845bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch            }
1846bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch
1847bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch            mErrorConsoleContainer.addView(errorConsole,
184815b8ec6b226f4d57307716e1f495e10a91f8cbf4Romain Guy                    new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
1849bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch                                                  ViewGroup.LayoutParams.WRAP_CONTENT));
1850bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch        }
1851bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch
1852a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb        WebView view = t.getWebView();
1853a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb        view.setEmbeddedTitleBar(mTitleBar);
185458d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        if (t.isInVoiceSearchMode()) {
185558d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins            showVoiceTitleBar(t.getVoiceDisplayTitle());
185658d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        } else {
185758d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins            revertVoiceTitleBar();
185858d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        }
18590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Request focus on the top window.
18600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        t.getTopWindow().requestFocus();
1861a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb        if (mTabControl.getTabChangeListener() != null) {
1862a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb            mTabControl.getTabChangeListener().onCurrentTab(t);
1863a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb        }
18640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
18650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
18660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Attach a sub window to the main WebView of the given tab.
186722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void attachSubWindow(Tab t) {
1868d0119535d0c490e087be114ae8fd1639bb1945dcPatrick Scott        t.attachSubWindow(mContentView);
1869d0119535d0c490e087be114ae8fd1639bb1945dcPatrick Scott        getTopWindow().requestFocus();
18700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
18710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
18720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Remove the given tab from the content view.
187322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private void removeTabFromContentView(Tab t) {
18742bc69918d97a767a02132090e58718077381ba1aSteve Block        // Remove the container that contains the main WebView.
1875d0119535d0c490e087be114ae8fd1639bb1945dcPatrick Scott        t.removeTabFromContentView(mContentView);
1876bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch
187722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        ErrorConsoleView errorConsole = t.getErrorConsole(false);
187822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (errorConsole != null) {
187922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mErrorConsoleContainer.removeView(errorConsole);
1880bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch        }
1881bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch
1882a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb        WebView view = t.getWebView();
1883a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb        if (view != null) {
1884a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb            view.setEmbeddedTitleBar(null);
1885bb85b9016201d45ea939d7cb7edd0ba6616a111cLeon Scroggins        }
18860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
18870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
18880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Remove the sub window if it exists. Also called by TabControl when the
18890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // user clicks the 'X' to dismiss a sub window.
189022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /* package */ void dismissSubWindow(Tab t) {
1891d0119535d0c490e087be114ae8fd1639bb1945dcPatrick Scott        t.removeSubWindow(mContentView);
189222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // dismiss the subwindow. This will destroy the WebView.
189322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        t.dismissSubWindow();
1894d0119535d0c490e087be114ae8fd1639bb1945dcPatrick Scott        getTopWindow().requestFocus();
18950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
18960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
18971f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins    // A wrapper function of {@link #openTabAndShow(UrlData, boolean, String)}
189825ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima    // that accepts url as string.
189922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private Tab openTabAndShow(String url, boolean closeOnExit, String appId) {
19001f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins        return openTabAndShow(new UrlData(url), closeOnExit, appId);
19010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
19020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
19030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // This method does a ton of stuff. It will attempt to create a new tab
19040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // if we haven't reached MAX_TABS. Otherwise it uses the current tab. If
19051f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins    // url isn't null, it will load the given url.
190622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /* package */Tab openTabAndShow(UrlData urlData, boolean closeOnExit,
190722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            String appId) {
190822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        final Tab currentTab = mTabControl.getCurrentTab();
190922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mTabControl.canCreateNewTab()) {
191022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            final Tab tab = mTabControl.createNewTab(closeOnExit, appId,
1911f0f03954b3092296c58dcb040e2dabd1696dd5c4Elliott Slaughter                    urlData.mUrl, false);
19121f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins            WebView webview = tab.getWebView();
19130a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins            // If the last tab was removed from the active tabs page, currentTab
19140a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins            // will be null.
19150a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins            if (currentTab != null) {
19160a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins                removeTabFromContentView(currentTab);
19170a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins            }
19188bbd69f50abd537bfe7eb314b3a3e20241ac22bdPatrick Scott            // We must set the new tab as the current tab to reflect the old
19198bbd69f50abd537bfe7eb314b3a3e20241ac22bdPatrick Scott            // animation behavior.
19208bbd69f50abd537bfe7eb314b3a3e20241ac22bdPatrick Scott            mTabControl.setCurrentTab(tab);
1921eb6eef4c45df2d65c3e70660493a147a2be405e3Grace Kloba            attachTabToContentView(tab);
1922160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins            if (!urlData.isEmpty()) {
19239d53da05812f959745810a33bb4e06b273393c42Patrick Scott                loadUrlDataIn(tab, urlData);
19240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
19251f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins            return tab;
192664b80f3efd95d7b5192731e995ccde79c4c6c11fLeon Scroggins        } else {
19271f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins            // Get rid of the subwindow if it exists
19281f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins            dismissSubWindow(currentTab);
19291f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins            if (!urlData.isEmpty()) {
19301f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                // Load the given url.
19319d53da05812f959745810a33bb4e06b273393c42Patrick Scott                loadUrlDataIn(currentTab, urlData);
19320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
193358d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins            return currentTab;
19340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
19350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
19360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
193768792c84eded7f83e2f086d3efe81f9cfc07f9c3Michael Kolb    private Tab openTab(String url, boolean forceForeground) {
193868792c84eded7f83e2f086d3efe81f9cfc07f9c3Michael Kolb        if (mSettings.openInBackground() && !forceForeground) {
193922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            Tab t = mTabControl.createNewTab();
19400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (t != null) {
19411f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                WebView view = t.getWebView();
194292472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins                loadUrl(view, url);
19430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
1944c9181841c7ed6b9f7dfc953eab8dc7ba1047022cGrace Kloba            return t;
19450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
19461f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins            return openTabAndShow(url, false, null);
19470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
19480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
19490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
1950f0f03954b3092296c58dcb040e2dabd1696dd5c4Elliott Slaughter    /* package */ Tab openIncognitoTab() {
1951f0f03954b3092296c58dcb040e2dabd1696dd5c4Elliott Slaughter        if (mTabControl.canCreateNewTab()) {
1952f0f03954b3092296c58dcb040e2dabd1696dd5c4Elliott Slaughter            Tab currentTab = mTabControl.getCurrentTab();
1953f0f03954b3092296c58dcb040e2dabd1696dd5c4Elliott Slaughter            Tab tab = mTabControl.createNewTab(false, null, null, true);
1954f0f03954b3092296c58dcb040e2dabd1696dd5c4Elliott Slaughter            if (currentTab != null) {
1955f0f03954b3092296c58dcb040e2dabd1696dd5c4Elliott Slaughter                removeTabFromContentView(currentTab);
1956f0f03954b3092296c58dcb040e2dabd1696dd5c4Elliott Slaughter            }
1957f0f03954b3092296c58dcb040e2dabd1696dd5c4Elliott Slaughter            mTabControl.setCurrentTab(tab);
1958f0f03954b3092296c58dcb040e2dabd1696dd5c4Elliott Slaughter            attachTabToContentView(tab);
1959f0f03954b3092296c58dcb040e2dabd1696dd5c4Elliott Slaughter            return tab;
1960f0f03954b3092296c58dcb040e2dabd1696dd5c4Elliott Slaughter        }
1961f0f03954b3092296c58dcb040e2dabd1696dd5c4Elliott Slaughter        return null;
1962f0f03954b3092296c58dcb040e2dabd1696dd5c4Elliott Slaughter    }
1963f0f03954b3092296c58dcb040e2dabd1696dd5c4Elliott Slaughter
19640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private class Copy implements OnMenuItemClickListener {
19650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        private CharSequence mText;
19660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
19670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public boolean onMenuItemClick(MenuItem item) {
19680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            copy(mText);
19690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return true;
19700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
19710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
19720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public Copy(CharSequence toCopy) {
19730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mText = toCopy;
19740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
19750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
19760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
19770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private class Download implements OnMenuItemClickListener {
19780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        private String mText;
19790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
19800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public boolean onMenuItemClick(MenuItem item) {
19810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            onDownloadStartNoStream(mText, null, null, null, -1);
19820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return true;
19830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
19840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
19850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public Download(String toDownload) {
19860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mText = toDownload;
19870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
19880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
19890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
19904f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch    private class SetAsWallpaper extends Thread implements
19914f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch            OnMenuItemClickListener, DialogInterface.OnCancelListener {
19924f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch        private URL mUrl;
19934f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch        private ProgressDialog mWallpaperProgress;
19944f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch        private boolean mCanceled = false;
19954f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch
19964f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch        public SetAsWallpaper(String url) {
19974f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch            try {
19984f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                mUrl = new URL(url);
19994f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch            } catch (MalformedURLException e) {
20004f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                mUrl = null;
20014f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch            }
20024f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch        }
20034f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch
20044f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch        public void onCancel(DialogInterface dialog) {
20054f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch            mCanceled = true;
20064f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch        }
20074f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch
20084f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch        public boolean onMenuItemClick(MenuItem item) {
20094f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch            if (mUrl != null) {
20104f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                // The user may have tried to set a image with a large file size as their
20114f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                // background so it may take a few moments to perform the operation. Display
20124f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                // a progress spinner while it is working.
20134f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                mWallpaperProgress = new ProgressDialog(BrowserActivity.this);
20144f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                mWallpaperProgress.setIndeterminate(true);
20154f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                mWallpaperProgress.setMessage(getText(R.string.progress_dialog_setting_wallpaper));
20164f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                mWallpaperProgress.setCancelable(true);
20174f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                mWallpaperProgress.setOnCancelListener(this);
20184f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                mWallpaperProgress.show();
20194f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                start();
20204f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch            }
20214f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch            return true;
20224f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch        }
20234f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch
2024e0a3666b5c0dca7352895fa8b9b4fbb2237df721Michael Kolb        @Override
20254f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch        public void run() {
20264f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch            Drawable oldWallpaper = BrowserActivity.this.getWallpaper();
20274f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch            try {
20284f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                // TODO: This will cause the resource to be downloaded again, when we
20294f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                // should in most cases be able to grab it from the cache. To fix this
20304f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                // we should query WebCore to see if we can access a cached version and
20314f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                // instead open an input stream on that. This pattern could also be used
20324f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                // in the download manager where the same problem exists.
20334f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                InputStream inputstream = mUrl.openStream();
20344f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                if (inputstream != null) {
20354f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                    setWallpaper(inputstream);
20364f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                }
20374f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch            } catch (IOException e) {
20384f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                Log.e(LOGTAG, "Unable to set new wallpaper");
20394f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                // Act as though the user canceled the operation so we try to
20404f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                // restore the old wallpaper.
20414f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                mCanceled = true;
20424f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch            }
20434f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch
20444f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch            if (mCanceled) {
20454f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                // Restore the old wallpaper if the user cancelled whilst we were setting
20464f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                // the new wallpaper.
20474f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                int width = oldWallpaper.getIntrinsicWidth();
20484f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                int height = oldWallpaper.getIntrinsicHeight();
20494f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                Bitmap bm = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);
20504f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                Canvas canvas = new Canvas(bm);
20514f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                oldWallpaper.setBounds(0, 0, width, height);
20524f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                oldWallpaper.draw(canvas);
20534f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                try {
20544f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                    setWallpaper(bm);
20554f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                } catch (IOException e) {
20564f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                    Log.e(LOGTAG, "Unable to restore old wallpaper.");
20574f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                }
20584f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                mCanceled = false;
20594f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch            }
20604f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch
20614f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch            if (mWallpaperProgress.isShowing()) {
20624f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                mWallpaperProgress.dismiss();
20634f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch            }
20644f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch        }
20654f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch    }
20664f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch
20670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void copy(CharSequence text) {
206880f32627140aefe828ad539f66fc439d1580bae7Dianne Hackborn        ClipboardManager cm = (ClipboardManager)getSystemService(Context.CLIPBOARD_SERVICE);
206980f32627140aefe828ad539f66fc439d1580bae7Dianne Hackborn        cm.setText(text);
20700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
20710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
20720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
20730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Resets the browser title-view to whatever it must be
20740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * (for example, if we had a loading error)
20750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * When we have a new page, we call resetTitle, when we
20760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * have to reset the titlebar to whatever it used to be
20770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * (for example, if the user chose to stop loading), we
20780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * call resetTitleAndRevertLockIcon.
20790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
20800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /* package */ void resetTitleAndRevertLockIcon() {
208122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mTabControl.getCurrentTab().revertLockIcon();
208222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        updateLockIconToLatest();
20830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        resetTitleIconAndProgress();
20840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
20850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
20860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
20870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Reset the title, favicon, and progress.
20880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
20890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void resetTitleIconAndProgress() {
20900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebView current = mTabControl.getCurrentWebView();
20910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (current == null) {
20920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
20930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
20940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        resetTitleAndIcon(current);
20950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        int progress = current.getProgress();
209622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        current.getWebChromeClient().onProgressChanged(current, progress);
20970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
20980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
20990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Reset the title and the icon based on the given item.
21000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void resetTitleAndIcon(WebView view) {
21010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebHistoryItem item = view.copyBackForwardList().getCurrentItem();
21020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (item != null) {
210368579393973f745fc65a2781061af9bb8f2d7020Leon Scroggins            setUrlTitle(item.getUrl(), item.getTitle());
21040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            setFavicon(item.getFavicon());
21050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
210668579393973f745fc65a2781061af9bb8f2d7020Leon Scroggins            setUrlTitle(null, null);
21070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            setFavicon(null);
21080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
21090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
21100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
21110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
21120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Sets a title composed of the URL and the title string.
21130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param url The URL of the site being loaded.
21140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param title The title of the site being loaded.
21150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
211622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void setUrlTitle(String url, String title) {
21170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mUrl = url;
21180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mTitle = title;
21190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
212058d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        // If we are in voice search mode, the title has already been set.
212158d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        if (mTabControl.getCurrentTab().isInVoiceSearchMode()) return;
212258d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        mTitleBar.setDisplayTitle(url);
2123a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb        mFakeTitleBar.setDisplayTitle(url);
21240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
21250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
21260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
21270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param url The URL to build a title version of the URL from.
21280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @return The title version of the URL or null if fails.
21290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * The title version of the URL can be either the URL hostname,
21300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * or the hostname with an "https://" prefix (for secure URLs),
21310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * or an empty string if, for example, the URL in question is a
21320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * file:// URL with no hostname.
21330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
213432e14a6deccfa75490b3032bb4ddd5ae90f89de8Leon Scroggins    /* package */ static String buildTitleUrl(String url) {
21350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String titleUrl = null;
21360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
21370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (url != null) {
21380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            try {
21390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // parse the url string
21400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                URL urlObj = new URL(url);
21410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (urlObj != null) {
21420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    titleUrl = "";
21430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
21440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    String protocol = urlObj.getProtocol();
21450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    String host = urlObj.getHost();
21460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
21470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    if (host != null && 0 < host.length()) {
21480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        titleUrl = host;
21490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        if (protocol != null) {
21500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            // if a secure site, add an "https://" prefix!
21510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            if (protocol.equalsIgnoreCase("https")) {
21520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                titleUrl = protocol + "://" + host;
21530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            }
21540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }
21550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
21560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
21570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } catch (MalformedURLException e) {}
21580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
21590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
21600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return titleUrl;
21610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
21620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
21630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Set the favicon in the title bar.
216422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void setFavicon(Bitmap icon) {
216568579393973f745fc65a2781061af9bb8f2d7020Leon Scroggins        mTitleBar.setFavicon(icon);
2166a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb        mFakeTitleBar.setFavicon(icon);
21670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
21680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
21690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
21700a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins     * Close the tab, remove its associated title bar, and adjust mTabControl's
21710a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins     * current tab to a valid value.
21721f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins     */
217322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /* package */ void closeTab(Tab t) {
21740a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins        int currentIndex = mTabControl.getCurrentIndex();
21750a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins        int removeIndex = mTabControl.getTabIndex(t);
21761f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins        mTabControl.removeTab(t);
21770a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins        if (currentIndex >= removeIndex && currentIndex != 0) {
21780a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins            currentIndex--;
21790a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins        }
21800a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins        mTabControl.setCurrentTab(mTabControl.getTab(currentIndex));
2181a5bf1deca120315a2643ea5b010f94d853461b15Andrei Popescu        resetTitleIconAndProgress();
2182654899b4b7a280efc01aac4977b74369024e5c94Leon Scroggins        updateLockIconToLatest();
21830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
21840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
2185dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins    /* package */ void goBackOnePageOrQuit() {
218622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        Tab current = mTabControl.getCurrentTab();
21870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (current == null) {
21880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            /*
21890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project             * Instead of finishing the activity, simply push this to the back
21900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project             * of the stack and let ActivityManager to choose the foreground
21910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project             * activity. As BrowserActivity is singleTask, it will be always the
21920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project             * root of the task. So we can use either true or false for
21930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project             * moveTaskToBack().
21940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project             */
21950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            moveTaskToBack(true);
219600d85e74921459b34e70eb93368245b4c0a9bf5fGrace Kloba            return;
21970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
21980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebView w = current.getWebView();
21990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (w.canGoBack()) {
22000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            w.goBack();
22010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
22020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Check to see if we are closing a window that was created by
22030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // another window. If so, we switch back to that window.
220422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            Tab parent = current.getParentTab();
22050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (parent != null) {
22061f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                switchToTab(mTabControl.getTabIndex(parent));
22071f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                // Now we close the other tab
22081f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                closeTab(current);
22090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } else {
22100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (current.closeOnExit()) {
221122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    // force the tab's inLoad() to be false as we are going to
221222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    // either finish the activity or remove the tab. This will
221322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    // ensure pauseWebViewTimers() taking action.
221422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    mTabControl.getCurrentTab().clearInLoad();
22150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    if (mTabControl.getTabCount() == 1) {
22160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        finish();
22170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        return;
22180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
22197bfa63b55644fbf2da1fe6a24b3be0267529202cMike Reed                    // call pauseWebViewTimers() now, we won't be able to call
22207bfa63b55644fbf2da1fe6a24b3be0267529202cMike Reed                    // it in onPause() as the WebView won't be valid.
2221ec1b5ad8d8283b1fbbc5d7fa1cd50ef95b9e594dGrace Kloba                    // Temporarily change mActivityInPause to be true as
2222ec1b5ad8d8283b1fbbc5d7fa1cd50ef95b9e594dGrace Kloba                    // pauseWebViewTimers() will do nothing if mActivityInPause
2223ec1b5ad8d8283b1fbbc5d7fa1cd50ef95b9e594dGrace Kloba                    // is false.
2224918e1d78b2db6ef21c71a07868572d9cda498476Grace Kloba                    boolean savedState = mActivityInPause;
2225918e1d78b2db6ef21c71a07868572d9cda498476Grace Kloba                    if (savedState) {
2226ec1b5ad8d8283b1fbbc5d7fa1cd50ef95b9e594dGrace Kloba                        Log.e(LOGTAG, "BrowserActivity is already paused "
2227ec1b5ad8d8283b1fbbc5d7fa1cd50ef95b9e594dGrace Kloba                                + "while handing goBackOnePageOrQuit.");
2228918e1d78b2db6ef21c71a07868572d9cda498476Grace Kloba                    }
2229918e1d78b2db6ef21c71a07868572d9cda498476Grace Kloba                    mActivityInPause = true;
22307bfa63b55644fbf2da1fe6a24b3be0267529202cMike Reed                    pauseWebViewTimers();
2231918e1d78b2db6ef21c71a07868572d9cda498476Grace Kloba                    mActivityInPause = savedState;
22320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    removeTabFromContentView(current);
22330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    mTabControl.removeTab(current);
22340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
22350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                /*
22360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                 * Instead of finishing the activity, simply push this to the back
22370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                 * of the stack and let ActivityManager to choose the foreground
22380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                 * activity. As BrowserActivity is singleTask, it will be always the
22390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                 * root of the task. So we can use either true or false for
22400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                 * moveTaskToBack().
22410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                 */
22420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                moveTaskToBack(true);
22430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
22440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
22450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
22460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
224722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    boolean isMenuDown() {
224822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return mMenuIsDown;
224922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
225022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
22515942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba    @Override
22525942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba    public boolean onKeyDown(int keyCode, KeyEvent event) {
2253f65b50ddd2f7ed1205002d74082fff1ac2336d5cLeon Scroggins        // Even if MENU is already held down, we need to call to super to open
2254f65b50ddd2f7ed1205002d74082fff1ac2336d5cLeon Scroggins        // the IME on long press.
2255f65b50ddd2f7ed1205002d74082fff1ac2336d5cLeon Scroggins        if (KeyEvent.KEYCODE_MENU == keyCode) {
2256f65b50ddd2f7ed1205002d74082fff1ac2336d5cLeon Scroggins            mMenuIsDown = true;
2257f65b50ddd2f7ed1205002d74082fff1ac2336d5cLeon Scroggins            return super.onKeyDown(keyCode, event);
2258f65b50ddd2f7ed1205002d74082fff1ac2336d5cLeon Scroggins        }
22595942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba        // The default key mode is DEFAULT_KEYS_SEARCH_LOCAL. As the MENU is
22605942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba        // still down, we don't want to trigger the search. Pretend to consume
22615942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba        // the key and do nothing.
22625942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba        if (mMenuIsDown) return true;
22635942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba
22645942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba        switch(keyCode) {
22655942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba            case KeyEvent.KEYCODE_SPACE:
2266da0fe556a00773ce2af25eb6dcc5442bd08c7addGrace Kloba                // WebView/WebTextView handle the keys in the KeyDown. As
2267da0fe556a00773ce2af25eb6dcc5442bd08c7addGrace Kloba                // the Activity's shortcut keys are only handled when WebView
2268da0fe556a00773ce2af25eb6dcc5442bd08c7addGrace Kloba                // doesn't, have to do it in onKeyDown instead of onKeyUp.
2269da0fe556a00773ce2af25eb6dcc5442bd08c7addGrace Kloba                if (event.isShiftPressed()) {
2270da0fe556a00773ce2af25eb6dcc5442bd08c7addGrace Kloba                    getTopWindow().pageUp(false);
2271da0fe556a00773ce2af25eb6dcc5442bd08c7addGrace Kloba                } else {
2272da0fe556a00773ce2af25eb6dcc5442bd08c7addGrace Kloba                    getTopWindow().pageDown(false);
2273da0fe556a00773ce2af25eb6dcc5442bd08c7addGrace Kloba                }
22745942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                return true;
22755942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba            case KeyEvent.KEYCODE_BACK:
22765942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                if (event.getRepeatCount() == 0) {
22775942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                    event.startTracking();
22785942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                    return true;
22795942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                } else if (mCustomView == null && mActiveTabsPage == null
22805942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                        && event.isLongPress()) {
228168792c84eded7f83e2f086d3efe81f9cfc07f9c3Michael Kolb                    bookmarksOrHistoryPicker(true, false);
22825942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                    return true;
22830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
22845942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                break;
22850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
22865942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba        return super.onKeyDown(keyCode, event);
22870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
22880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
22895942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba    @Override
22905942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba    public boolean onKeyUp(int keyCode, KeyEvent event) {
22915942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba        switch(keyCode) {
22925942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba            case KeyEvent.KEYCODE_MENU:
22935942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                mMenuIsDown = false;
22945942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                break;
22955942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba            case KeyEvent.KEYCODE_BACK:
22965942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                if (event.isTracking() && !event.isCanceled()) {
22975942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                    if (mCustomView != null) {
22985942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                        // if a custom view is showing, hide it
229922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        mTabControl.getCurrentWebView().getWebChromeClient()
230022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                .onHideCustomView();
23015942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                    } else if (mActiveTabsPage != null) {
23025942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                        // if tab page is showing, hide it
23035942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                        removeActiveTabPage(true);
23040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    } else {
23055942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                        WebView subwindow = mTabControl.getCurrentSubWindow();
23065942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                        if (subwindow != null) {
23075942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                            if (subwindow.canGoBack()) {
23085942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                                subwindow.goBack();
23095942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                            } else {
23105942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                                dismissSubWindow(mTabControl.getCurrentTab());
23115942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                            }
23125942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                        } else {
23135942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                            goBackOnePageOrQuit();
23145942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                        }
23150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
23165942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                    return true;
23175942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                }
23185942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                break;
23190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
23205942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba        return super.onKeyUp(keyCode, event);
23210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
23220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
232368579393973f745fc65a2781061af9bb8f2d7020Leon Scroggins    /* package */ void stopLoading() {
2324b7cc8b439dc595dc48e1c2183b35d23ad72dfbe5Ben Murdoch        mDidStopLoad = true;
23250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        resetTitleAndRevertLockIcon();
23260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebView w = getTopWindow();
23270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        w.stopLoading();
232822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // FIXME: before refactor, it is using mWebViewClient. So I keep the
232922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // same logic here. But for subwindow case, should we call into the main
233022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // WebView's onPageFinished as we never call its onPageStarted and if
233122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // the page finishes itself, we don't call onPageFinished.
233222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mTabControl.getCurrentWebView().getWebViewClient().onPageFinished(w,
233322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                w.getUrl());
23340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
23350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        cancelStopToast();
23360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mStopToast = Toast
23370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .makeText(this, R.string.stopping, Toast.LENGTH_SHORT);
23380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mStopToast.show();
23390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
23400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
234122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    boolean didUserStopLoading() {
234222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return mDidStopLoad;
234322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
234422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
23450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void cancelStopToast() {
23460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mStopToast != null) {
23470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mStopToast.cancel();
23480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mStopToast = null;
23490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
23500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
23510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
235222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // called by a UI or non-UI thread to post the message
235322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    public void postMessage(int what, int arg1, int arg2, Object obj,
235422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            long delayMillis) {
235522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mHandler.sendMessageDelayed(mHandler.obtainMessage(what, arg1, arg2,
235622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                obj), delayMillis);
235722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
235822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
235922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // called by a UI or non-UI thread to remove the message
236022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void removeMessages(int what, Object object) {
236122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mHandler.removeMessages(what, object);
23620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
23630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
23640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // public message ids
23650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public final static int LOAD_URL                = 1001;
23660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public final static int STOP_LOAD               = 1002;
23670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
23680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Message Ids
23690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private static final int FOCUS_NODE_HREF         = 102;
237092c18a52ca7a79c114028b5ba22c3dfe443bd1a4Grace Kloba    private static final int RELEASE_WAKELOCK        = 107;
23710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
237222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    static final int UPDATE_BOOKMARK_THUMBNAIL       = 108;
23732694e23a55d5ca526fc29534a80a200e2c58698bBen Murdoch
2374eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch    private static final int TOUCH_ICON_DOWNLOADED   = 109;
2375eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch
23760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Private handler for handling javascript and saving passwords
23770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private Handler mHandler = new Handler() {
23780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
2379e0a3666b5c0dca7352895fa8b9b4fbb2237df721Michael Kolb        @Override
23800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public void handleMessage(Message msg) {
23810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            switch (msg.what) {
23820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                case FOCUS_NODE_HREF:
23832694e23a55d5ca526fc29534a80a200e2c58698bBen Murdoch                {
23840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    String url = (String) msg.getData().get("url");
238590d088caeee718f89755ee9c25249ba6da15ab97Ben Murdoch                    String title = (String) msg.getData().get("title");
23860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    if (url == null || url.length() == 0) {
23870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        break;
23880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
23890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    HashMap focusNodeMap = (HashMap) msg.obj;
23900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    WebView view = (WebView) focusNodeMap.get("webview");
23910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // Only apply the action if the top window did not change.
23920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    if (getTopWindow() != view) {
23930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        break;
23940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
23950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    switch (msg.arg1) {
23960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        case R.id.open_context_menu_id:
23970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        case R.id.view_image_context_menu_id:
239892472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins                            loadUrlFromContext(getTopWindow(), url);
23990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            break;
24000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        case R.id.bookmark_context_menu_id:
24010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            Intent intent = new Intent(BrowserActivity.this,
24020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    AddBookmarkPage.class);
24030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            intent.putExtra("url", url);
240490d088caeee718f89755ee9c25249ba6da15ab97Ben Murdoch                            intent.putExtra("title", title);
24050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            startActivity(intent);
24060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            break;
24070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        case R.id.share_link_context_menu_id:
24083e20445506307d2c8d699e1d17fb82a0cedde1d0Leon Scroggins                            sharePage(BrowserActivity.this, title, url, null,
240996afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                                    null);
24100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            break;
24110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        case R.id.copy_link_context_menu_id:
24120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            copy(url);
24130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            break;
24140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        case R.id.save_link_context_menu_id:
24150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        case R.id.download_context_menu_id:
24160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            onDownloadStartNoStream(url, null, null, null, -1);
24170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            break;
24180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
24190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    break;
24202694e23a55d5ca526fc29534a80a200e2c58698bBen Murdoch                }
24210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
24220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                case LOAD_URL:
242392472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins                    loadUrlFromContext(getTopWindow(), (String) msg.obj);
24240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    break;
24250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
24260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                case STOP_LOAD:
24270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    stopLoading();
24280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    break;
24290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
24300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                case RELEASE_WAKELOCK:
24310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    if (mWakeLock.isHeld()) {
24320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        mWakeLock.release();
24335d0e02e646e46b14289168f75c2a8f6ed43cac54Grace Kloba                        // if we reach here, Browser should be still in the
24345d0e02e646e46b14289168f75c2a8f6ed43cac54Grace Kloba                        // background loading after WAKELOCK_TIMEOUT (5-min).
24355d0e02e646e46b14289168f75c2a8f6ed43cac54Grace Kloba                        // To avoid burning the battery, stop loading.
24365d0e02e646e46b14289168f75c2a8f6ed43cac54Grace Kloba                        mTabControl.stopAllLoading();
24370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
24380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    break;
24392694e23a55d5ca526fc29534a80a200e2c58698bBen Murdoch
24402694e23a55d5ca526fc29534a80a200e2c58698bBen Murdoch                case UPDATE_BOOKMARK_THUMBNAIL:
24412694e23a55d5ca526fc29534a80a200e2c58698bBen Murdoch                    WebView view = (WebView) msg.obj;
24422694e23a55d5ca526fc29534a80a200e2c58698bBen Murdoch                    if (view != null) {
24432694e23a55d5ca526fc29534a80a200e2c58698bBen Murdoch                        updateScreenshot(view);
24442694e23a55d5ca526fc29534a80a200e2c58698bBen Murdoch                    }
24452694e23a55d5ca526fc29534a80a200e2c58698bBen Murdoch                    break;
2446eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch
2447eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch                case TOUCH_ICON_DOWNLOADED:
2448eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch                    Bundle b = msg.getData();
2449eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch                    showSaveToHomescreenDialog(b.getString("url"),
2450eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch                        b.getString("title"),
2451eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch                        (Bitmap) b.getParcelable("touchIcon"),
2452eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch                        (Bitmap) b.getParcelable("favicon"));
2453eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch                    break;
24540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
24550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
24560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    };
24570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
245896afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins    /**
245996afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins     * Share a page, providing the title, url, favicon, and a screenshot.  Uses
246096afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins     * an {@link Intent} to launch the Activity chooser.
246196afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins     * @param c Context used to launch a new Activity.
246296afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins     * @param title Title of the page.  Stored in the Intent with
246303e6d39560d7de359782485d4c863d600b34fb51Paul Westbrook     *          {@link Intent#EXTRA_SUBJECT}
246496afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins     * @param url URL of the page.  Stored in the Intent with
246596afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins     *          {@link Intent#EXTRA_TEXT}
246696afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins     * @param favicon Bitmap of the favicon for the page.  Stored in the Intent
246796afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins     *          with {@link Browser#EXTRA_SHARE_FAVICON}
246896afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins     * @param screenshot Bitmap of a screenshot of the page.  Stored in the
246996afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins     *          Intent with {@link Browser#EXTRA_SHARE_SCREENSHOT}
247096afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins     */
247196afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins    public static final void sharePage(Context c, String title, String url,
247296afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins            Bitmap favicon, Bitmap screenshot) {
247396afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins        Intent send = new Intent(Intent.ACTION_SEND);
247496afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins        send.setType("text/plain");
247596afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins        send.putExtra(Intent.EXTRA_TEXT, url);
247603e6d39560d7de359782485d4c863d600b34fb51Paul Westbrook        send.putExtra(Intent.EXTRA_SUBJECT, title);
247796afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins        send.putExtra(Browser.EXTRA_SHARE_FAVICON, favicon);
247896afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins        send.putExtra(Browser.EXTRA_SHARE_SCREENSHOT, screenshot);
247996afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins        try {
248096afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins            c.startActivity(Intent.createChooser(send, c.getString(
248196afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                    R.string.choosertitle_sharevia)));
248296afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins        } catch(android.content.ActivityNotFoundException ex) {
248396afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins            // if no app handles it, do nothing
248496afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins        }
248596afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins    }
248696afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins
248789c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins    private void updateScreenshot(WebView view) {
248889c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins        // If this is a bookmarked site, add a screenshot to the database.
248989c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins        // FIXME: When should we update?  Every time?
249089c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins        // FIXME: Would like to make sure there is actually something to
249189c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins        // draw, but the API for that (WebViewCore.pictureReady()) is not
249289c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins        // currently accessible here.
2493aac7aa6fcfcb519755987ec126be066323f589c8Ben Murdoch
249487cc65d95c80c5e3a1c343ad5177a7dc2de874f6Ben Murdoch        final Bitmap bm = createScreenshot(view, getDesiredThumbnailWidth(this),
249587cc65d95c80c5e3a1c343ad5177a7dc2de874f6Ben Murdoch                getDesiredThumbnailHeight(this));
2496cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott        if (bm == null) {
2497cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott            return;
2498cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott        }
2499cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott
2500cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott        final ContentResolver cr = getContentResolver();
2501cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott        final String url = view.getUrl();
2502cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott        final String originalUrl = view.getOriginalUrl();
2503cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott
2504cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott        new AsyncTask<Void, Void, Void>() {
2505cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott            @Override
2506cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott            protected Void doInBackground(Void... unused) {
2507cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott                Cursor c = null;
2508cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott                try {
25098402962ef58546d3cfd48fbb211b5e36df0f118eJeff Hamilton                    c = Bookmarks.queryBookmarksForUrl(
25108ce956c6076a89aae85856f35b94bad7fc8fa1f1Jeff Hamilton                            cr, originalUrl, url);
2511cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott                    if (c != null) {
2512cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott                        if (c.moveToFirst()) {
2513cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott                            ContentValues values = new ContentValues();
2514cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott                            final ByteArrayOutputStream os
2515cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott                                    = new ByteArrayOutputStream();
2516cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott                            bm.compress(Bitmap.CompressFormat.PNG, 100, os);
25178ce956c6076a89aae85856f35b94bad7fc8fa1f1Jeff Hamilton                            values.put(BrowserContract.Bookmarks.THUMBNAIL,
2518cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott                                    os.toByteArray());
2519cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott                            do {
2520cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott                                cr.update(ContentUris.withAppendedId(
25218ce956c6076a89aae85856f35b94bad7fc8fa1f1Jeff Hamilton                                        BrowserContract.Bookmarks.CONTENT_URI, c.getLong(0)),
2522cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott                                        values, null, null);
2523cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott                            } while (c.moveToNext());
2524cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott                        }
25254580057e772b60433272af5cd691825748892693Leon Scroggins                    }
2526cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott                } catch (IllegalStateException e) {
2527cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott                    // Ignore
2528cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott                } finally {
2529cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott                    if (c != null) c.close();
253089c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins                }
2531cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott                return null;
253289c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins            }
2533cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott        }.execute();
253489c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins    }
253589c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins
253606ec5f2d8735d1ba17b779deb0f8da032e0a62eaLeon Scroggins    /**
2537f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins     * Values for the size of the thumbnail created when taking a screenshot.
2538f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins     * Lazily initialized.  Instead of using these directly, use
2539f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins     * getDesiredThumbnailWidth() or getDesiredThumbnailHeight().
254006ec5f2d8735d1ba17b779deb0f8da032e0a62eaLeon Scroggins     */
2541f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins    private static int THUMBNAIL_WIDTH = 0;
2542f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins    private static int THUMBNAIL_HEIGHT = 0;
2543f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins
2544f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins    /**
2545f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins     * Return the desired width for thumbnail screenshots, which are stored in
2546f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins     * the database, and used on the bookmarks screen.
2547f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins     * @param context Context for finding out the density of the screen.
2548f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins     * @return int desired width for thumbnail screenshot.
2549f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins     */
2550f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins    /* package */ static int getDesiredThumbnailWidth(Context context) {
2551f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins        if (THUMBNAIL_WIDTH == 0) {
2552f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins            float density = context.getResources().getDisplayMetrics().density;
2553f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins            THUMBNAIL_WIDTH = (int) (90 * density);
2554f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins            THUMBNAIL_HEIGHT = (int) (80 * density);
2555f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins        }
2556f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins        return THUMBNAIL_WIDTH;
2557f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins    }
2558f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins
2559f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins    /**
2560f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins     * Return the desired height for thumbnail screenshots, which are stored in
2561f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins     * the database, and used on the bookmarks screen.
2562f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins     * @param context Context for finding out the density of the screen.
2563f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins     * @return int desired height for thumbnail screenshot.
2564f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins     */
2565f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins    /* package */ static int getDesiredThumbnailHeight(Context context) {
2566f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins        // To ensure that they are both initialized.
2567f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins        getDesiredThumbnailWidth(context);
2568f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins        return THUMBNAIL_HEIGHT;
2569f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins    }
257006ec5f2d8735d1ba17b779deb0f8da032e0a62eaLeon Scroggins
257187cc65d95c80c5e3a1c343ad5177a7dc2de874f6Ben Murdoch    private Bitmap createScreenshot(WebView view, int width, int height) {
2572dcc2b6f08dd5677bc6ba761a9ba6f1c655113051Ben Murdoch        Picture thumbnail = view.capturePicture();
25734580057e772b60433272af5cd691825748892693Leon Scroggins        if (thumbnail == null) {
25744580057e772b60433272af5cd691825748892693Leon Scroggins            return null;
25754580057e772b60433272af5cd691825748892693Leon Scroggins        }
257687cc65d95c80c5e3a1c343ad5177a7dc2de874f6Ben Murdoch        Bitmap bm = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);
2577dcc2b6f08dd5677bc6ba761a9ba6f1c655113051Ben Murdoch        Canvas canvas = new Canvas(bm);
2578dcc2b6f08dd5677bc6ba761a9ba6f1c655113051Ben Murdoch        // May need to tweak these values to determine what is the
2579dcc2b6f08dd5677bc6ba761a9ba6f1c655113051Ben Murdoch        // best scale factor
25802694e23a55d5ca526fc29534a80a200e2c58698bBen Murdoch        int thumbnailWidth = thumbnail.getWidth();
2581ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch        int thumbnailHeight = thumbnail.getHeight();
2582ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch        float scaleFactorX = 1.0f;
2583ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch        float scaleFactorY = 1.0f;
25842694e23a55d5ca526fc29534a80a200e2c58698bBen Murdoch        if (thumbnailWidth > 0) {
258587cc65d95c80c5e3a1c343ad5177a7dc2de874f6Ben Murdoch            scaleFactorX = (float) width / (float)thumbnailWidth;
2586ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch        } else {
2587ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch            return null;
258806ec5f2d8735d1ba17b779deb0f8da032e0a62eaLeon Scroggins        }
2589ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch
2590ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch        if (view.getWidth() > view.getHeight() &&
2591ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch                thumbnailHeight < view.getHeight() && thumbnailHeight > 0) {
2592ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch            // If the device is in landscape and the page is shorter
2593ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch            // than the height of the view, stretch the thumbnail to fill the
2594ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch            // space.
259587cc65d95c80c5e3a1c343ad5177a7dc2de874f6Ben Murdoch            scaleFactorY = (float) height / (float)thumbnailHeight;
2596ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch        } else {
2597ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch            // In the portrait case, this looks nice.
2598ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch            scaleFactorY = scaleFactorX;
2599ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch        }
2600ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch
2601ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch        canvas.scale(scaleFactorX, scaleFactorY);
2602ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch
2603dcc2b6f08dd5677bc6ba761a9ba6f1c655113051Ben Murdoch        thumbnail.draw(canvas);
2604dcc2b6f08dd5677bc6ba761a9ba6f1c655113051Ben Murdoch        return bm;
2605dcc2b6f08dd5677bc6ba761a9ba6f1c655113051Ben Murdoch    }
2606dcc2b6f08dd5677bc6ba761a9ba6f1c655113051Ben Murdoch
26070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // -------------------------------------------------------------------------
260822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // Helper function for WebViewClient.
26090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    //-------------------------------------------------------------------------
26100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
26110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Use in overrideUrlLoading
26120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /* package */ final static String SCHEME_WTAI = "wtai://wp/";
26130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /* package */ final static String SCHEME_WTAI_MC = "wtai://wp/mc;";
26140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /* package */ final static String SCHEME_WTAI_SD = "wtai://wp/sd;";
26150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /* package */ final static String SCHEME_WTAI_AP = "wtai://wp/ap;";
26160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
261792472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins    // Keep this initial progress in sync with initialProgressValue (* 100)
261892472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins    // in ProgressTracker.cpp
261992472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins    private final static int INITIAL_PROGRESS = 10;
262092472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins
262122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void onPageStarted(WebView view, String url, Bitmap favicon) {
262222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // when BrowserActivity just starts, onPageStarted may be called before
262322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // onResume as it is triggered from onCreate. Call resumeWebViewTimers
262422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // to start the timer. As we won't switch tabs while an activity is in
262522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // pause state, we can ensure calling resume and pause in pair.
262622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mActivityInPause) resumeWebViewTimers();
262722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
262822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        resetLockIcon(url);
262922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        setUrlTitle(url, null);
263022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        setFavicon(favicon);
26318cf8f682e90f004d4b8028d2f5b74f72c0cf4e19Leon Scroggins        // Show some progress so that the user knows the page is beginning to
26328cf8f682e90f004d4b8028d2f5b74f72c0cf4e19Leon Scroggins        // load
263392472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins        onProgressChanged(view, INITIAL_PROGRESS);
263422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mDidStopLoad = false;
263522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (!mIsNetworkUp) createAndShowNetworkDialog();
26368e4fbf1b26c2cc05a56ba2d4e7d1eda7d1574e91Leon Scroggins III        endActionMode();
263722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mSettings.isTracing()) {
263822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            String host;
263922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            try {
264022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                WebAddress uri = new WebAddress(url);
264122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                host = uri.mHost;
264222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            } catch (android.net.ParseException ex) {
264322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                host = "browser";
264422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
264522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            host = host.replace('.', '_');
264622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            host += ".trace";
264722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mInTrace = true;
264822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            Debug.startMethodTracing(host, 20 * 1024 * 1024);
264915525d48024d325c8a52766d8ca727191251a8d4Patrick Scott        }
265015525d48024d325c8a52766d8ca727191251a8d4Patrick Scott
265122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Performance probe
265222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (false) {
265322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mStart = SystemClock.uptimeMillis();
265422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mProcessStart = Process.getElapsedCpuTime();
265522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            long[] sysCpu = new long[7];
265622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (Process.readProcFile("/proc/stat", SYSTEM_CPU_FORMAT, null,
265722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    sysCpu, null)) {
265822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                mUserStart = sysCpu[0] + sysCpu[1];
265922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                mSystemStart = sysCpu[2];
266022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                mIdleStart = sysCpu[3];
266122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                mIrqStart = sysCpu[4] + sysCpu[5] + sysCpu[6];
266222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
266322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mUiStart = SystemClock.currentThreadTimeMillis();
26640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
26650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
26660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
266722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void onPageFinished(WebView view, String url) {
266822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Reset the title and icon in case we stopped a provisional load.
266922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        resetTitleAndIcon(view);
267022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Update the lock icon image only once we are done loading
267122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        updateLockIconToLatest();
267222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // pause the WebView timer and release the wake lock if it is finished
267322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // while BrowserActivity is in pause state.
267422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mActivityInPause && pauseWebViewTimers()) {
267522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (mWakeLock.isHeld()) {
267622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                mHandler.removeMessages(RELEASE_WAKELOCK);
267722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                mWakeLock.release();
267822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
267922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
268022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
268122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Performance probe
268222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (false) {
268322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            long[] sysCpu = new long[7];
268422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (Process.readProcFile("/proc/stat", SYSTEM_CPU_FORMAT, null,
268522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    sysCpu, null)) {
268622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                String uiInfo = "UI thread used "
268722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        + (SystemClock.currentThreadTimeMillis() - mUiStart)
268822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        + " ms";
268922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                if (LOGD_ENABLED) {
269022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    Log.d(LOGTAG, uiInfo);
269122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                }
269222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                //The string that gets written to the log
269322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                String performanceString = "It took total "
269422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        + (SystemClock.uptimeMillis() - mStart)
269522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        + " ms clock time to load the page."
269622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        + "\nbrowser process used "
269722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        + (Process.getElapsedCpuTime() - mProcessStart)
269822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        + " ms, user processes used "
269922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        + (sysCpu[0] + sysCpu[1] - mUserStart) * 10
270022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        + " ms, kernel used "
270122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        + (sysCpu[2] - mSystemStart) * 10
270222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        + " ms, idle took " + (sysCpu[3] - mIdleStart) * 10
270322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        + " ms and irq took "
270422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        + (sysCpu[4] + sysCpu[5] + sysCpu[6] - mIrqStart)
270522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        * 10 + " ms, " + uiInfo;
270622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                if (LOGD_ENABLED) {
270722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    Log.d(LOGTAG, performanceString + "\nWebpage: " + url);
27080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
270922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                if (url != null) {
271022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    // strip the url to maintain consistency
271122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    String newUrl = new String(url);
271222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    if (newUrl.startsWith("http://www.")) {
271322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        newUrl = newUrl.substring(11);
271422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    } else if (newUrl.startsWith("http://")) {
271522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        newUrl = newUrl.substring(7);
271622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    } else if (newUrl.startsWith("https://www.")) {
271722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        newUrl = newUrl.substring(12);
271822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    } else if (newUrl.startsWith("https://")) {
271922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        newUrl = newUrl.substring(8);
27200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
272131a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort                    if (LOGD_ENABLED) {
272222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        Log.d(LOGTAG, newUrl + " loaded");
27230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
27240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
27250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
272622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         }
27270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
272822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mInTrace) {
272922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mInTrace = false;
273022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            Debug.stopMethodTracing();
27310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
273222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
27330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
2734e7fe26bb1af55ec9e1535dcff8c9611692a7132dGrace Kloba    private void closeEmptyChildTab() {
2735e7fe26bb1af55ec9e1535dcff8c9611692a7132dGrace Kloba        Tab current = mTabControl.getCurrentTab();
2736e7fe26bb1af55ec9e1535dcff8c9611692a7132dGrace Kloba        if (current != null
2737e7fe26bb1af55ec9e1535dcff8c9611692a7132dGrace Kloba                && current.getWebView().copyBackForwardList().getSize() == 0) {
2738e7fe26bb1af55ec9e1535dcff8c9611692a7132dGrace Kloba            Tab parent = current.getParentTab();
2739e7fe26bb1af55ec9e1535dcff8c9611692a7132dGrace Kloba            if (parent != null) {
2740e7fe26bb1af55ec9e1535dcff8c9611692a7132dGrace Kloba                switchToTab(mTabControl.getTabIndex(parent));
2741e7fe26bb1af55ec9e1535dcff8c9611692a7132dGrace Kloba                closeTab(current);
2742e7fe26bb1af55ec9e1535dcff8c9611692a7132dGrace Kloba            }
2743e7fe26bb1af55ec9e1535dcff8c9611692a7132dGrace Kloba        }
2744e7fe26bb1af55ec9e1535dcff8c9611692a7132dGrace Kloba    }
2745e7fe26bb1af55ec9e1535dcff8c9611692a7132dGrace Kloba
274622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    boolean shouldOverrideUrlLoading(WebView view, String url) {
274722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (url.startsWith(SCHEME_WTAI)) {
274822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // wtai://wp/mc;number
274922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // number=string(phone-number)
275022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (url.startsWith(SCHEME_WTAI_MC)) {
275122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                Intent intent = new Intent(Intent.ACTION_VIEW,
275222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        Uri.parse(WebView.SCHEME_TEL +
275322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        url.substring(SCHEME_WTAI_MC.length())));
275422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                startActivity(intent);
2755e7fe26bb1af55ec9e1535dcff8c9611692a7132dGrace Kloba                // before leaving BrowserActivity, close the empty child tab.
2756e7fe26bb1af55ec9e1535dcff8c9611692a7132dGrace Kloba                // If a new tab is created through JavaScript open to load this
2757e7fe26bb1af55ec9e1535dcff8c9611692a7132dGrace Kloba                // url, we would like to close it as we will load this url in a
2758e7fe26bb1af55ec9e1535dcff8c9611692a7132dGrace Kloba                // different Activity.
2759e7fe26bb1af55ec9e1535dcff8c9611692a7132dGrace Kloba                closeEmptyChildTab();
276022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                return true;
27610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
276222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // wtai://wp/sd;dtmf
276322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // dtmf=string(dialstring)
276422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (url.startsWith(SCHEME_WTAI_SD)) {
276522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                // TODO: only send when there is active voice connection
27669918943559193e3e047a1c18442e2cdb0fe22b15Dianne Hackborn                return false;
27679918943559193e3e047a1c18442e2cdb0fe22b15Dianne Hackborn            }
276822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // wtai://wp/ap;number;name
276922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // number=string(phone-number)
277022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // name=string
277122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (url.startsWith(SCHEME_WTAI_AP)) {
277222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                // TODO
27730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                return false;
27740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
27750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
27760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
277722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // The "about:" schemes are internal to the browser; don't want these to
277822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // be dispatched to other apps.
277922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (url.startsWith("about:")) {
278022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            return false;
27810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
27820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
278322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        Intent intent;
278422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // perform generic parsing of the URI to turn it into an Intent.
278522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        try {
278622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            intent = Intent.parseUri(url, Intent.URI_INTENT_SCHEME);
278722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        } catch (URISyntaxException ex) {
278822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            Log.w("Browser", "Bad URI " + url + ": " + ex.getMessage());
278922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            return false;
27900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
27910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
279222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // check whether the intent can be resolved. If not, we will see
279322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // whether we can download it from the Market.
279422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (getPackageManager().resolveActivity(intent, 0) == null) {
279522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            String packagename = intent.getPackage();
279622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (packagename != null) {
279722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                intent = new Intent(Intent.ACTION_VIEW, Uri
279822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        .parse("market://search?q=pname:" + packagename));
279922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                intent.addCategory(Intent.CATEGORY_BROWSABLE);
280022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                startActivity(intent);
2801e7fe26bb1af55ec9e1535dcff8c9611692a7132dGrace Kloba                // before leaving BrowserActivity, close the empty child tab.
2802e7fe26bb1af55ec9e1535dcff8c9611692a7132dGrace Kloba                // If a new tab is created through JavaScript open to load this
2803e7fe26bb1af55ec9e1535dcff8c9611692a7132dGrace Kloba                // url, we would like to close it as we will load this url in a
2804e7fe26bb1af55ec9e1535dcff8c9611692a7132dGrace Kloba                // different Activity.
2805e7fe26bb1af55ec9e1535dcff8c9611692a7132dGrace Kloba                closeEmptyChildTab();
280622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                return true;
28070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } else {
28080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                return false;
28090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
28100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
28110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
281222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // sanitize the Intent, ensuring web pages can not bypass browser
281322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // security (only access to BROWSABLE activities).
281422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        intent.addCategory(Intent.CATEGORY_BROWSABLE);
281522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        intent.setComponent(null);
281622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        try {
281722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (startActivityIfNeeded(intent, -1)) {
2818e7fe26bb1af55ec9e1535dcff8c9611692a7132dGrace Kloba                // before leaving BrowserActivity, close the empty child tab.
2819e7fe26bb1af55ec9e1535dcff8c9611692a7132dGrace Kloba                // If a new tab is created through JavaScript open to load this
2820e7fe26bb1af55ec9e1535dcff8c9611692a7132dGrace Kloba                // url, we would like to close it as we will load this url in a
2821e7fe26bb1af55ec9e1535dcff8c9611692a7132dGrace Kloba                // different Activity.
2822e7fe26bb1af55ec9e1535dcff8c9611692a7132dGrace Kloba                closeEmptyChildTab();
28230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                return true;
28240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
282522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        } catch (ActivityNotFoundException ex) {
282622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // ignore the error. If no application can handle the URL,
282722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // eg about:blank, assume the browser can handle it.
282822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
28290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
283022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mMenuIsDown) {
283168792c84eded7f83e2f086d3efe81f9cfc07f9c3Michael Kolb            openTab(url, false);
283222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            closeOptionsMenu();
28330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return true;
28340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
283522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return false;
283622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
28370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
283822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // -------------------------------------------------------------------------
283922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // Helper function for WebChromeClient
284022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // -------------------------------------------------------------------------
28410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
284222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void onProgressChanged(WebView view, int newProgress) {
2843a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb
2844a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb        // On the phone, the fake title bar will always cover up the
2845a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb        // regular title bar (or the regular one is offscreen), so only the
2846a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb        // fake title bar needs to change its progress
2847a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb        mFakeTitleBar.setProgress(newProgress);
284822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
284922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (newProgress == 100) {
285022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // onProgressChanged() may continue to be called after the main
285122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // frame has finished loading, as any remaining sub frames continue
285222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // to load. We'll only get called once though with newProgress as
285322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // 100 when everything is loaded. (onPageFinished is called once
285422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // when the main frame completes loading regardless of the state of
285522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // any sub frames so calls to onProgressChanges may continue after
285622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // onPageFinished has executed)
285722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (mInLoad) {
285822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                mInLoad = false;
2859a27ff19e24cb1c9fef5624dbc4554548349b5b31Leon Scroggins                updateInLoadMenuItems();
286022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                // If the options menu is open, leave the title bar
286122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                if (!mOptionsMenuOpen || !mIconView) {
286222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    hideFakeTitleBar();
28630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
28640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
2865aa37e7fdb52d0180b8eea25d53950c5c0791f968Leon Scroggins        } else {
2866aa37e7fdb52d0180b8eea25d53950c5c0791f968Leon Scroggins            if (!mInLoad) {
2867aa37e7fdb52d0180b8eea25d53950c5c0791f968Leon Scroggins                // onPageFinished may have already been called but a subframe is
2868aa37e7fdb52d0180b8eea25d53950c5c0791f968Leon Scroggins                // still loading and updating the progress. Reset mInLoad and
2869aa37e7fdb52d0180b8eea25d53950c5c0791f968Leon Scroggins                // update the menu items.
2870aa37e7fdb52d0180b8eea25d53950c5c0791f968Leon Scroggins                mInLoad = true;
2871aa37e7fdb52d0180b8eea25d53950c5c0791f968Leon Scroggins                updateInLoadMenuItems();
2872aa37e7fdb52d0180b8eea25d53950c5c0791f968Leon Scroggins            }
2873aa37e7fdb52d0180b8eea25d53950c5c0791f968Leon Scroggins            // When the page first begins to load, the Activity may still be
2874aa37e7fdb52d0180b8eea25d53950c5c0791f968Leon Scroggins            // paused, in which case showFakeTitleBar will do nothing.  Call
2875aa37e7fdb52d0180b8eea25d53950c5c0791f968Leon Scroggins            // again as the page continues to load so that it will be shown.
2876aa37e7fdb52d0180b8eea25d53950c5c0791f968Leon Scroggins            // (Calling it will the fake title bar is already showing will also
2877aa37e7fdb52d0180b8eea25d53950c5c0791f968Leon Scroggins            // do nothing.
287822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (!mOptionsMenuOpen || mIconView) {
287922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                // This page has begun to load, so show the title bar
288022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                showFakeTitleBar();
28813918d4443ff38ef1870e02aa51a8b29f8352bb1aPatrick Scott            }
28820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
288322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
2884092dd5d22d7f2ee0efcc68bd6e5a3afd1ea98953Ben Murdoch
288522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void onShowCustomView(View view, WebChromeClient.CustomViewCallback callback) {
28868ff57db0a8dc8eb659fbcdcd4a856208609e6070Derek Sollenberger        // if a view already exists then immediately terminate the new one
28878ff57db0a8dc8eb659fbcdcd4a856208609e6070Derek Sollenberger        if (mCustomView != null) {
28888ff57db0a8dc8eb659fbcdcd4a856208609e6070Derek Sollenberger            callback.onCustomViewHidden();
288922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            return;
28908ff57db0a8dc8eb659fbcdcd4a856208609e6070Derek Sollenberger        }
28912bc69918d97a767a02132090e58718077381ba1aSteve Block
289222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Add the custom view to its container.
289322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mCustomViewContainer.addView(view, COVER_SCREEN_GRAVITY_CENTER);
289422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mCustomView = view;
289522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mCustomViewCallback = callback;
289622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Save the menu state and set it to empty while the custom
289722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // view is showing.
289822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mOldMenuState = mMenuState;
289922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mMenuState = EMPTY_MENU;
290022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Hide the content view.
290122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mContentView.setVisibility(View.GONE);
290222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Finally show the custom view container.
2903163ab74e2f85b53a1a374c49677073fb64d35f28Andrei Popescu        setStatusBarVisibility(false);
290422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mCustomViewContainer.setVisibility(View.VISIBLE);
290522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mCustomViewContainer.bringToFront();
290622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
290722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
290822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void onHideCustomView() {
290922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mCustomView == null)
291022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            return;
29112bc69918d97a767a02132090e58718077381ba1aSteve Block
291222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Hide the custom view.
291322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mCustomView.setVisibility(View.GONE);
291422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Remove the custom view from its container.
291522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mCustomViewContainer.removeView(mCustomView);
291622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mCustomView = null;
291722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Reset the old menu state.
291822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mMenuState = mOldMenuState;
291922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mOldMenuState = EMPTY_MENU;
292022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mCustomViewContainer.setVisibility(View.GONE);
292122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mCustomViewCallback.onCustomViewHidden();
292222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Show the content view.
2923163ab74e2f85b53a1a374c49677073fb64d35f28Andrei Popescu        setStatusBarVisibility(true);
292422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mContentView.setVisibility(View.VISIBLE);
292522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
2926540035dfd1347c78eeec10ec0847e18fcc50ef36Andrei Popescu
292722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    Bitmap getDefaultVideoPoster() {
292822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mDefaultVideoPoster == null) {
292922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mDefaultVideoPoster = BitmapFactory.decodeResource(
293022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    getResources(), R.drawable.default_video_poster);
2931540035dfd1347c78eeec10ec0847e18fcc50ef36Andrei Popescu        }
293222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return mDefaultVideoPoster;
293322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
2934540035dfd1347c78eeec10ec0847e18fcc50ef36Andrei Popescu
293522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    View getVideoLoadingProgressView() {
293622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mVideoProgressView == null) {
293722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            LayoutInflater inflater = LayoutInflater.from(BrowserActivity.this);
293822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mVideoProgressView = inflater.inflate(
293922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    R.layout.video_loading_progress, null);
2940540035dfd1347c78eeec10ec0847e18fcc50ef36Andrei Popescu        }
294122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return mVideoProgressView;
294222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
29430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
29448d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins    /*
29458d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins     * The Object used to inform the WebView of the file to upload.
29468d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins     */
29478d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins    private ValueCallback<Uri> mUploadMessage;
294862b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch    private String mCameraFilePath;
294962b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch
295062b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch    void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType) {
295162b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch
295262b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch        final String imageMimeType = "image/*";
29536af492aeddda96c749142885e3b49455aa336309Ben Murdoch        final String videoMimeType = "video/*";
2954039bd47edd231965abb2c8e9b2dd32308cddb74bBen Murdoch        final String audioMimeType = "audio/*";
2955b50d7403816f316fdcaf5b5a318383e64f1a8775Ben Murdoch        final String mediaSourceKey = "capture";
29566af492aeddda96c749142885e3b49455aa336309Ben Murdoch        final String mediaSourceValueCamera = "camera";
2957b50d7403816f316fdcaf5b5a318383e64f1a8775Ben Murdoch        final String mediaSourceValueFileSystem = "filesystem";
29586af492aeddda96c749142885e3b49455aa336309Ben Murdoch        final String mediaSourceValueCamcorder = "camcorder";
2959039bd47edd231965abb2c8e9b2dd32308cddb74bBen Murdoch        final String mediaSourceValueMicrophone = "microphone";
296062b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch
2961039bd47edd231965abb2c8e9b2dd32308cddb74bBen Murdoch        // media source can be 'filesystem' or 'camera' or 'camcorder' or 'microphone'.
29626af492aeddda96c749142885e3b49455aa336309Ben Murdoch        String mediaSource = "";
296362b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch
29646af492aeddda96c749142885e3b49455aa336309Ben Murdoch        // We add the camera intent if there was no accept type (or '*/*' or 'image/*').
296562b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch        boolean addCameraIntent = true;
29666af492aeddda96c749142885e3b49455aa336309Ben Murdoch        // We add the camcorder intent if there was no accept type (or '*/*' or 'video/*').
29676af492aeddda96c749142885e3b49455aa336309Ben Murdoch        boolean addCamcorderIntent = true;
29686af492aeddda96c749142885e3b49455aa336309Ben Murdoch
29696af492aeddda96c749142885e3b49455aa336309Ben Murdoch        if (mUploadMessage != null) {
29706af492aeddda96c749142885e3b49455aa336309Ben Murdoch            // Already a file picker operation in progress.
29716af492aeddda96c749142885e3b49455aa336309Ben Murdoch            return;
29726af492aeddda96c749142885e3b49455aa336309Ben Murdoch        }
29738d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins
297422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mUploadMessage = uploadMsg;
297562b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch
297662b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch        // Parse the accept type.
297762b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch        String params[] = acceptType.split(";");
297862b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch        String mimeType = params[0];
297962b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch
298062b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch        for (String p : params) {
298162b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch            String[] keyValue = p.split("=");
298262b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch            if (keyValue.length == 2) {
298362b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch                // Process key=value parameters.
29846af492aeddda96c749142885e3b49455aa336309Ben Murdoch                if (mediaSourceKey.equals(keyValue[0])) {
29856af492aeddda96c749142885e3b49455aa336309Ben Murdoch                    mediaSource = keyValue[1];
298662b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch                }
298762b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch            }
298862b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch        }
298962b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch
299062b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch        // This intent will display the standard OPENABLE file picker.
299122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        Intent i = new Intent(Intent.ACTION_GET_CONTENT);
299222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        i.addCategory(Intent.CATEGORY_OPENABLE);
299362b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch
299462b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch        // Create an intent to add to the standard file picker that will
299562b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch        // capture an image from the camera. We'll combine this intent with
299662b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch        // the standard OPENABLE picker unless the web developer specifically
299762b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch        // requested the camera or gallery be opened by passing a parameter
299862b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch        // in the accept type.
299962b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch        Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
300062b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch        File externalDataDir = Environment.getExternalStoragePublicDirectory(
300162b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch                Environment.DIRECTORY_DCIM);
300262b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch        File cameraDataDir = new File(externalDataDir.getAbsolutePath() +
300362b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch                File.separator + "browser-photos");
300462b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch        cameraDataDir.mkdirs();
300562b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch        mCameraFilePath = cameraDataDir.getAbsolutePath() + File.separator +
300662b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch                System.currentTimeMillis() + ".jpg";
300762b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch        cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(new File(mCameraFilePath)));
300862b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch
30096af492aeddda96c749142885e3b49455aa336309Ben Murdoch        Intent camcorderIntent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
30106af492aeddda96c749142885e3b49455aa336309Ben Murdoch
3011039bd47edd231965abb2c8e9b2dd32308cddb74bBen Murdoch        Intent soundRecIntent = new Intent(MediaStore.Audio.Media.RECORD_SOUND_ACTION);
3012039bd47edd231965abb2c8e9b2dd32308cddb74bBen Murdoch
301362b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch        if (mimeType.equals(imageMimeType)) {
301462b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch            i.setType(imageMimeType);
30156af492aeddda96c749142885e3b49455aa336309Ben Murdoch            addCamcorderIntent = false;
30166af492aeddda96c749142885e3b49455aa336309Ben Murdoch            if (mediaSource.equals(mediaSourceValueCamera)) {
301762b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch                // Specified 'image/*' and requested the camera, so go ahead and launch the camera
301862b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch                // directly.
301962b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch                BrowserActivity.this.startActivityForResult(cameraIntent, FILE_SELECTED);
302062b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch                return;
3021b50d7403816f316fdcaf5b5a318383e64f1a8775Ben Murdoch            } else if (mediaSource.equals(mediaSourceValueFileSystem)) {
3022b50d7403816f316fdcaf5b5a318383e64f1a8775Ben Murdoch                // Specified filesytem as the source, so don't want to consider the camera.
302362b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch                addCameraIntent = false;
302462b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch            }
30256af492aeddda96c749142885e3b49455aa336309Ben Murdoch        } else if (mimeType.equals(videoMimeType)) {
30266af492aeddda96c749142885e3b49455aa336309Ben Murdoch            i.setType(videoMimeType);
30276af492aeddda96c749142885e3b49455aa336309Ben Murdoch            addCameraIntent = false;
30286af492aeddda96c749142885e3b49455aa336309Ben Murdoch            // The camcorder saves it's own file and returns it to us in the intent, so
30296af492aeddda96c749142885e3b49455aa336309Ben Murdoch            // we don't need to generate one here.
30306af492aeddda96c749142885e3b49455aa336309Ben Murdoch            mCameraFilePath = null;
30316af492aeddda96c749142885e3b49455aa336309Ben Murdoch
30326af492aeddda96c749142885e3b49455aa336309Ben Murdoch            if (mediaSource.equals(mediaSourceValueCamcorder)) {
3033039bd47edd231965abb2c8e9b2dd32308cddb74bBen Murdoch                // Specified 'video/*' and requested the camcorder, so go ahead and launch the
3034039bd47edd231965abb2c8e9b2dd32308cddb74bBen Murdoch                // camcorder directly.
30356af492aeddda96c749142885e3b49455aa336309Ben Murdoch                BrowserActivity.this.startActivityForResult(camcorderIntent, FILE_SELECTED);
30366af492aeddda96c749142885e3b49455aa336309Ben Murdoch                return;
3037b50d7403816f316fdcaf5b5a318383e64f1a8775Ben Murdoch            } else if (mediaSource.equals(mediaSourceValueFileSystem)) {
3038b50d7403816f316fdcaf5b5a318383e64f1a8775Ben Murdoch                // Specified filesystem as the source, so don't want to consider the camcorder.
30396af492aeddda96c749142885e3b49455aa336309Ben Murdoch                addCamcorderIntent = false;
30406af492aeddda96c749142885e3b49455aa336309Ben Murdoch            }
3041039bd47edd231965abb2c8e9b2dd32308cddb74bBen Murdoch        } else if (mimeType.equals(audioMimeType)) {
3042039bd47edd231965abb2c8e9b2dd32308cddb74bBen Murdoch            i.setType(audioMimeType);
3043039bd47edd231965abb2c8e9b2dd32308cddb74bBen Murdoch            addCameraIntent = false;
3044039bd47edd231965abb2c8e9b2dd32308cddb74bBen Murdoch            addCamcorderIntent = false;
3045039bd47edd231965abb2c8e9b2dd32308cddb74bBen Murdoch            if (mediaSource.equals(mediaSourceValueMicrophone)) {
3046039bd47edd231965abb2c8e9b2dd32308cddb74bBen Murdoch                // Specified 'audio/*' and requested microphone, so go ahead and launch the sound
3047039bd47edd231965abb2c8e9b2dd32308cddb74bBen Murdoch                // recorder.
3048039bd47edd231965abb2c8e9b2dd32308cddb74bBen Murdoch                BrowserActivity.this.startActivityForResult(soundRecIntent, FILE_SELECTED);
3049039bd47edd231965abb2c8e9b2dd32308cddb74bBen Murdoch                return;
3050039bd47edd231965abb2c8e9b2dd32308cddb74bBen Murdoch            }
3051039bd47edd231965abb2c8e9b2dd32308cddb74bBen Murdoch            // On a default system, there is no single option to open an audio "gallery". Both the
3052039bd47edd231965abb2c8e9b2dd32308cddb74bBen Murdoch            // sound recorder and music browser respond to the OPENABLE/audio/* intent unlike the
3053039bd47edd231965abb2c8e9b2dd32308cddb74bBen Murdoch            // image/* and video/* OPENABLE intents where the image / video gallery are the only
3054039bd47edd231965abb2c8e9b2dd32308cddb74bBen Murdoch            // respondants (and so the user is not prompted by default).
305562b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch        } else {
305662b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch            i.setType("*/*");
305762b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch        }
305862b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch
30596af492aeddda96c749142885e3b49455aa336309Ben Murdoch        // Combine the chooser and the extra choices (like camera or camcorder)
306062b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch        Intent chooser = new Intent(Intent.ACTION_CHOOSER);
306162b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch        chooser.putExtra(Intent.EXTRA_INTENT, i);
306262b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch
30636af492aeddda96c749142885e3b49455aa336309Ben Murdoch        Vector<Intent> extraInitialIntents = new Vector<Intent>(0);
30646af492aeddda96c749142885e3b49455aa336309Ben Murdoch
306562b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch        if (addCameraIntent) {
30666af492aeddda96c749142885e3b49455aa336309Ben Murdoch            extraInitialIntents.add(cameraIntent);
30676af492aeddda96c749142885e3b49455aa336309Ben Murdoch        }
30686af492aeddda96c749142885e3b49455aa336309Ben Murdoch
30696af492aeddda96c749142885e3b49455aa336309Ben Murdoch        if (addCamcorderIntent) {
30706af492aeddda96c749142885e3b49455aa336309Ben Murdoch            extraInitialIntents.add(camcorderIntent);
30716af492aeddda96c749142885e3b49455aa336309Ben Murdoch        }
30726af492aeddda96c749142885e3b49455aa336309Ben Murdoch
30736af492aeddda96c749142885e3b49455aa336309Ben Murdoch        if (extraInitialIntents.size() > 0) {
30746af492aeddda96c749142885e3b49455aa336309Ben Murdoch            Intent[] extraIntents = new Intent[extraInitialIntents.size()];
30756af492aeddda96c749142885e3b49455aa336309Ben Murdoch            chooser.putExtra(Intent.EXTRA_INITIAL_INTENTS, extraInitialIntents.toArray(extraIntents));
307662b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch        }
307762b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch
307862b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch        chooser.putExtra(Intent.EXTRA_TITLE, getString(R.string.choose_upload));
307962b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch        BrowserActivity.this.startActivityForResult(chooser, FILE_SELECTED);
308022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
308122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
308222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // -------------------------------------------------------------------------
308322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // Implement functions for DownloadListener
308422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // -------------------------------------------------------------------------
308522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
30860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
30870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Notify the host application a download should be done, or that
30880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * the data should be streamed if a streaming viewer is available.
30890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param url The full url to the content that should be downloaded
30900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param contentDisposition Content-disposition http header, if
30910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *                           present.
30920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param mimetype The mimetype of the content reported by the server
30930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param contentLength The file size reported by the server
30940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
30950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public void onDownloadStart(String url, String userAgent,
30960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            String contentDisposition, String mimetype, long contentLength) {
30970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // if we're dealing wih A/V content that's not explicitly marked
30980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        //     for download, check if it's streamable.
30990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (contentDisposition == null
3100e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                || !contentDisposition.regionMatches(
3101e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                        true, 0, "attachment", 0, 10)) {
31020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // query the package manager to see if there's a registered handler
31030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            //     that matches.
31040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Intent intent = new Intent(Intent.ACTION_VIEW);
31050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            intent.setDataAndType(Uri.parse(url), mimetype);
3106e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott            ResolveInfo info = getPackageManager().resolveActivity(intent,
3107e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                    PackageManager.MATCH_DEFAULT_ONLY);
3108e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott            if (info != null) {
3109e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                ComponentName myName = getComponentName();
3110e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                // If we resolved to ourselves, we don't want to attempt to
3111e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                // load the url only to try and download it again.
3112e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                if (!myName.getPackageName().equals(
3113e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                        info.activityInfo.packageName)
3114e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                        || !myName.getClassName().equals(
3115e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                                info.activityInfo.name)) {
3116e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                    // someone (other than us) knows how to handle this mime
3117e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                    // type with this scheme, don't download.
3118e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                    try {
3119e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                        startActivity(intent);
3120e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                        return;
3121e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                    } catch (ActivityNotFoundException ex) {
3122e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                        if (LOGD_ENABLED) {
3123e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                            Log.d(LOGTAG, "activity not found for " + mimetype
3124e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                                    + " over " + Uri.parse(url).getScheme(),
3125e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                                    ex);
3126e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                        }
3127e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                        // Best behavior is to fall back to a download in this
3128e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                        // case
31290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
31300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
31310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
31320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
31330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        onDownloadStartNoStream(url, userAgent, contentDisposition, mimetype, contentLength);
31340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
31350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
3136fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen    // This is to work around the fact that java.net.URI throws Exceptions
3137fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen    // instead of just encoding URL's properly
3138fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen    // Helper method for onDownloadStartNoStream
3139fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen    private static String encodePath(String path) {
3140fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen        char[] chars = path.toCharArray();
3141fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen
3142fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen        boolean needed = false;
3143fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen        for (char c : chars) {
3144fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen            if (c == '[' || c == ']') {
3145fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen                needed = true;
3146fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen                break;
3147fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen            }
3148fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen        }
3149fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen        if (needed == false) {
3150fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen            return path;
3151fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen        }
3152fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen
3153fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen        StringBuilder sb = new StringBuilder("");
3154fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen        for (char c : chars) {
3155fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen            if (c == '[' || c == ']') {
3156fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen                sb.append('%');
3157fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen                sb.append(Integer.toHexString(c));
3158fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen            } else {
3159fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen                sb.append(c);
3160fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen            }
3161fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen        }
3162fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen
3163fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen        return sb.toString();
3164fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen    }
3165fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen
31660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
31670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Notify the host application a download should be done, even if there
31680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * is a streaming viewer available for thise type.
31690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param url The full url to the content that should be downloaded
31700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param contentDisposition Content-disposition http header, if
31710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *                           present.
31720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param mimetype The mimetype of the content reported by the server
31730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param contentLength The file size reported by the server
31740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
31750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /*package */ void onDownloadStartNoStream(String url, String userAgent,
31760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            String contentDisposition, String mimetype, long contentLength) {
31770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
31780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String filename = URLUtil.guessFileName(url,
31790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                contentDisposition, mimetype);
31800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
31810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Check to see if we have an SDCard
31820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String status = Environment.getExternalStorageState();
31830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (!status.equals(Environment.MEDIA_MOUNTED)) {
31840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            int title;
31850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            String msg;
31860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
31870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Check to see if the SDCard is busy, same as the music app
31880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (status.equals(Environment.MEDIA_SHARED)) {
31890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                msg = getString(R.string.download_sdcard_busy_dlg_msg);
31900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                title = R.string.download_sdcard_busy_dlg_title;
31910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } else {
31920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                msg = getString(R.string.download_no_sdcard_dlg_msg, filename);
31930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                title = R.string.download_no_sdcard_dlg_title;
31940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
31950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
31960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            new AlertDialog.Builder(this)
31970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setTitle(title)
31980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setIcon(android.R.drawable.ic_dialog_alert)
31990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setMessage(msg)
32000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setPositiveButton(R.string.ok, null)
32010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .show();
32020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
32030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
32040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
3205fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen        // java.net.URI is a lot stricter than KURL so we have to encode some
3206fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen        // extra characters. Fix for b 2538060 and b 1634719
3207fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen        WebAddress webAddress;
32080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        try {
3209fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen            webAddress = new WebAddress(url);
3210fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen            webAddress.mPath = encodePath(webAddress.mPath);
32110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } catch (Exception e) {
3212fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen            // This only happens for very bad urls, we want to chatch the
3213fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen            // exception here
3214fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen            Log.e(LOGTAG, "Exception trying to parse url:" + url);
32150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
32160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
32170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
32180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // XXX: Have to use the old url since the cookies were stored using the
32190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // old percent-encoded url.
32200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String cookies = CookieManager.getInstance().getCookie(url);
32210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
32220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        ContentValues values = new ContentValues();
3223fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen        values.put(Downloads.Impl.COLUMN_URI, webAddress.toString());
32241e5bad97ca8fb9b12501f4f747941d02f03e1362Jean-Baptiste Queru        values.put(Downloads.Impl.COLUMN_COOKIE_DATA, cookies);
32251e5bad97ca8fb9b12501f4f747941d02f03e1362Jean-Baptiste Queru        values.put(Downloads.Impl.COLUMN_USER_AGENT, userAgent);
32261e5bad97ca8fb9b12501f4f747941d02f03e1362Jean-Baptiste Queru        values.put(Downloads.Impl.COLUMN_NOTIFICATION_PACKAGE,
32270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                getPackageName());
32281e5bad97ca8fb9b12501f4f747941d02f03e1362Jean-Baptiste Queru        values.put(Downloads.Impl.COLUMN_NOTIFICATION_CLASS,
3229a563d09392905140893d7a017dd63721577e1953Leon Scroggins                OpenDownloadReceiver.class.getCanonicalName());
32301e5bad97ca8fb9b12501f4f747941d02f03e1362Jean-Baptiste Queru        values.put(Downloads.Impl.COLUMN_VISIBILITY,
32311e5bad97ca8fb9b12501f4f747941d02f03e1362Jean-Baptiste Queru                Downloads.Impl.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
32321e5bad97ca8fb9b12501f4f747941d02f03e1362Jean-Baptiste Queru        values.put(Downloads.Impl.COLUMN_MIME_TYPE, mimetype);
32331e5bad97ca8fb9b12501f4f747941d02f03e1362Jean-Baptiste Queru        values.put(Downloads.Impl.COLUMN_FILE_NAME_HINT, filename);
3234fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen        values.put(Downloads.Impl.COLUMN_DESCRIPTION, webAddress.mHost);
32350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (contentLength > 0) {
32361e5bad97ca8fb9b12501f4f747941d02f03e1362Jean-Baptiste Queru            values.put(Downloads.Impl.COLUMN_TOTAL_BYTES, contentLength);
32370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
32380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mimetype == null) {
32390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // We must have long pressed on a link or image to download it. We
32400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // are not sure of the mimetype in this case, so do a head request
32410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            new FetchUrlMimeType(this).execute(values);
32420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
32430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            final Uri contentUri =
32441e5bad97ca8fb9b12501f4f747941d02f03e1362Jean-Baptiste Queru                    getContentResolver().insert(Downloads.Impl.CONTENT_URI, values);
32450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
32469191a7f745c965cf57df94d0628890b413c710c9Leon Scroggins        Toast.makeText(this, R.string.download_pending, Toast.LENGTH_SHORT)
32479191a7f745c965cf57df94d0628890b413c710c9Leon Scroggins                .show();
32480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
32490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
325022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // -------------------------------------------------------------------------
325122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
32520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
32530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Resets the lock icon. This method is called when we start a new load and
32540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * know the url to be loaded.
32550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
32560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void resetLockIcon(String url) {
32570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Save the lock-icon state (we revert to it if the load gets cancelled)
325822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mTabControl.getCurrentTab().resetLockIcon(url);
32590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        updateLockIconImage(LOCK_ICON_UNSECURE);
32600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
32610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
32620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
32633bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     * Update the lock icon to correspond to our latest state.
32643bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     */
326522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private void updateLockIconToLatest() {
326691f65fccfd6feae560a42abdd3385ca3318f0430Leon Scroggins        Tab t = mTabControl.getCurrentTab();
326791f65fccfd6feae560a42abdd3385ca3318f0430Leon Scroggins        if (t != null) {
326891f65fccfd6feae560a42abdd3385ca3318f0430Leon Scroggins            updateLockIconImage(t.getLockIconType());
326991f65fccfd6feae560a42abdd3385ca3318f0430Leon Scroggins        }
32703bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    }
32713bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins
32723bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    /**
32730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Updates the lock-icon image in the title-bar.
32740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
32750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void updateLockIconImage(int lockIconType) {
32760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        Drawable d = null;
32770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (lockIconType == LOCK_ICON_SECURE) {
32780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            d = mSecLockIcon;
32790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else if (lockIconType == LOCK_ICON_MIXED) {
32800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            d = mMixLockIcon;
32810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
328268579393973f745fc65a2781061af9bb8f2d7020Leon Scroggins        mTitleBar.setLock(d);
3283a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb        mFakeTitleBar.setLock(d);
32840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
32850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
32860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
32870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Displays a page-info dialog.
32880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param tab The tab to show info about
32890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param fromShowSSLCertificateOnError The flag that indicates whether
32900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * this dialog was opened from the SSL-certificate-on-error dialog or
32910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * not. This is important, since we need to know whether to return to
32920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * the parent dialog or simply dismiss.
32930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
329422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private void showPageInfo(final Tab tab,
32950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                              final boolean fromShowSSLCertificateOnError) {
32960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final LayoutInflater factory = LayoutInflater
32970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .from(this);
32980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
32990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final View pageInfoView = factory.inflate(R.layout.page_info, null);
33000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
33010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final WebView view = tab.getWebView();
33020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
33030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String url = null;
33040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String title = null;
33050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
33060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (view == null) {
33070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            url = tab.getUrl();
33080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            title = tab.getTitle();
33090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else if (view == mTabControl.getCurrentWebView()) {
33100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project             // Use the cached title and url if this is the current WebView
33110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            url = mUrl;
33120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            title = mTitle;
33130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
33140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            url = view.getUrl();
33150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            title = view.getTitle();
33160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
33170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
33180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (url == null) {
33190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            url = "";
33200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
33210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (title == null) {
33220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            title = "";
33230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
33240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
33250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        ((TextView) pageInfoView.findViewById(R.id.address)).setText(url);
33260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        ((TextView) pageInfoView.findViewById(R.id.title)).setText(title);
33270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
33280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mPageInfoView = tab;
3329c7b92f811dfa3572578ddc6714c98a03936d9ce5Leon Scroggins        mPageInfoFromShowSSLCertificateOnError = fromShowSSLCertificateOnError;
33300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
33310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        AlertDialog.Builder alertDialogBuilder =
33320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            new AlertDialog.Builder(this)
33330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            .setTitle(R.string.page_info).setIcon(android.R.drawable.ic_dialog_info)
33340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            .setView(pageInfoView)
33350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            .setPositiveButton(
33360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                R.string.ok,
33370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                new DialogInterface.OnClickListener() {
33380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    public void onClick(DialogInterface dialog,
33390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        int whichButton) {
33400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        mPageInfoDialog = null;
33410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        mPageInfoView = null;
33420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
33430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        // if we came here from the SSL error dialog
33440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        if (fromShowSSLCertificateOnError) {
33450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            // go back to the SSL error dialog
33460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            showSSLCertificateOnError(
33470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorView,
33480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorHandler,
33490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorError);
33500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }
33510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
33520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                })
33530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            .setOnCancelListener(
33540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                new DialogInterface.OnCancelListener() {
33550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    public void onCancel(DialogInterface dialog) {
33560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        mPageInfoDialog = null;
33570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        mPageInfoView = null;
33580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
33590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        // if we came here from the SSL error dialog
33600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        if (fromShowSSLCertificateOnError) {
33610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            // go back to the SSL error dialog
33620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            showSSLCertificateOnError(
33630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorView,
33640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorHandler,
33650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorError);
33660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }
33670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
33680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                });
33690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
33700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // if we have a main top-level page SSL certificate set or a certificate
33710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // error
33720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (fromShowSSLCertificateOnError ||
33730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                (view != null && view.getCertificate() != null)) {
33740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // add a 'View Certificate' button
33750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            alertDialogBuilder.setNeutralButton(
33760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                R.string.view_certificate,
33770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                new DialogInterface.OnClickListener() {
33780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    public void onClick(DialogInterface dialog,
33790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        int whichButton) {
33800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        mPageInfoDialog = null;
33810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        mPageInfoView = null;
33820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
33830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        // if we came here from the SSL error dialog
33840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        if (fromShowSSLCertificateOnError) {
33850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            // go back to the SSL error dialog
33860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            showSSLCertificateOnError(
33870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorView,
33880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorHandler,
33890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorError);
33900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        } else {
33910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            // otherwise, display the top-most certificate from
33920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            // the chain
33930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            if (view.getCertificate() != null) {
33940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                showSSLCertificate(tab);
33950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            }
33960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }
33970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
33980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                });
33990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
34000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
34010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mPageInfoDialog = alertDialogBuilder.show();
34020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
34030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
34040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project       /**
34050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Displays the main top-level page SSL certificate dialog
34060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * (accessible from the Page-Info dialog).
34070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param tab The tab to show certificate for.
34080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
340922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private void showSSLCertificate(final Tab tab) {
34100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final View certificateView =
34110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                inflateCertificateView(tab.getWebView().getCertificate());
34120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (certificateView == null) {
34130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
34140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
34150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
34160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        LayoutInflater factory = LayoutInflater.from(this);
34170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
34180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final LinearLayout placeholder =
34190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                (LinearLayout)certificateView.findViewById(R.id.placeholder);
34200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
34210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        LinearLayout ll = (LinearLayout) factory.inflate(
34220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            R.layout.ssl_success, placeholder);
34230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        ((TextView)ll.findViewById(R.id.success))
34240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            .setText(R.string.ssl_certificate_is_valid);
34250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
34260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mSSLCertificateView = tab;
34270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mSSLCertificateDialog =
34280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            new AlertDialog.Builder(this)
34290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setTitle(R.string.ssl_certificate).setIcon(
34300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    R.drawable.ic_dialog_browser_certificate_secure)
34310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setView(certificateView)
34320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setPositiveButton(R.string.ok,
34330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new DialogInterface.OnClickListener() {
34340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            public void onClick(DialogInterface dialog,
34350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    int whichButton) {
34360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateDialog = null;
34370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateView = null;
34380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
34390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                showPageInfo(tab, false);
34400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            }
34410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        })
34420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setOnCancelListener(
34430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new DialogInterface.OnCancelListener() {
34440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            public void onCancel(DialogInterface dialog) {
34450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateDialog = null;
34460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateView = null;
34470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
34480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                showPageInfo(tab, false);
34490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            }
34500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        })
34510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .show();
34520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
34530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
34540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
34550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Displays the SSL error certificate dialog.
34560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param view The target web-view.
34570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param handler The SSL error handler responsible for cancelling the
34580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * connection that resulted in an SSL error or proceeding per user request.
34590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param error The SSL error object.
34600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
346122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void showSSLCertificateOnError(
34620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final WebView view, final SslErrorHandler handler, final SslError error) {
34630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
34640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final View certificateView =
34650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            inflateCertificateView(error.getCertificate());
34660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (certificateView == null) {
34670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
34680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
34690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
34700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        LayoutInflater factory = LayoutInflater.from(this);
34710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
34720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final LinearLayout placeholder =
34730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                (LinearLayout)certificateView.findViewById(R.id.placeholder);
34740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
34750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (error.hasError(SslError.SSL_UNTRUSTED)) {
34760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            LinearLayout ll = (LinearLayout)factory
34770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .inflate(R.layout.ssl_warning, placeholder);
34780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((TextView)ll.findViewById(R.id.warning))
34790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setText(R.string.ssl_untrusted);
34800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
34810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
34820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (error.hasError(SslError.SSL_IDMISMATCH)) {
34830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            LinearLayout ll = (LinearLayout)factory
34840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .inflate(R.layout.ssl_warning, placeholder);
34850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((TextView)ll.findViewById(R.id.warning))
34860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setText(R.string.ssl_mismatch);
34870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
34880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
34890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (error.hasError(SslError.SSL_EXPIRED)) {
34900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            LinearLayout ll = (LinearLayout)factory
34910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .inflate(R.layout.ssl_warning, placeholder);
34920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((TextView)ll.findViewById(R.id.warning))
34930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setText(R.string.ssl_expired);
34940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
34950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
34960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (error.hasError(SslError.SSL_NOTYETVALID)) {
34970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            LinearLayout ll = (LinearLayout)factory
34980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .inflate(R.layout.ssl_warning, placeholder);
34990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((TextView)ll.findViewById(R.id.warning))
35000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setText(R.string.ssl_not_yet_valid);
35010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
35020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
35030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mSSLCertificateOnErrorHandler = handler;
35040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mSSLCertificateOnErrorView = view;
35050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mSSLCertificateOnErrorError = error;
35060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mSSLCertificateOnErrorDialog =
35070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            new AlertDialog.Builder(this)
35080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setTitle(R.string.ssl_certificate).setIcon(
35090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    R.drawable.ic_dialog_browser_certificate_partially_secure)
35100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setView(certificateView)
35110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setPositiveButton(R.string.ok,
35120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new DialogInterface.OnClickListener() {
35130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            public void onClick(DialogInterface dialog,
35140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    int whichButton) {
35150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorDialog = null;
35160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorView = null;
35170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorHandler = null;
35180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorError = null;
35190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
352022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                view.getWebViewClient().onReceivedSslError(
352122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                                view, handler, error);
35220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            }
35230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        })
35240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                 .setNeutralButton(R.string.page_info_view,
35250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new DialogInterface.OnClickListener() {
35260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            public void onClick(DialogInterface dialog,
35270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    int whichButton) {
35280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorDialog = null;
35290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
35300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                // do not clear the dialog state: we will
35310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                // need to show the dialog again once the
35320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                // user is done exploring the page-info details
35330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
35340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                showPageInfo(mTabControl.getTabFromView(view),
35350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        true);
35360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            }
35370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        })
35380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setOnCancelListener(
35390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new DialogInterface.OnCancelListener() {
35400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            public void onCancel(DialogInterface dialog) {
35410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorDialog = null;
35420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorView = null;
35430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorHandler = null;
35440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorError = null;
35450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
354622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                view.getWebViewClient().onReceivedSslError(
354722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                                view, handler, error);
35480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            }
35490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        })
35500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .show();
35510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
35520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
35530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
35540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Inflates the SSL certificate view (helper method).
35550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param certificate The SSL certificate.
35560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @return The resultant certificate view with issued-to, issued-by,
35570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * issued-on, expires-on, and possibly other fields set.
35580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * If the input certificate is null, returns null.
35590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
35600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private View inflateCertificateView(SslCertificate certificate) {
35610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (certificate == null) {
35620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return null;
35630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
35640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
35650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        LayoutInflater factory = LayoutInflater.from(this);
35660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
35670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        View certificateView = factory.inflate(
35680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            R.layout.ssl_certificate, null);
35690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
35700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // issued to:
35710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        SslCertificate.DName issuedTo = certificate.getIssuedTo();
35720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (issuedTo != null) {
35730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((TextView) certificateView.findViewById(R.id.to_common))
35740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setText(issuedTo.getCName());
35750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((TextView) certificateView.findViewById(R.id.to_org))
35760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setText(issuedTo.getOName());
35770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((TextView) certificateView.findViewById(R.id.to_org_unit))
35780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setText(issuedTo.getUName());
35790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
35800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
35810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // issued by:
35820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        SslCertificate.DName issuedBy = certificate.getIssuedBy();
35830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (issuedBy != null) {
35840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((TextView) certificateView.findViewById(R.id.by_common))
35850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setText(issuedBy.getCName());
35860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((TextView) certificateView.findViewById(R.id.by_org))
35870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setText(issuedBy.getOName());
35880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((TextView) certificateView.findViewById(R.id.by_org_unit))
35890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setText(issuedBy.getUName());
35900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
35910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
35920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // issued on:
359395a2e4ab94514e4e41033b0d27a0e66855cff8ebBrian Carlstrom        String issuedOn = formatCertificateDate(
359495a2e4ab94514e4e41033b0d27a0e66855cff8ebBrian Carlstrom            certificate.getValidNotBeforeDate());
35950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        ((TextView) certificateView.findViewById(R.id.issued_on))
35960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            .setText(issuedOn);
35970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
35980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // expires on:
359995a2e4ab94514e4e41033b0d27a0e66855cff8ebBrian Carlstrom        String expiresOn = formatCertificateDate(
360095a2e4ab94514e4e41033b0d27a0e66855cff8ebBrian Carlstrom            certificate.getValidNotAfterDate());
36010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        ((TextView) certificateView.findViewById(R.id.expires_on))
36020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            .setText(expiresOn);
36030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
36040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return certificateView;
36050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
36060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
36070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
360895a2e4ab94514e4e41033b0d27a0e66855cff8ebBrian Carlstrom     * Formats the certificate date to a properly localized date string.
36090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @return Properly localized version of the certificate date string and
361095a2e4ab94514e4e41033b0d27a0e66855cff8ebBrian Carlstrom     * the "" if it fails to localize.
36110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
361295a2e4ab94514e4e41033b0d27a0e66855cff8ebBrian Carlstrom    private String formatCertificateDate(Date certificateDate) {
361395a2e4ab94514e4e41033b0d27a0e66855cff8ebBrian Carlstrom      if (certificateDate == null) {
361495a2e4ab94514e4e41033b0d27a0e66855cff8ebBrian Carlstrom          return "";
36150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project      }
361695a2e4ab94514e4e41033b0d27a0e66855cff8ebBrian Carlstrom      String formattedDate = DateFormat.getDateFormat(this).format(certificateDate);
361795a2e4ab94514e4e41033b0d27a0e66855cff8ebBrian Carlstrom      if (formattedDate == null) {
361895a2e4ab94514e4e41033b0d27a0e66855cff8ebBrian Carlstrom          return "";
361995a2e4ab94514e4e41033b0d27a0e66855cff8ebBrian Carlstrom      }
362095a2e4ab94514e4e41033b0d27a0e66855cff8ebBrian Carlstrom      return formattedDate;
36210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
36220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
36230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
36240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Displays an http-authentication dialog.
36250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
362622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void showHttpAuthentication(final HttpAuthHandler handler,
36270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            final String host, final String realm, final String title,
36280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            final String name, final String password, int focusId) {
36290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        LayoutInflater factory = LayoutInflater.from(this);
36300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final View v = factory
36310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .inflate(R.layout.http_authentication, null);
36320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (name != null) {
36330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((EditText) v.findViewById(R.id.username_edit)).setText(name);
36340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
36350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (password != null) {
36360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((EditText) v.findViewById(R.id.password_edit)).setText(password);
36370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
36380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
36390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String titleText = title;
36400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (titleText == null) {
36410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            titleText = getText(R.string.sign_in_to).toString().replace(
36420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    "%s1", host).replace("%s2", realm);
36430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
36440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
36450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mHttpAuthHandler = handler;
36460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        AlertDialog dialog = new AlertDialog.Builder(this)
36470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setTitle(titleText)
36480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setIcon(android.R.drawable.ic_dialog_alert)
36490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setView(v)
36500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setPositiveButton(R.string.action,
36510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new DialogInterface.OnClickListener() {
36520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                             public void onClick(DialogInterface dialog,
36530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                     int whichButton) {
36540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                String nm = ((EditText) v
36550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        .findViewById(R.id.username_edit))
36560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        .getText().toString();
36570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                String pw = ((EditText) v
36580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        .findViewById(R.id.password_edit))
36590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        .getText().toString();
36600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                BrowserActivity.this.setHttpAuthUsernamePassword
36610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        (host, realm, nm, pw);
36620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                handler.proceed(nm, pw);
36630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mHttpAuthenticationDialog = null;
36640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mHttpAuthHandler = null;
36650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            }})
36660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setNegativeButton(R.string.cancel,
36670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new DialogInterface.OnClickListener() {
36680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            public void onClick(DialogInterface dialog,
36690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    int whichButton) {
36700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                handler.cancel();
36710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                BrowserActivity.this.resetTitleAndRevertLockIcon();
36720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mHttpAuthenticationDialog = null;
36730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mHttpAuthHandler = null;
36740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            }})
36750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setOnCancelListener(new DialogInterface.OnCancelListener() {
36760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        public void onCancel(DialogInterface dialog) {
36770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            handler.cancel();
36780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            BrowserActivity.this.resetTitleAndRevertLockIcon();
36790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            mHttpAuthenticationDialog = null;
36800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            mHttpAuthHandler = null;
36810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }})
36820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .create();
36830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Make the IME appear when the dialog is displayed if applicable.
36840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        dialog.getWindow().setSoftInputMode(
36850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);
36860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        dialog.show();
36870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (focusId != 0) {
36880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            dialog.findViewById(focusId).requestFocus();
36890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
36900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            v.findViewById(R.id.username_edit).requestFocus();
36910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
36920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mHttpAuthenticationDialog = dialog;
36930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
36940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
36950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public int getProgress() {
36960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebView w = mTabControl.getCurrentWebView();
36970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (w != null) {
36980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return w.getProgress();
36990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
37000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return 100;
37010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
37020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
37030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
37040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
37050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Set HTTP authentication password.
37060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *
37070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param host The host for the password
37080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param realm The realm for the password
37090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param username The username for the password. If it is null, it means
37100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *            password can't be saved.
37110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param password The password
37120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
37130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public void setHttpAuthUsernamePassword(String host, String realm,
37140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                            String username,
37150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                            String password) {
371695a53b25504f12c3a5f8ecbbfcff7ac1dc047e4fSteve Block        WebView w = getTopWindow();
37170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (w != null) {
37180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            w.setHttpAuthUsernamePassword(host, realm, username, password);
37190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
37200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
37210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
37220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
37230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * connectivity manager says net has come or gone... inform the user
37240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param up true if net has come up, false if net has gone down
37250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
37260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public void onNetworkToggle(boolean up) {
37270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (up == mIsNetworkUp) {
37280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
37290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else if (up) {
37300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mIsNetworkUp = true;
37310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (mAlertDialog != null) {
37320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mAlertDialog.cancel();
37330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mAlertDialog = null;
37340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
37350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
37360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mIsNetworkUp = false;
3737eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott            if (mInLoad) {
3738eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott                createAndShowNetworkDialog();
3739eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott           }
37400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
37410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebView w = mTabControl.getCurrentWebView();
37420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (w != null) {
37430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            w.setNetworkAvailable(up);
37440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
37450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
37460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
374722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    boolean isNetworkUp() {
374822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return mIsNetworkUp;
374922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
375022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
3751eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott    // This method shows the network dialog alerting the user that the net is
3752eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott    // down. It will only show the dialog if mAlertDialog is null.
3753eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott    private void createAndShowNetworkDialog() {
3754eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott        if (mAlertDialog == null) {
3755eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott            mAlertDialog = new AlertDialog.Builder(this)
3756eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott                    .setTitle(R.string.loadSuspendedTitle)
3757eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott                    .setMessage(R.string.loadSuspended)
3758eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott                    .setPositiveButton(R.string.ok, null)
3759eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott                    .show();
3760eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott        }
3761eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott    }
3762eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott
37630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    @Override
37640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    protected void onActivityResult(int requestCode, int resultCode,
37650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    Intent intent) {
3766bb394f3e134b6e5898ef7ae861b75e95e618688fGrace Kloba        if (getTopWindow() == null) return;
3767bb394f3e134b6e5898ef7ae861b75e95e618688fGrace Kloba
37680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        switch (requestCode) {
37690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case COMBO_PAGE:
37700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (resultCode == RESULT_OK && intent != null) {
37710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    String data = intent.getAction();
37720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    Bundle extras = intent.getExtras();
37730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    if (extras != null && extras.getBoolean("new_window", false)) {
377468792c84eded7f83e2f086d3efe81f9cfc07f9c3Michael Kolb                        openTab(data, false);
377568792c84eded7f83e2f086d3efe81f9cfc07f9c3Michael Kolb                    } else if ((extras != null) &&
377668792c84eded7f83e2f086d3efe81f9cfc07f9c3Michael Kolb                            extras.getBoolean(CombinedBookmarkHistoryActivity.NEWTAB_MODE)) {
377768792c84eded7f83e2f086d3efe81f9cfc07f9c3Michael Kolb                        openTab(data, true);
37780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    } else {
377968792c84eded7f83e2f086d3efe81f9cfc07f9c3Michael Kolb                        final Tab currentTab = mTabControl.getCurrentTab();
37801f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                        dismissSubWindow(currentTab);
37811f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                        if (data != null && data.length() != 0) {
378292472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins                            loadUrl(getTopWindow(), data);
37830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }
37840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
37850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
3786fde9746ac3055848e110c35f19ec5893c621f766Leon Scroggins                // Deliberately fall through to PREFERENCES_PAGE, since the
3787fde9746ac3055848e110c35f19ec5893c621f766Leon Scroggins                // same extra may be attached to the COMBO_PAGE
3788fde9746ac3055848e110c35f19ec5893c621f766Leon Scroggins            case PREFERENCES_PAGE:
3789fde9746ac3055848e110c35f19ec5893c621f766Leon Scroggins                if (resultCode == RESULT_OK && intent != null) {
3790fde9746ac3055848e110c35f19ec5893c621f766Leon Scroggins                    String action = intent.getStringExtra(Intent.EXTRA_TEXT);
3791fde9746ac3055848e110c35f19ec5893c621f766Leon Scroggins                    if (BrowserSettings.PREF_CLEAR_HISTORY.equals(action)) {
3792fde9746ac3055848e110c35f19ec5893c621f766Leon Scroggins                        mTabControl.removeParentChildRelationShips();
3793fde9746ac3055848e110c35f19ec5893c621f766Leon Scroggins                    }
3794fde9746ac3055848e110c35f19ec5893c621f766Leon Scroggins                }
37950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
37968d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins            // Choose a file from the file picker.
37978d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins            case FILE_SELECTED:
37988d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins                if (null == mUploadMessage) break;
37998d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins                Uri result = intent == null || resultCode != RESULT_OK ? null
38008d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins                        : intent.getData();
380162b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch
380262b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch                // As we ask the camera to save the result of the user taking
380362b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch                // a picture, the camera application does not return anything other
380462b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch                // than RESULT_OK. So we need to check whether the file we expected
380562b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch                // was written to disk in the in the case that we
380662b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch                // did not get an intent returned but did get a RESULT_OK. If it was,
380762b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch                // we assume that this result has came back from the camera.
380862b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch                if (result == null && intent == null && resultCode == RESULT_OK) {
380962b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch                    File cameraFile = new File(mCameraFilePath);
381062b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch                    if (cameraFile.exists()) {
381162b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch                        result = Uri.fromFile(cameraFile);
381207d3473804cdfd646b39001ca80ebf530e8f8749Ben Murdoch                        // Broadcast to the media scanner that we have a new photo
381307d3473804cdfd646b39001ca80ebf530e8f8749Ben Murdoch                        // so it will be added into the gallery for the user.
381407d3473804cdfd646b39001ca80ebf530e8f8749Ben Murdoch                        sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, result));
381562b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch                    }
381662b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch                }
38178d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins                mUploadMessage.onReceiveValue(result);
38188d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins                mUploadMessage = null;
381962b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch                mCameraFilePath = null;
38208d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins                break;
38210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            default:
38220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
38230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
3824304442375719effd41dbd53ae62de7a8d0cec7d9Leon Scroggins        getTopWindow().requestFocus();
38250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
38260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
38270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /*
38280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * This method is called as a result of the user selecting the options
3829f08809b2cf7e502fef5965691a7fb6d7cf0322afLeon Scroggins     * menu to see the download window. It shows the download window on top of
3830f08809b2cf7e502fef5965691a7fb6d7cf0322afLeon Scroggins     * the current window.
38310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
3832f08809b2cf7e502fef5965691a7fb6d7cf0322afLeon Scroggins    private void viewDownloads(Uri downloadRecord) {
38330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        Intent intent = new Intent(this,
38340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                BrowserDownloadPage.class);
38350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        intent.setData(downloadRecord);
383622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        startActivityForResult(intent, BrowserActivity.DOWNLOAD_PAGE);
38370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
38380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
38390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
3840eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch    /* package*/ void promptAddOrInstallBookmark() {
3841eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch        final Tab current = mTabControl.getCurrentTab();
3842eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch        Resources resources = getResources();
3843eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch        CharSequence[] choices = {
3844eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch                resources.getString(R.string.save_to_bookmarks),
3845eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch                resources.getString(R.string.create_shortcut_bookmark)
3846eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch        };
3847eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch
3848eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch        AlertDialog.Builder builder = new AlertDialog.Builder(this);
3849eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch        builder.setTitle(R.string.add_new_bookmark);
3850eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch        builder.setItems(choices, new DialogInterface.OnClickListener() {
3851eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch                public void onClick(DialogInterface dialog, int item) {
3852eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch                    if (item == 0) {
3853eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch                        bookmarkCurrentPage();
3854eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch                    } else if (item == 1) {
3855eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch                        current.populatePickerData();
3856eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch                        String touchIconUrl = mTabControl.getCurrentWebView().getTouchIconUrl();
3857eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch                        if (touchIconUrl != null) {
3858eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch                            // Download the touch icon for this site then save it to the
3859eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch                            // homescreen.
3860eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch                            Bundle b = new Bundle();
3861eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch                            b.putString("url", current.getUrl());
3862eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch                            b.putString("title", current.getTitle());
3863eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch                            b.putParcelable("favicon", current.getFavicon());
3864eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch                            Message msg = mHandler.obtainMessage(TOUCH_ICON_DOWNLOADED);
3865eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch                            msg.setData(b);
3866ccb5de06714993c28d16f1e5abfcd9f0b1e656fcBen Murdoch                            new DownloadTouchIcon(BrowserActivity.this, msg,
3867eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch                                    mTabControl.getCurrentWebView().getSettings()
3868eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch                                    .getUserAgentString()).execute(touchIconUrl);
3869eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch                        } else {
3870eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch                            // add to homescreen, can do it immediately as there is no touch
3871eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch                            // icon.
3872eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch                            showSaveToHomescreenDialog(current.getUrl(), current.getTitle(),
3873eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch                                    null, current.getFavicon());
3874eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch                        }
3875eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch                     }
3876eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch                 }
3877eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch        });
3878eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch        builder.create().show();
3879eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch    }
3880eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch
3881160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins    /**
3882160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins     * Open the Go page.
3883160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins     * @param startWithHistory If true, open starting on the history tab.
3884160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins     *                         Otherwise, start with the bookmarks tab.
3885160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins     */
388668792c84eded7f83e2f086d3efe81f9cfc07f9c3Michael Kolb    /* package */ void bookmarksOrHistoryPicker(boolean startWithHistory, boolean newTabMode) {
38870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebView current = mTabControl.getCurrentWebView();
38880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (current == null) {
38890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
38900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
38910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        Intent intent = new Intent(this,
38920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                CombinedBookmarkHistoryActivity.class);
38930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String title = current.getTitle();
38940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String url = current.getUrl();
389587cc65d95c80c5e3a1c343ad5177a7dc2de874f6Ben Murdoch        Bitmap thumbnail = createScreenshot(current, getDesiredThumbnailWidth(this),
389687cc65d95c80c5e3a1c343ad5177a7dc2de874f6Ben Murdoch                getDesiredThumbnailHeight(this));
3897dcc2b6f08dd5677bc6ba761a9ba6f1c655113051Ben Murdoch
38980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Just in case the user opens bookmarks before a page finishes loading
38990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // so the current history item, and therefore the page, is null.
39000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (null == url) {
39010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            url = mLastEnteredUrl;
39020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // This can happen.
39030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (null == url) {
39040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                url = mSettings.getHomePage();
39050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
39060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
39070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // In case the web page has not yet received its associated title.
39080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (title == null) {
39090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            title = url;
39100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
39110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        intent.putExtra("title", title);
39120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        intent.putExtra("url", url);
3913dcc2b6f08dd5677bc6ba761a9ba6f1c655113051Ben Murdoch        intent.putExtra("thumbnail", thumbnail);
3914304442375719effd41dbd53ae62de7a8d0cec7d9Leon Scroggins        // Disable opening in a new window if we have maxed out the windows
391522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        intent.putExtra("disable_new_window", !mTabControl.canCreateNewTab());
39163918d4443ff38ef1870e02aa51a8b29f8352bb1aPatrick Scott        intent.putExtra("touch_icon_url", current.getTouchIconUrl());
39170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (startWithHistory) {
39180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            intent.putExtra(CombinedBookmarkHistoryActivity.STARTING_TAB,
39190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    CombinedBookmarkHistoryActivity.HISTORY_TAB);
39200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
392168792c84eded7f83e2f086d3efe81f9cfc07f9c3Michael Kolb        if (newTabMode) {
392268792c84eded7f83e2f086d3efe81f9cfc07f9c3Michael Kolb            intent.putExtra(CombinedBookmarkHistoryActivity.NEWTAB_MODE, true);
392368792c84eded7f83e2f086d3efe81f9cfc07f9c3Michael Kolb        }
39240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        startActivityForResult(intent, COMBO_PAGE);
39250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
39260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
3927eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch    private void showSaveToHomescreenDialog(String url, String title, Bitmap touchIcon,
3928eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch            Bitmap favicon) {
3929eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch        Intent intent = new Intent(this, SaveToHomescreenDialog.class);
3930eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch
3931eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch        // Just in case the user tries to save before a page finishes loading
3932eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch        // so the current history item, and therefore the page, is null.
3933eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch        if (null == url) {
3934eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch            url = mLastEnteredUrl;
3935eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch            // This can happen.
3936eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch            if (null == url) {
3937eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch                url = mSettings.getHomePage();
3938eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch            }
3939eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch        }
3940eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch
3941eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch        // In case the web page has not yet received its associated title.
3942eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch        if (title == null) {
3943eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch            title = url;
3944eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch        }
3945eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch
3946eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch        intent.putExtra("title", title);
3947eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch        intent.putExtra("url", url);
3948eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch        intent.putExtra("favicon", favicon);
3949eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch        intent.putExtra("touchIcon", touchIcon);
3950eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch        startActivity(intent);
3951eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch    }
3952eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch
3953eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch
39540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Called when loading from context menu or LOAD_URL message
395592472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins    private void loadUrlFromContext(WebView view, String url) {
39560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // In case the user enters nothing.
39570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (url != null && url.length() != 0 && view != null) {
39580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            url = smartUrlFilter(url);
395922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (!view.getWebViewClient().shouldOverrideUrlLoading(view, url)) {
396092472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins                loadUrl(view, url);
39610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
39620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
39630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
39640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
396592472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins    /**
396692472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins     * Load the URL into the given WebView and update the title bar
396792472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins     * to reflect the new load.  Call this instead of WebView.loadUrl
396892472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins     * directly.
396992472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins     * @param view The WebView used to load url.
397092472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins     * @param url The URL to load.
397192472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins     */
397292472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins    private void loadUrl(WebView view, String url) {
397392472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins        updateTitleBarForNewLoad(view, url);
397492472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins        view.loadUrl(url);
397592472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins    }
397692472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins
397792472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins    /**
397892472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins     * Load UrlData into a Tab and update the title bar to reflect the new
397992472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins     * load.  Call this instead of UrlData.loadIn directly.
398092472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins     * @param t The Tab used to load.
398192472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins     * @param data The UrlData being loaded.
398292472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins     */
398392472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins    private void loadUrlDataIn(Tab t, UrlData data) {
398492472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins        updateTitleBarForNewLoad(t.getWebView(), data.mUrl);
398592472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins        data.loadIn(t);
398692472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins    }
398792472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins
398892472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins    /**
398992472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins     * If the WebView is the top window, update the title bar to reflect
399092472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins     * loading the new URL.  i.e. set its text, clear the favicon (which
399192472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins     * will be set once the page begins loading), and set the progress to
399292472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins     * INITIAL_PROGRESS to show that the page has begun to load. Called
399392472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins     * by loadUrl and loadUrlDataIn.
399492472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins     * @param view The WebView that is starting a load.
399592472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins     * @param url The URL that is being loaded.
399692472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins     */
399792472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins    private void updateTitleBarForNewLoad(WebView view, String url) {
399892472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins        if (view == getTopWindow()) {
399992472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins            setUrlTitle(url, null);
400092472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins            setFavicon(null);
400192472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins            onProgressChanged(view, INITIAL_PROGRESS);
400292472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins        }
400392472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins    }
400492472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins
40050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private String smartUrlFilter(Uri inUri) {
40060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (inUri != null) {
40070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return smartUrlFilter(inUri.toString());
40080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
40090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return null;
40100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
40110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
4012b34f87a2e13af13d697130482af01b537ab7c5fdFeng Qian    protected static final Pattern ACCEPTED_URI_SCHEMA = Pattern.compile(
40130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            "(?i)" + // switch on case insensitive matching
40140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            "(" +    // begin group for schema
40150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            "(?:http|https|file):\\/\\/" +
401625ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima            "|(?:inline|data|about|content|javascript):" +
40170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ")" +
40180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            "(.*)" );
40190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
40200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
40210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Attempts to determine whether user input is a URL or search
40220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * terms.  Anything with a space is passed to search.
40230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *
40240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Converts to lowercase any mistakenly uppercased schema (i.e.,
40250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * "Http://" converts to "http://"
40260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *
40270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @return Original or modified URL
40280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *
40290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
40300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    String smartUrlFilter(String url) {
40310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
40320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String inUrl = url.trim();
40330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        boolean hasSpace = inUrl.indexOf(' ') != -1;
40340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
40350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        Matcher matcher = ACCEPTED_URI_SCHEMA.matcher(inUrl);
40360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (matcher.matches()) {
40370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // force scheme to lowercase
40380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            String scheme = matcher.group(1);
40390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            String lcScheme = scheme.toLowerCase();
40400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (!lcScheme.equals(scheme)) {
4041123ecfb21e7ca670e3d04efe58780b3bac54a9a1Mitsuru Oshima                inUrl = lcScheme + matcher.group(2);
4042123ecfb21e7ca670e3d04efe58780b3bac54a9a1Mitsuru Oshima            }
4043123ecfb21e7ca670e3d04efe58780b3bac54a9a1Mitsuru Oshima            if (hasSpace) {
4044123ecfb21e7ca670e3d04efe58780b3bac54a9a1Mitsuru Oshima                inUrl = inUrl.replace(" ", "%20");
40450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
40460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return inUrl;
40470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
40480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (hasSpace) {
4049565505b1a2c1d3099496af5910760087602e994aSatish Sampath            // FIXME: Is this the correct place to add to searches?
4050565505b1a2c1d3099496af5910760087602e994aSatish Sampath            // what if someone else calls this function?
4051565505b1a2c1d3099496af5910760087602e994aSatish Sampath            int shortcut = parseUrlShortcut(inUrl);
4052565505b1a2c1d3099496af5910760087602e994aSatish Sampath            if (shortcut != SHORTCUT_INVALID) {
4053565505b1a2c1d3099496af5910760087602e994aSatish Sampath                Browser.addSearchUrl(mResolver, inUrl);
4054565505b1a2c1d3099496af5910760087602e994aSatish Sampath                String query = inUrl.substring(2);
4055565505b1a2c1d3099496af5910760087602e994aSatish Sampath                switch (shortcut) {
4056565505b1a2c1d3099496af5910760087602e994aSatish Sampath                case SHORTCUT_GOOGLE_SEARCH:
405747fdfdb989ffb79590a39c40792be995de32e521Grace Kloba                    return URLUtil.composeSearchUrl(query, QuickSearch_G, QUERY_PLACE_HOLDER);
4058565505b1a2c1d3099496af5910760087602e994aSatish Sampath                case SHORTCUT_WIKIPEDIA_SEARCH:
4059565505b1a2c1d3099496af5910760087602e994aSatish Sampath                    return URLUtil.composeSearchUrl(query, QuickSearch_W, QUERY_PLACE_HOLDER);
4060565505b1a2c1d3099496af5910760087602e994aSatish Sampath                case SHORTCUT_DICTIONARY_SEARCH:
4061565505b1a2c1d3099496af5910760087602e994aSatish Sampath                    return URLUtil.composeSearchUrl(query, QuickSearch_D, QUERY_PLACE_HOLDER);
4062565505b1a2c1d3099496af5910760087602e994aSatish Sampath                case SHORTCUT_GOOGLE_MOBILE_LOCAL_SEARCH:
40630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // FIXME: we need location in this case
4064565505b1a2c1d3099496af5910760087602e994aSatish Sampath                    return URLUtil.composeSearchUrl(query, QuickSearch_L, QUERY_PLACE_HOLDER);
40650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
40660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
40670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
40685ee906c089567bca705e18561357510d7b55cb5aDan Egnor            if (Patterns.WEB_URL.matcher(inUrl).matches()) {
40690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                return URLUtil.guessUrl(inUrl);
40700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
40710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
40720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
40730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        Browser.addSearchUrl(mResolver, inUrl);
407447fdfdb989ffb79590a39c40792be995de32e521Grace Kloba        return URLUtil.composeSearchUrl(inUrl, QuickSearch_G, QUERY_PLACE_HOLDER);
40750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
40760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
4077bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch    /* package */ void setShouldShowErrorConsole(boolean flag) {
4078bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch        if (flag == mShouldShowErrorConsole) {
4079bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch            // Nothing to do.
4080bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch            return;
4081bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch        }
4082bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch
4083bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch        mShouldShowErrorConsole = flag;
4084bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch
408522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        ErrorConsoleView errorConsole = mTabControl.getCurrentTab()
408622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                .getErrorConsole(true);
4087bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch
4088bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch        if (flag) {
4089bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch            // Setting the show state of the console will cause it's the layout to be inflated.
4090bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch            if (errorConsole.numberOfErrors() > 0) {
4091bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch                errorConsole.showConsole(ErrorConsoleView.SHOW_MINIMIZED);
4092bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch            } else {
4093bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch                errorConsole.showConsole(ErrorConsoleView.SHOW_NONE);
4094bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch            }
4095bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch
4096bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch            // Now we can add it to the main view.
4097bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch            mErrorConsoleContainer.addView(errorConsole,
409815b8ec6b226f4d57307716e1f495e10a91f8cbf4Romain Guy                    new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
4099bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch                                                  ViewGroup.LayoutParams.WRAP_CONTENT));
4100bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch        } else {
4101bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch            mErrorConsoleContainer.removeView(errorConsole);
4102bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch        }
4103bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch
4104bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch    }
4105bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch
410622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    boolean shouldShowErrorConsole() {
410722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return mShouldShowErrorConsole;
410822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
410922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
4110163ab74e2f85b53a1a374c49677073fb64d35f28Andrei Popescu    private void setStatusBarVisibility(boolean visible) {
4111163ab74e2f85b53a1a374c49677073fb64d35f28Andrei Popescu        int flag = visible ? 0 : WindowManager.LayoutParams.FLAG_FULLSCREEN;
4112163ab74e2f85b53a1a374c49677073fb64d35f28Andrei Popescu        getWindow().setFlags(flag, WindowManager.LayoutParams.FLAG_FULLSCREEN);
4113163ab74e2f85b53a1a374c49677073fb64d35f28Andrei Popescu    }
4114163ab74e2f85b53a1a374c49677073fb64d35f28Andrei Popescu
411556199cc25e7ee0455ec2a8099098b66b8554f677Andrei Popescu
411656199cc25e7ee0455ec2a8099098b66b8554f677Andrei Popescu    private void sendNetworkType(String type, String subtype) {
411756199cc25e7ee0455ec2a8099098b66b8554f677Andrei Popescu        WebView w = mTabControl.getCurrentWebView();
411856199cc25e7ee0455ec2a8099098b66b8554f677Andrei Popescu        if (w != null) {
411956199cc25e7ee0455ec2a8099098b66b8554f677Andrei Popescu            w.setNetworkType(type, subtype);
412056199cc25e7ee0455ec2a8099098b66b8554f677Andrei Popescu        }
412156199cc25e7ee0455ec2a8099098b66b8554f677Andrei Popescu    }
412256199cc25e7ee0455ec2a8099098b66b8554f677Andrei Popescu
412330995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu    private void packageChanged(String packageName, boolean wasAdded) {
412430995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu        WebView w = mTabControl.getCurrentWebView();
412530995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu        if (w == null) {
412630995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu            return;
412730995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu        }
412830995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu
412930995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu        if (wasAdded) {
413030995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu            w.addPackageName(packageName);
413130995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu        } else {
413230995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu            w.removePackageName(packageName);
413330995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu        }
413430995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu    }
413530995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu
413630995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu    private void addPackageNames(Set<String> packageNames) {
413730995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu        WebView w = mTabControl.getCurrentWebView();
413830995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu        if (w == null) {
413930995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu            return;
414030995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu        }
414130995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu
414230995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu        w.addPackageNames(packageNames);
414330995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu    }
414430995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu
414530995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu    private void getInstalledPackages() {
414630995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu        AsyncTask<Void, Void, Set<String> > task =
414730995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu            new AsyncTask<Void, Void, Set<String> >() {
4148e0a3666b5c0dca7352895fa8b9b4fbb2237df721Michael Kolb            @Override
414930995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu            protected Set<String> doInBackground(Void... unused) {
415030995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu                Set<String> installedPackages = new HashSet<String>();
415130995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu                PackageManager pm = BrowserActivity.this.getPackageManager();
415230995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu                if (pm != null) {
415330995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu                    List<PackageInfo> packages = pm.getInstalledPackages(0);
415430995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu                    for (PackageInfo p : packages) {
415530995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu                        if (BrowserActivity.this.sGoogleApps.contains(p.packageName)) {
415630995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu                            installedPackages.add(p.packageName);
415730995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu                        }
415830995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu                    }
415930995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu                }
416030995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu
416130995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu                return installedPackages;
416230995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu            }
416330995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu
416430995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu            // Executes on the UI thread
4165e0a3666b5c0dca7352895fa8b9b4fbb2237df721Michael Kolb            @Override
416630995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu            protected void onPostExecute(Set<String> installedPackages) {
416730995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu                addPackageNames(installedPackages);
416830995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu            }
416930995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu        };
417030995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu        task.execute();
417130995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu    }
417230995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu
4173eb6eef4c45df2d65c3e70660493a147a2be405e3Grace Kloba    final static int LOCK_ICON_UNSECURE = 0;
4174eb6eef4c45df2d65c3e70660493a147a2be405e3Grace Kloba    final static int LOCK_ICON_SECURE   = 1;
4175eb6eef4c45df2d65c3e70660493a147a2be405e3Grace Kloba    final static int LOCK_ICON_MIXED    = 2;
41760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
41770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private BrowserSettings mSettings;
41780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private TabControl      mTabControl;
41790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private ContentResolver mResolver;
41800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private FrameLayout     mContentView;
4181adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu    private View            mCustomView;
4182adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu    private FrameLayout     mCustomViewContainer;
4183c9b5556351b59caec77b4eec1ad30652fec6a4d9Andrei Popescu    private WebChromeClient.CustomViewCallback mCustomViewCallback;
41840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
41850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // FIXME, temp address onPrepareMenu performance problem. When we move everything out of
41860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // view, we should rewrite this.
41870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private int mCurrentMenuState = 0;
41880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private int mMenuState = R.id.MAIN_MENU;
4189adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu    private int mOldMenuState = EMPTY_MENU;
41900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private static final int EMPTY_MENU = -1;
41910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private Menu mMenu;
41920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
41930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Used to prevent chording to result in firing two shortcuts immediately
41940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // one after another.  Fixes bug 1211714.
41950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    boolean mCanChord;
41960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
41970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private boolean mInLoad;
41980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private boolean mIsNetworkUp;
4199b7cc8b439dc595dc48e1c2183b35d23ad72dfbe5Ben Murdoch    private boolean mDidStopLoad;
42000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
42011f10cbfca5bf96e1466e0ed3ce1dbcd6fcfd0608Cary Clark    /* package */ boolean mActivityInPause = true;
42020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
42030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private boolean mMenuIsDown;
42040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
42050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private static boolean mInTrace;
42060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
42070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Performance probe
42080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private static final int[] SYSTEM_CPU_FORMAT = new int[] {
42090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Process.PROC_SPACE_TERM | Process.PROC_COMBINE,
42100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Process.PROC_SPACE_TERM | Process.PROC_OUT_LONG, // 1: user time
42110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Process.PROC_SPACE_TERM | Process.PROC_OUT_LONG, // 2: nice time
42120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Process.PROC_SPACE_TERM | Process.PROC_OUT_LONG, // 3: sys time
42130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Process.PROC_SPACE_TERM | Process.PROC_OUT_LONG, // 4: idle time
42140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Process.PROC_SPACE_TERM | Process.PROC_OUT_LONG, // 5: iowait time
42150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Process.PROC_SPACE_TERM | Process.PROC_OUT_LONG, // 6: irq time
42160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Process.PROC_SPACE_TERM | Process.PROC_OUT_LONG  // 7: softirq time
42170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    };
42180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
42190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private long mStart;
42200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private long mProcessStart;
42210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private long mUserStart;
42220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private long mSystemStart;
42230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private long mIdleStart;
42240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private long mIrqStart;
42250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
42260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private long mUiStart;
42270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
42280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private Drawable    mMixLockIcon;
42290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private Drawable    mSecLockIcon;
42300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
42310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /* hold a ref so we can auto-cancel if necessary */
42320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private AlertDialog mAlertDialog;
42330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
42340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // The up-to-date URL and title (these can be different from those stored
42350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // in WebView, since it takes some time for the information in WebView to
42360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // get updated)
42370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private String mUrl;
42380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private String mTitle;
42390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
42400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // As PageInfo has different style for landscape / portrait, we have
42410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // to re-open it when configuration changed
42420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private AlertDialog mPageInfoDialog;
424322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private Tab mPageInfoView;
42440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // If the Page-Info dialog is launched from the SSL-certificate-on-error
42450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // dialog, we should not just dismiss it, but should get back to the
42460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // SSL-certificate-on-error dialog. This flag is used to store this state
4247c7b92f811dfa3572578ddc6714c98a03936d9ce5Leon Scroggins    private boolean mPageInfoFromShowSSLCertificateOnError;
42480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
42490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // as SSLCertificateOnError has different style for landscape / portrait,
42500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // we have to re-open it when configuration changed
42510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private AlertDialog mSSLCertificateOnErrorDialog;
42520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private WebView mSSLCertificateOnErrorView;
42530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private SslErrorHandler mSSLCertificateOnErrorHandler;
42540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private SslError mSSLCertificateOnErrorError;
42550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
42560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // as SSLCertificate has different style for landscape / portrait, we
42570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // have to re-open it when configuration changed
42580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private AlertDialog mSSLCertificateDialog;
425922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private Tab mSSLCertificateView;
42600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
42610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // as HttpAuthentication has different style for landscape / portrait, we
42620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // have to re-open it when configuration changed
42630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private AlertDialog mHttpAuthenticationDialog;
42640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private HttpAuthHandler mHttpAuthHandler;
42650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
42660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /*package*/ static final FrameLayout.LayoutParams COVER_SCREEN_PARAMS =
42670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                            new FrameLayout.LayoutParams(
426815b8ec6b226f4d57307716e1f495e10a91f8cbf4Romain Guy                                            ViewGroup.LayoutParams.MATCH_PARENT,
426915b8ec6b226f4d57307716e1f495e10a91f8cbf4Romain Guy                                            ViewGroup.LayoutParams.MATCH_PARENT);
4270adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu    /*package*/ static final FrameLayout.LayoutParams COVER_SCREEN_GRAVITY_CENTER =
4271adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu                                            new FrameLayout.LayoutParams(
427215b8ec6b226f4d57307716e1f495e10a91f8cbf4Romain Guy                                            ViewGroup.LayoutParams.MATCH_PARENT,
427315b8ec6b226f4d57307716e1f495e10a91f8cbf4Romain Guy                                            ViewGroup.LayoutParams.MATCH_PARENT,
4274adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu                                            Gravity.CENTER);
427547fdfdb989ffb79590a39c40792be995de32e521Grace Kloba    // Google search
427647fdfdb989ffb79590a39c40792be995de32e521Grace Kloba    final static String QuickSearch_G = "http://www.google.com/m?q=%s";
42770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Wikipedia search
42780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    final static String QuickSearch_W = "http://en.wikipedia.org/w/index.php?search=%s&go=Go";
42790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Dictionary search
42800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    final static String QuickSearch_D = "http://dictionary.reference.com/search?q=%s";
42810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Google Mobile Local search
42820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    final static String QuickSearch_L = "http://www.google.com/m/search?site=local&q=%s&near=mountain+view";
42830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
42840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    final static String QUERY_PLACE_HOLDER = "%s";
42850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
42860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // "source" parameter for Google search through search key
42870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    final static String GOOGLE_SEARCH_SOURCE_SEARCHKEY = "browser-key";
42880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // "source" parameter for Google search through goto menu
42890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    final static String GOOGLE_SEARCH_SOURCE_GOTO = "browser-goto";
42900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // "source" parameter for Google search through simplily type
42910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    final static String GOOGLE_SEARCH_SOURCE_TYPE = "browser-type";
42920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // "source" parameter for Google search suggested by the browser
42930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    final static String GOOGLE_SEARCH_SOURCE_SUGGEST = "browser-suggest";
42940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // "source" parameter for Google search from unknown source
42950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    final static String GOOGLE_SEARCH_SOURCE_UNKNOWN = "unknown";
42960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
42970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private final static String LOGTAG = "browser";
42980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
42990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private String mLastEnteredUrl;
43000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
43010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private PowerManager.WakeLock mWakeLock;
43020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private final static int WAKELOCK_TIMEOUT = 5 * 60 * 1000; // 5 minutes
43030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
43040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private Toast mStopToast;
43050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
4306571b3762a5eb9e492283e0a1e437edd209fdc0deLeon Scroggins    private TitleBarBase mTitleBar;
4307a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb    private TabBar mTabBar;
430881db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins
4309bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch    private LinearLayout mErrorConsoleContainer = null;
4310bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch    private boolean mShouldShowErrorConsole = false;
4311bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch
43120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // As the ids are dynamically created, we can't guarantee that they will
43130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // be in sequence, so this static array maps ids to a window number.
43140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    final static private int[] WINDOW_SHORTCUT_ID_ARRAY =
43150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    { R.id.window_one_menu_id, R.id.window_two_menu_id, R.id.window_three_menu_id,
43160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project      R.id.window_four_menu_id, R.id.window_five_menu_id, R.id.window_six_menu_id,
43170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project      R.id.window_seven_menu_id, R.id.window_eight_menu_id };
43180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
43190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // monitor platform changes
43200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private IntentFilter mNetworkStateChangedFilter;
43210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private BroadcastReceiver mNetworkStateIntentReceiver;
43220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
4323b4da0ad0351996f639b50f9f29b123a9b5c24fd0Grace Kloba    private BroadcastReceiver mPackageInstallationReceiver;
4324b4da0ad0351996f639b50f9f29b123a9b5c24fd0Grace Kloba
4325a7611811e0d744a7220b7bf80c8f795af5ea53edBjorn Bringert    private SystemAllowGeolocationOrigins mSystemAllowGeolocationOrigins;
4326a7611811e0d744a7220b7bf80c8f795af5ea53edBjorn Bringert
43270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // activity requestCode
432878a98e459323f938e97789a6131beddbebb459ceNicolas Roard    final static int COMBO_PAGE                 = 1;
432978a98e459323f938e97789a6131beddbebb459ceNicolas Roard    final static int DOWNLOAD_PAGE              = 2;
433078a98e459323f938e97789a6131beddbebb459ceNicolas Roard    final static int PREFERENCES_PAGE           = 3;
43318d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins    final static int FILE_SELECTED              = 4;
43320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
4333540035dfd1347c78eeec10ec0847e18fcc50ef36Andrei Popescu    // the default <video> poster
4334540035dfd1347c78eeec10ec0847e18fcc50ef36Andrei Popescu    private Bitmap mDefaultVideoPoster;
4335540035dfd1347c78eeec10ec0847e18fcc50ef36Andrei Popescu    // the video progress view
4336540035dfd1347c78eeec10ec0847e18fcc50ef36Andrei Popescu    private View mVideoProgressView;
4337540035dfd1347c78eeec10ec0847e18fcc50ef36Andrei Popescu
433830995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu    // The Google packages we monitor for the navigator.isApplicationInstalled()
433930995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu    // API. Add as needed.
434030995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu    private static Set<String> sGoogleApps;
434130995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu    static {
434230995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu        sGoogleApps = new HashSet<String>();
434330995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu        sGoogleApps.add("com.google.android.youtube");
434430995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu    }
434530995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu
434625ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima    /**
434725ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima     * A UrlData class to abstract how the content will be set to WebView.
434825ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima     * This base class uses loadUrl to show the content.
434925ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima     */
43506eac63e78d43d04e31c4d16830c44c4d9df82639Leon Scroggins    /* package */ static class UrlData {
4351068e48b469f5abca53ee3da38f933cf2c25c93b8Grace Kloba        final String mUrl;
4352068e48b469f5abca53ee3da38f933cf2c25c93b8Grace Kloba        final Map<String, String> mHeaders;
435358d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        final Intent mVoiceIntent;
435460e095c190496d42327f8ec2ef990c044d15a76fGrace Kloba
435525ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima        UrlData(String url) {
435625ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima            this.mUrl = url;
4357068e48b469f5abca53ee3da38f933cf2c25c93b8Grace Kloba            this.mHeaders = null;
435858d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins            this.mVoiceIntent = null;
435925ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima        }
436060e095c190496d42327f8ec2ef990c044d15a76fGrace Kloba
436158d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        UrlData(String url, Map<String, String> headers, Intent intent) {
4362068e48b469f5abca53ee3da38f933cf2c25c93b8Grace Kloba            this.mUrl = url;
4363068e48b469f5abca53ee3da38f933cf2c25c93b8Grace Kloba            this.mHeaders = headers;
4364a1cc3fdce19a336c251297c61cd83ac6cf767cd1Leon Scroggins            if (RecognizerResultsIntent.ACTION_VOICE_SEARCH_RESULTS
4365a1cc3fdce19a336c251297c61cd83ac6cf767cd1Leon Scroggins                    .equals(intent.getAction())) {
436658d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins                this.mVoiceIntent = intent;
436758d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins            } else {
436858d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins                this.mVoiceIntent = null;
436958d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins            }
437060e095c190496d42327f8ec2ef990c044d15a76fGrace Kloba        }
437160e095c190496d42327f8ec2ef990c044d15a76fGrace Kloba
437225ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima        boolean isEmpty() {
437358d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins            return mVoiceIntent == null && (mUrl == null || mUrl.length() == 0);
437425ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima        }
437525ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima
437692472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins        /**
437792472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins         * Load this UrlData into the given Tab.  Use loadUrlDataIn to update
437892472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins         * the title bar as well.
437992472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins         */
438058d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        public void loadIn(Tab t) {
438158d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins            if (mVoiceIntent != null) {
438258d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins                t.activateVoiceSearchMode(mVoiceIntent);
438358d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins            } else {
438458d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins                t.getWebView().loadUrl(mUrl, mHeaders);
438558d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins            }
438625ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima        }
438725ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima    };
438825ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima
43891f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins    /* package */ static final UrlData EMPTY_URL_DATA = new UrlData(null);
43900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project}
4391