BrowserActivity.java revision f3026374dccf7b491152946c5d0e42daec08d899
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
193f65c3831ff82a20f6f0edb08df2d7edae540044Michael Kolbimport com.android.browser.ScrollWebView.ScrollListener;
203f65c3831ff82a20f6f0edb08df2d7edae540044Michael Kolbimport com.android.common.Search;
213f65c3831ff82a20f6f0edb08df2d7edae540044Michael Kolbimport com.android.common.speech.LoggingEvents;
223f65c3831ff82a20f6f0edb08df2d7edae540044Michael Kolb
23ed217745066c160f785626e9a15ebe70af5e25e4Michael Kolbimport android.app.ActionBar;
240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.app.Activity;
250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.app.AlertDialog;
260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.app.ProgressDialog;
270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.app.SearchManager;
280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.content.ActivityNotFoundException;
290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.content.BroadcastReceiver;
3080f32627140aefe828ad539f66fc439d1580bae7Dianne Hackbornimport android.content.ClipboardManager;
310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.content.ComponentName;
3258d56c6b5052faa86083965132cd51b1a9594d0eLeon Scrogginsimport android.content.ContentProvider;
3358d56c6b5052faa86083965132cd51b1a9594d0eLeon Scrogginsimport android.content.ContentProviderClient;
340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.content.ContentResolver;
35b6b7f9ef3b4ed220063f555d8b7c205210a61a04Leon Scrogginsimport android.content.ContentUris;
360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.content.ContentValues;
370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.content.Context;
380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.content.DialogInterface;
390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.content.Intent;
400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.content.IntentFilter;
410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.content.pm.PackageManager;
420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.content.pm.ResolveInfo;
430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.content.res.Configuration;
440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.content.res.Resources;
450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.database.Cursor;
460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.graphics.Bitmap;
47540035dfd1347c78eeec10ec0847e18fcc50ef36Andrei Popescuimport android.graphics.BitmapFactory;
480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.graphics.Canvas;
490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.graphics.Picture;
503bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scrogginsimport android.graphics.PixelFormat;
510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.graphics.drawable.Drawable;
520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.net.ConnectivityManager;
5356199cc25e7ee0455ec2a8099098b66b8554f677Andrei Popescuimport android.net.NetworkInfo;
540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.net.Uri;
550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.net.WebAddress;
560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.net.http.SslCertificate;
570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.net.http.SslError;
580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.os.AsyncTask;
590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.os.Bundle;
600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.os.Debug;
610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.os.Environment;
620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.os.Handler;
630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.os.Message;
640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.os.PowerManager;
650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.os.Process;
660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.os.SystemClock;
670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.provider.Browser;
688ce956c6076a89aae85856f35b94bad7fc8fa1f1Jeff Hamiltonimport android.provider.BrowserContract;
695e335a381a0cd66e94117b202c1f34f5cb29c9b8Cary Clarkimport android.provider.ContactsContract;
70a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolbimport android.provider.ContactsContract.Intents.Insert;
710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.provider.Downloads;
720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.provider.MediaStore;
73a1cc3fdce19a336c251297c61cd83ac6cf767cd1Leon Scrogginsimport android.speech.RecognizerResultsIntent;
740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.text.TextUtils;
750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.text.format.DateFormat;
760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.util.Log;
77385effd3192a16b737a7d4fbe4fc71c6cf467627Dianne Hackbornimport android.util.Patterns;
788e4fbf1b26c2cc05a56ba2d4e7d1eda7d1574e91Leon Scroggins IIIimport android.view.ActionMode;
790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.view.ContextMenu;
80a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolbimport android.view.ContextMenu.ContextMenuInfo;
810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.view.Gravity;
820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.view.KeyEvent;
830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.view.LayoutInflater;
840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.view.Menu;
850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.view.MenuInflater;
860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.view.MenuItem;
87a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolbimport android.view.MenuItem.OnMenuItemClickListener;
883f65c3831ff82a20f6f0edb08df2d7edae540044Michael Kolbimport android.view.MotionEvent;
890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.view.View;
900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.view.ViewGroup;
910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.view.Window;
920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.view.WindowManager;
932b34599c39d2c04c242d2a0ed755705fc414541dSvetoslav Ganovimport android.view.accessibility.AccessibilityManager;
940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.webkit.CookieManager;
950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.webkit.CookieSyncManager;
960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.webkit.DownloadListener;
970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.webkit.HttpAuthHandler;
980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.webkit.SslErrorHandler;
990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.webkit.URLUtil;
100cb6cc864e53f7d916622daf3b2cec133b36d6a55Leon Clarkeimport android.webkit.ValueCallback;
1010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.webkit.WebChromeClient;
1020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.webkit.WebHistoryItem;
1030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.webkit.WebIconDatabase;
1040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.webkit.WebView;
1050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.widget.EditText;
1060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.widget.FrameLayout;
1070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.widget.LinearLayout;
1080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.widget.TextView;
1090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.widget.Toast;
1100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
111b6b7f9ef3b4ed220063f555d8b7c205210a61a04Leon Scrogginsimport java.io.ByteArrayOutputStream;
1120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport java.io.File;
1134f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdochimport java.io.IOException;
1144f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdochimport java.io.InputStream;
1150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport java.net.MalformedURLException;
1169918943559193e3e047a1c18442e2cdb0fe22b15Dianne Hackbornimport java.net.URISyntaxException;
1170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport java.net.URL;
1180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport java.net.URLEncoder;
1193d6df16f1c9a64cf2dc5b41a2078f4c49b0c296aElliott Slaughterimport java.util.Calendar;
1200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport java.util.Date;
1210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport java.util.HashMap;
12200f54c589fd38431efd42ea2a551a49e64d595d5Grace Klobaimport java.util.Iterator;
123068e48b469f5abca53ee3da38f933cf2c25c93b8Grace Klobaimport java.util.Map;
124fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolbimport java.util.Vector;
1250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport java.util.regex.Matcher;
1260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport java.util.regex.Pattern;
1270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
1280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectpublic class BrowserActivity extends Activity
12998d5fce7c687cfcc956b10d44946d31f39b6dc15Shimeng (Simon) Wang    implements View.OnCreateContextMenuListener, DownloadListener {
1300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
13131a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort    /* Define some aliases to make these debugging flags easier to refer to.
13231a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort     * This file imports android.provider.Browser, so we can't just refer to "Browser.DEBUG".
13331a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort     */
13431a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort    private final static boolean DEBUG = com.android.browser.Browser.DEBUG;
13531a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort    private final static boolean LOGV_ENABLED = com.android.browser.Browser.LOGV_ENABLED;
13631a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort    private final static boolean LOGD_ENABLED = com.android.browser.Browser.LOGD_ENABLED;
13731a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort
138565505b1a2c1d3099496af5910760087602e994aSatish Sampath    // These are single-character shortcuts for searching popular sources.
139565505b1a2c1d3099496af5910760087602e994aSatish Sampath    private static final int SHORTCUT_INVALID = 0;
140565505b1a2c1d3099496af5910760087602e994aSatish Sampath    private static final int SHORTCUT_GOOGLE_SEARCH = 1;
141565505b1a2c1d3099496af5910760087602e994aSatish Sampath    private static final int SHORTCUT_WIKIPEDIA_SEARCH = 2;
142565505b1a2c1d3099496af5910760087602e994aSatish Sampath    private static final int SHORTCUT_DICTIONARY_SEARCH = 3;
143565505b1a2c1d3099496af5910760087602e994aSatish Sampath    private static final int SHORTCUT_GOOGLE_MOBILE_LOCAL_SEARCH = 4;
144565505b1a2c1d3099496af5910760087602e994aSatish Sampath
145a977124eb29b195127fd161120ebbc58b255fb48Cary Clark    private static class ClearThumbnails extends AsyncTask<File, Void, Void> {
1460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        @Override
1470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public Void doInBackground(File... files) {
1480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (files != null) {
1490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                for (File f : files) {
150d6be1758b38d5b066ff10b6af906aa66c63670cdCary Clark                    if (!f.delete()) {
151d6be1758b38d5b066ff10b6af906aa66c63670cdCary Clark                      Log.e(LOGTAG, f.getPath() + " was not deleted");
152d6be1758b38d5b066ff10b6af906aa66c63670cdCary Clark                    }
1530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
1540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
1550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return null;
1560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
1570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
1580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
1593bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    /**
1603bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     * This layout holds everything you see below the status bar, including the
1613bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     * error console, the custom view container, and the webviews.
1623bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     */
1633bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    private FrameLayout mBrowserFrameLayout;
16481db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins
165d746a94137a87ffcc1fcefdac9a3764c3bc3f5cdLeon Scroggins    private boolean mXLargeScreenSize;
166d746a94137a87ffcc1fcefdac9a3764c3bc3f5cdLeon Scroggins
16743610292590fe3e2f8d0ddba1adf9e5557c0f401Jeff Davidson    private Boolean mIsProviderPresent = null;
16843610292590fe3e2f8d0ddba1adf9e5557c0f401Jeff Davidson    private Uri mRlzUri = null;
16943610292590fe3e2f8d0ddba1adf9e5557c0f401Jeff Davidson
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
2803d6df16f1c9a64cf2dc5b41a2078f4c49b0c296aElliott Slaughter        // Unless the last browser usage was within 24 hours, destroy any
2813d6df16f1c9a64cf2dc5b41a2078f4c49b0c296aElliott Slaughter        // remaining incognito tabs.
2823d6df16f1c9a64cf2dc5b41a2078f4c49b0c296aElliott Slaughter
2833d6df16f1c9a64cf2dc5b41a2078f4c49b0c296aElliott Slaughter        Calendar lastActiveDate = icicle != null ? (Calendar) icicle.getSerializable("lastActiveDate") : null;
2843d6df16f1c9a64cf2dc5b41a2078f4c49b0c296aElliott Slaughter        Calendar today = Calendar.getInstance();
2853d6df16f1c9a64cf2dc5b41a2078f4c49b0c296aElliott Slaughter        Calendar yesterday = Calendar.getInstance();
2863d6df16f1c9a64cf2dc5b41a2078f4c49b0c296aElliott Slaughter        yesterday.add(Calendar.DATE, -1);
2873d6df16f1c9a64cf2dc5b41a2078f4c49b0c296aElliott Slaughter
2883d6df16f1c9a64cf2dc5b41a2078f4c49b0c296aElliott Slaughter        boolean dontRestoreIncognitoTabs = lastActiveDate == null
2893d6df16f1c9a64cf2dc5b41a2078f4c49b0c296aElliott Slaughter            || lastActiveDate.before(yesterday)
2903d6df16f1c9a64cf2dc5b41a2078f4c49b0c296aElliott Slaughter            || lastActiveDate.after(today);
2913d6df16f1c9a64cf2dc5b41a2078f4c49b0c296aElliott Slaughter
2923d6df16f1c9a64cf2dc5b41a2078f4c49b0c296aElliott Slaughter        if (!mTabControl.restoreState(icicle, dontRestoreIncognitoTabs)) {
2930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // clear up the thumbnail directory if we can't restore the state as
2940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // none of the files in the directory are referenced any more.
2950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            new ClearThumbnails().execute(
2960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    mTabControl.getThumbnailDir().listFiles());
297aab3f09b5c2d39b19067e57635614080b2403a46Grace Kloba            // there is no quit on Android. But if we can't restore the state,
298aab3f09b5c2d39b19067e57635614080b2403a46Grace Kloba            // we can treat it as a new Browser, remove the old session cookies.
299aab3f09b5c2d39b19067e57635614080b2403a46Grace Kloba            CookieManager.getInstance().removeSessionCookie();
3003d6df16f1c9a64cf2dc5b41a2078f4c49b0c296aElliott Slaughter            // remove any incognito files
3013d6df16f1c9a64cf2dc5b41a2078f4c49b0c296aElliott Slaughter            WebView.cleanupPrivateBrowsingFiles(this);
3020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            final Intent intent = getIntent();
3030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            final Bundle extra = intent.getExtras();
3040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Create an initial tab.
3050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // If the intent is ACTION_VIEW and data is not null, the Browser is
3060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // invoked to view the content by another application. In this case,
3070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // the tab will be close when exit.
30825ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima            UrlData urlData = getUrlDataFromIntent(intent);
30925ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima
31058d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins            String action = intent.getAction();
31122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            final Tab t = mTabControl.createNewTab(
31258d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins                    (Intent.ACTION_VIEW.equals(action) &&
31358d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins                    intent.getData() != null)
314a1cc3fdce19a336c251297c61cd83ac6cf767cd1Leon Scroggins                    || RecognizerResultsIntent.ACTION_VOICE_SEARCH_RESULTS
315a1cc3fdce19a336c251297c61cd83ac6cf767cd1Leon Scroggins                    .equals(action),
316f0f03954b3092296c58dcb040e2dabd1696dd5c4Elliott Slaughter                    intent.getStringExtra(Browser.EXTRA_APPLICATION_ID),
317f0f03954b3092296c58dcb040e2dabd1696dd5c4Elliott Slaughter                    urlData.mUrl, false);
3180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mTabControl.setCurrentTab(t);
3190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            attachTabToContentView(t);
3200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            WebView webView = t.getWebView();
3210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (extra != null) {
3220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                int scale = extra.getInt(Browser.INITIAL_ZOOM_LEVEL, 0);
3230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (scale > 0 && scale <= 1000) {
3240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    webView.setInitialScale(scale);
3250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
3260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
3270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
32825ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima            if (urlData.isEmpty()) {
32998d5fce7c687cfcc956b10d44946d31f39b6dc15Shimeng (Simon) Wang                loadUrl(webView, mSettings.getHomePage());
3300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } else {
3319d53da05812f959745810a33bb4e06b273393c42Patrick Scott                loadUrlDataIn(t, urlData);
3320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
3330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
3343d6df16f1c9a64cf2dc5b41a2078f4c49b0c296aElliott Slaughter            if (dontRestoreIncognitoTabs) {
3353d6df16f1c9a64cf2dc5b41a2078f4c49b0c296aElliott Slaughter                WebView.cleanupPrivateBrowsingFiles(this);
3363d6df16f1c9a64cf2dc5b41a2078f4c49b0c296aElliott Slaughter            }
3373d6df16f1c9a64cf2dc5b41a2078f4c49b0c296aElliott Slaughter
3380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // TabControl.restoreState() will create a new tab even if
3391f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins            // restoring the state fails.
3400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            attachTabToContentView(mTabControl.getCurrentTab());
3410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
342615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba
343b4b83182219908210d4554466367736692faf6ceCary Clark        // Delete old thumbnails to save space
344b4b83182219908210d4554466367736692faf6ceCary Clark        File dir = mTabControl.getThumbnailDir();
345b4b83182219908210d4554466367736692faf6ceCary Clark        if (dir.exists()) {
346b4b83182219908210d4554466367736692faf6ceCary Clark            for (String child : dir.list()) {
347b4b83182219908210d4554466367736692faf6ceCary Clark                File f = new File(dir, child);
348b4b83182219908210d4554466367736692faf6ceCary Clark                f.delete();
349b4b83182219908210d4554466367736692faf6ceCary Clark            }
350b4b83182219908210d4554466367736692faf6ceCary Clark        }
351b4b83182219908210d4554466367736692faf6ceCary Clark
352b3c02da4553b1a629b16377970fdabae28394c94Feng Qian        // Read JavaScript flags if it exists.
353b3c02da4553b1a629b16377970fdabae28394c94Feng Qian        String jsFlags = mSettings.getJsFlags();
354b3c02da4553b1a629b16377970fdabae28394c94Feng Qian        if (jsFlags.trim().length() != 0) {
355b3c02da4553b1a629b16377970fdabae28394c94Feng Qian            mTabControl.getCurrentWebView().setJsFlags(jsFlags);
356b3c02da4553b1a629b16377970fdabae28394c94Feng Qian        }
357a7611811e0d744a7220b7bf80c8f795af5ea53edBjorn Bringert
358a7611811e0d744a7220b7bf80c8f795af5ea53edBjorn Bringert        // Start watching the default geolocation permissions
359a7611811e0d744a7220b7bf80c8f795af5ea53edBjorn Bringert        mSystemAllowGeolocationOrigins
360a7611811e0d744a7220b7bf80c8f795af5ea53edBjorn Bringert                = new SystemAllowGeolocationOrigins(getApplicationContext());
361a7611811e0d744a7220b7bf80c8f795af5ea53edBjorn Bringert        mSystemAllowGeolocationOrigins.start();
3620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
3630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
364a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb    ScrollListener getScrollListener() {
365a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb        return mTabBar;
366a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb    }
367a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb
36858d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    /**
36958d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins     * Feed the previously stored results strings to the BrowserProvider so that
37058d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins     * the SearchDialog will show them instead of the standard searches.
37158d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins     * @param result String to show on the editable line of the SearchDialog.
37258d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins     */
37358d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    /* package */ void showVoiceSearchResults(String result) {
37458d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        ContentProviderClient client = mResolver.acquireContentProviderClient(
37558d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins                Browser.BOOKMARKS_URI);
37658d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        ContentProvider prov = client.getLocalContentProvider();
37758d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        BrowserProvider bp = (BrowserProvider) prov;
37858d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        bp.setQueryResults(mTabControl.getCurrentTab().getVoiceSearchResults());
37958d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        client.release();
38058d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins
381fbb3f15f725e890837431f402b43e802045a4f3fLeon Scroggins        Bundle bundle = createGoogleSearchSourceBundle(
382fbb3f15f725e890837431f402b43e802045a4f3fLeon Scroggins                GOOGLE_SEARCH_SOURCE_SEARCHKEY);
383fbb3f15f725e890837431f402b43e802045a4f3fLeon Scroggins        bundle.putBoolean(SearchManager.CONTEXT_IS_VOICE, true);
384fbb3f15f725e890837431f402b43e802045a4f3fLeon Scroggins        startSearch(result, false, bundle, false);
38558d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    }
38658d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins
3870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    @Override
3880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    protected void onNewIntent(Intent intent) {
38922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        Tab current = mTabControl.getCurrentTab();
3900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // When a tab is closed on exit, the current tab index is set to -1.
3910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Reset before proceed as Browser requires the current tab to be set.
3920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (current == null) {
3930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Try to reset the tab in case the index was incorrect.
3940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            current = mTabControl.getTab(0);
3950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (current == null) {
3960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // No tabs at all so just ignore this intent.
3970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                return;
3980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
3990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mTabControl.setCurrentTab(current);
4000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            attachTabToContentView(current);
4010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            resetTitleAndIcon(current.getWebView());
4020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
4030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final String action = intent.getAction();
4040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final int flags = intent.getFlags();
4050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (Intent.ACTION_MAIN.equals(action) ||
4060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                (flags & Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY) != 0) {
4070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // just resume the browser
4080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
4090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
410b8a844da0049965b3cef5739dbab19c7ac766762Leon Scroggins        // In case the SearchDialog is open.
411b8a844da0049965b3cef5739dbab19c7ac766762Leon Scroggins        ((SearchManager) getSystemService(Context.SEARCH_SERVICE))
412b8a844da0049965b3cef5739dbab19c7ac766762Leon Scroggins                .stopSearch();
413a1cc3fdce19a336c251297c61cd83ac6cf767cd1Leon Scroggins        boolean activateVoiceSearch = RecognizerResultsIntent
414a1cc3fdce19a336c251297c61cd83ac6cf767cd1Leon Scroggins                .ACTION_VOICE_SEARCH_RESULTS.equals(action);
4150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (Intent.ACTION_VIEW.equals(action)
4160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                || Intent.ACTION_SEARCH.equals(action)
4170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                || MediaStore.INTENT_ACTION_MEDIA_SEARCH.equals(action)
41858d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins                || Intent.ACTION_WEB_SEARCH.equals(action)
41958d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins                || activateVoiceSearch) {
4203b18ce37c13fce7212948df90a012d7011924a6eLeon Scroggins            if (current.isInVoiceSearchMode()) {
4213b18ce37c13fce7212948df90a012d7011924a6eLeon Scroggins                String title = current.getVoiceDisplayTitle();
4223b18ce37c13fce7212948df90a012d7011924a6eLeon Scroggins                if (title != null && title.equals(intent.getStringExtra(
4233b18ce37c13fce7212948df90a012d7011924a6eLeon Scroggins                        SearchManager.QUERY))) {
4243b18ce37c13fce7212948df90a012d7011924a6eLeon Scroggins                    // The user submitted the same search as the last voice
4253b18ce37c13fce7212948df90a012d7011924a6eLeon Scroggins                    // search, so do nothing.
4263b18ce37c13fce7212948df90a012d7011924a6eLeon Scroggins                    return;
4273b18ce37c13fce7212948df90a012d7011924a6eLeon Scroggins                }
4281fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins                if (Intent.ACTION_SEARCH.equals(action)
4291fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins                        && current.voiceSearchSourceIsGoogle()) {
4301fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins                    Intent logIntent = new Intent(
4311fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins                            LoggingEvents.ACTION_LOG_EVENT);
4321fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins                    logIntent.putExtra(LoggingEvents.EXTRA_EVENT,
4331fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins                            LoggingEvents.VoiceSearch.QUERY_UPDATED);
4341fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins                    logIntent.putExtra(
4351fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins                            LoggingEvents.VoiceSearch.EXTRA_QUERY_UPDATED_VALUE,
4361fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins                            intent.getDataString());
4371fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins                    sendBroadcast(logIntent);
4381fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins                    // Note, onPageStarted will revert the voice title bar
4391fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins                    // When http://b/issue?id=2379215 is fixed, we should update
4401fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins                    // the title bar here.
4411fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins                }
4423b18ce37c13fce7212948df90a012d7011924a6eLeon Scroggins            }
443565505b1a2c1d3099496af5910760087602e994aSatish Sampath            // If this was a search request (e.g. search query directly typed into the address bar),
444565505b1a2c1d3099496af5910760087602e994aSatish Sampath            // pass it on to the default web search provider.
445565505b1a2c1d3099496af5910760087602e994aSatish Sampath            if (handleWebSearchIntent(intent)) {
446565505b1a2c1d3099496af5910760087602e994aSatish Sampath                return;
447565505b1a2c1d3099496af5910760087602e994aSatish Sampath            }
448565505b1a2c1d3099496af5910760087602e994aSatish Sampath
44925ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima            UrlData urlData = getUrlDataFromIntent(intent);
45025ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima            if (urlData.isEmpty()) {
45125ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima                urlData = new UrlData(mSettings.getHomePage());
4520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
45325ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima
454cc63403643786905262f505ab5266d8e80b9924cGrace Kloba            final String appId = intent
455cc63403643786905262f505ab5266d8e80b9924cGrace Kloba                    .getStringExtra(Browser.EXTRA_APPLICATION_ID);
4564720868afa09efffadd845019f2d8268ae3f2c78Leon Scroggins            if ((Intent.ACTION_VIEW.equals(action)
4574720868afa09efffadd845019f2d8268ae3f2c78Leon Scroggins                    // If a voice search has no appId, it means that it came
4584720868afa09efffadd845019f2d8268ae3f2c78Leon Scroggins                    // from the browser.  In that case, reuse the current tab.
4594720868afa09efffadd845019f2d8268ae3f2c78Leon Scroggins                    || (activateVoiceSearch && appId != null))
460cc63403643786905262f505ab5266d8e80b9924cGrace Kloba                    && !getPackageName().equals(appId)
461cc63403643786905262f505ab5266d8e80b9924cGrace Kloba                    && (flags & Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT) != 0) {
46222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                Tab appTab = mTabControl.getTabFromId(appId);
463f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                if (appTab != null) {
464f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    Log.i(LOGTAG, "Reusing tab for " + appId);
465f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    // Dismiss the subwindow if applicable.
466f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    dismissSubWindow(appTab);
467f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    // Since we might kill the WebView, remove it from the
468f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    // content view first.
469f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    removeTabFromContentView(appTab);
470f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    // Recreate the main WebView after destroying the old one.
471f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    // If the WebView has the same original url and is on that
472f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    // page, it can be reused.
473f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    boolean needsLoad =
4746eac63e78d43d04e31c4d16830c44c4d9df82639Leon Scroggins                            mTabControl.recreateWebView(appTab, urlData);
475bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch
476f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    if (current != appTab) {
4771f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                        switchToTab(mTabControl.getTabIndex(appTab));
4781f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                        if (needsLoad) {
4799d53da05812f959745810a33bb4e06b273393c42Patrick Scott                            loadUrlDataIn(appTab, urlData);
4801f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                        }
481f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    } else {
4821f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                        // If the tab was the current tab, we have to attach
4831f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                        // it to the view system again.
4841f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                        attachTabToContentView(appTab);
4851f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                        if (needsLoad) {
4869d53da05812f959745810a33bb4e06b273393c42Patrick Scott                            loadUrlDataIn(appTab, urlData);
487f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                        }
488f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    }
489f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    return;
490cd11589fc3930906d4b9b7dd18aa52a9f1eb0c8aPatrick Scott                } else {
491cd11589fc3930906d4b9b7dd18aa52a9f1eb0c8aPatrick Scott                    // No matching application tab, try to find a regular tab
492cd11589fc3930906d4b9b7dd18aa52a9f1eb0c8aPatrick Scott                    // with a matching url.
493cd11589fc3930906d4b9b7dd18aa52a9f1eb0c8aPatrick Scott                    appTab = mTabControl.findUnusedTabWithUrl(urlData.mUrl);
49425515f8bd458a2471d13d876cfb0e18d8ff2a00fLeon Scroggins                    if (appTab != null) {
49525515f8bd458a2471d13d876cfb0e18d8ff2a00fLeon Scroggins                        if (current != appTab) {
49625515f8bd458a2471d13d876cfb0e18d8ff2a00fLeon Scroggins                            switchToTab(mTabControl.getTabIndex(appTab));
49725515f8bd458a2471d13d876cfb0e18d8ff2a00fLeon Scroggins                        }
49825515f8bd458a2471d13d876cfb0e18d8ff2a00fLeon Scroggins                        // Otherwise, we are already viewing the correct tab.
499cd11589fc3930906d4b9b7dd18aa52a9f1eb0c8aPatrick Scott                    } else {
500cd11589fc3930906d4b9b7dd18aa52a9f1eb0c8aPatrick Scott                        // if FLAG_ACTIVITY_BROUGHT_TO_FRONT flag is on, the url
501cd11589fc3930906d4b9b7dd18aa52a9f1eb0c8aPatrick Scott                        // will be opened in a new tab unless we have reached
502cd11589fc3930906d4b9b7dd18aa52a9f1eb0c8aPatrick Scott                        // MAX_TABS. Then the url will be opened in the current
503cd11589fc3930906d4b9b7dd18aa52a9f1eb0c8aPatrick Scott                        // tab. If a new tab is created, it will have "true" for
504cd11589fc3930906d4b9b7dd18aa52a9f1eb0c8aPatrick Scott                        // exit on close.
5051f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                        openTabAndShow(urlData, true, appId);
506cd11589fc3930906d4b9b7dd18aa52a9f1eb0c8aPatrick Scott                    }
507f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                }
5080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } else {
509638d3f45791a31d0b290e180b93bad49576eb6d3Grace Kloba                if (!urlData.isEmpty()
510638d3f45791a31d0b290e180b93bad49576eb6d3Grace Kloba                        && urlData.mUrl.startsWith("about:debug")) {
511638d3f45791a31d0b290e180b93bad49576eb6d3Grace Kloba                    if ("about:debug.dom".equals(urlData.mUrl)) {
512638d3f45791a31d0b290e180b93bad49576eb6d3Grace Kloba                        current.getWebView().dumpDomTree(false);
513638d3f45791a31d0b290e180b93bad49576eb6d3Grace Kloba                    } else if ("about:debug.dom.file".equals(urlData.mUrl)) {
514638d3f45791a31d0b290e180b93bad49576eb6d3Grace Kloba                        current.getWebView().dumpDomTree(true);
515638d3f45791a31d0b290e180b93bad49576eb6d3Grace Kloba                    } else if ("about:debug.render".equals(urlData.mUrl)) {
516638d3f45791a31d0b290e180b93bad49576eb6d3Grace Kloba                        current.getWebView().dumpRenderTree(false);
517638d3f45791a31d0b290e180b93bad49576eb6d3Grace Kloba                    } else if ("about:debug.render.file".equals(urlData.mUrl)) {
518638d3f45791a31d0b290e180b93bad49576eb6d3Grace Kloba                        current.getWebView().dumpRenderTree(true);
519638d3f45791a31d0b290e180b93bad49576eb6d3Grace Kloba                    } else if ("about:debug.display".equals(urlData.mUrl)) {
520638d3f45791a31d0b290e180b93bad49576eb6d3Grace Kloba                        current.getWebView().dumpDisplayTree();
5219b78e1d1e0bd819ae03df5594d4a56519e5d87c7Mike Reed                    } else if (urlData.mUrl.startsWith("about:debug.drag")) {
5229b78e1d1e0bd819ae03df5594d4a56519e5d87c7Mike Reed                        int index = urlData.mUrl.codePointAt(16) - '0';
5239b78e1d1e0bd819ae03df5594d4a56519e5d87c7Mike Reed                        if (index <= 0 || index > 9) {
5249b78e1d1e0bd819ae03df5594d4a56519e5d87c7Mike Reed                            current.getWebView().setDragTracker(null);
5259b78e1d1e0bd819ae03df5594d4a56519e5d87c7Mike Reed                        } else {
5269b78e1d1e0bd819ae03df5594d4a56519e5d87c7Mike Reed                            current.getWebView().setDragTracker(new MeshTracker(index));
5279b78e1d1e0bd819ae03df5594d4a56519e5d87c7Mike Reed                        }
528638d3f45791a31d0b290e180b93bad49576eb6d3Grace Kloba                    } else {
529638d3f45791a31d0b290e180b93bad49576eb6d3Grace Kloba                        mSettings.toggleDebugSettings();
530638d3f45791a31d0b290e180b93bad49576eb6d3Grace Kloba                    }
5310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    return;
5320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
5331f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                // Get rid of the subwindow if it exists
5341f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                dismissSubWindow(current);
5358588d15a7c0b87049469fd80f9c53eb274cd837bLeon Scroggins                // If the current Tab is being used as an application tab,
5368588d15a7c0b87049469fd80f9c53eb274cd837bLeon Scroggins                // remove the association, since the new Intent means that it is
5378588d15a7c0b87049469fd80f9c53eb274cd837bLeon Scroggins                // no longer associated with that application.
5388588d15a7c0b87049469fd80f9c53eb274cd837bLeon Scroggins                current.setAppId(null);
5399d53da05812f959745810a33bb4e06b273393c42Patrick Scott                loadUrlDataIn(current, urlData);
5400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
5410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
5420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
5430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
544565505b1a2c1d3099496af5910760087602e994aSatish Sampath    private int parseUrlShortcut(String url) {
545565505b1a2c1d3099496af5910760087602e994aSatish Sampath        if (url == null) return SHORTCUT_INVALID;
546565505b1a2c1d3099496af5910760087602e994aSatish Sampath
547565505b1a2c1d3099496af5910760087602e994aSatish Sampath        // FIXME: quick search, need to be customized by setting
548565505b1a2c1d3099496af5910760087602e994aSatish Sampath        if (url.length() > 2 && url.charAt(1) == ' ') {
549565505b1a2c1d3099496af5910760087602e994aSatish Sampath            switch (url.charAt(0)) {
550565505b1a2c1d3099496af5910760087602e994aSatish Sampath            case 'g': return SHORTCUT_GOOGLE_SEARCH;
551565505b1a2c1d3099496af5910760087602e994aSatish Sampath            case 'w': return SHORTCUT_WIKIPEDIA_SEARCH;
552565505b1a2c1d3099496af5910760087602e994aSatish Sampath            case 'd': return SHORTCUT_DICTIONARY_SEARCH;
553565505b1a2c1d3099496af5910760087602e994aSatish Sampath            case 'l': return SHORTCUT_GOOGLE_MOBILE_LOCAL_SEARCH;
554565505b1a2c1d3099496af5910760087602e994aSatish Sampath            }
555565505b1a2c1d3099496af5910760087602e994aSatish Sampath        }
556565505b1a2c1d3099496af5910760087602e994aSatish Sampath        return SHORTCUT_INVALID;
557565505b1a2c1d3099496af5910760087602e994aSatish Sampath    }
558565505b1a2c1d3099496af5910760087602e994aSatish Sampath
559565505b1a2c1d3099496af5910760087602e994aSatish Sampath    /**
560565505b1a2c1d3099496af5910760087602e994aSatish Sampath     * Launches the default web search activity with the query parameters if the given intent's data
561565505b1a2c1d3099496af5910760087602e994aSatish Sampath     * are identified as plain search terms and not URLs/shortcuts.
562565505b1a2c1d3099496af5910760087602e994aSatish Sampath     * @return true if the intent was handled and web search activity was launched, false if not.
563565505b1a2c1d3099496af5910760087602e994aSatish Sampath     */
564565505b1a2c1d3099496af5910760087602e994aSatish Sampath    private boolean handleWebSearchIntent(Intent intent) {
565565505b1a2c1d3099496af5910760087602e994aSatish Sampath        if (intent == null) return false;
566565505b1a2c1d3099496af5910760087602e994aSatish Sampath
567565505b1a2c1d3099496af5910760087602e994aSatish Sampath        String url = null;
568565505b1a2c1d3099496af5910760087602e994aSatish Sampath        final String action = intent.getAction();
569a1cc3fdce19a336c251297c61cd83ac6cf767cd1Leon Scroggins        if (RecognizerResultsIntent.ACTION_VOICE_SEARCH_RESULTS.equals(
570a1cc3fdce19a336c251297c61cd83ac6cf767cd1Leon Scroggins                action)) {
57158d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins            return false;
57258d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        }
573565505b1a2c1d3099496af5910760087602e994aSatish Sampath        if (Intent.ACTION_VIEW.equals(action)) {
5741e70505659dd9bf0f7e03bce787ba880f9b7a8aaGrace Kloba            Uri data = intent.getData();
5751e70505659dd9bf0f7e03bce787ba880f9b7a8aaGrace Kloba            if (data != null) url = data.toString();
576565505b1a2c1d3099496af5910760087602e994aSatish Sampath        } else if (Intent.ACTION_SEARCH.equals(action)
577565505b1a2c1d3099496af5910760087602e994aSatish Sampath                || MediaStore.INTENT_ACTION_MEDIA_SEARCH.equals(action)
578565505b1a2c1d3099496af5910760087602e994aSatish Sampath                || Intent.ACTION_WEB_SEARCH.equals(action)) {
579565505b1a2c1d3099496af5910760087602e994aSatish Sampath            url = intent.getStringExtra(SearchManager.QUERY);
580565505b1a2c1d3099496af5910760087602e994aSatish Sampath        }
5810485170e03e079eb61b9dd52fc2c98da02fa7b2cBjorn Bringert        return handleWebSearchRequest(url, intent.getBundleExtra(SearchManager.APP_DATA),
5820485170e03e079eb61b9dd52fc2c98da02fa7b2cBjorn Bringert                intent.getStringExtra(SearchManager.EXTRA_DATA_KEY));
583565505b1a2c1d3099496af5910760087602e994aSatish Sampath    }
584565505b1a2c1d3099496af5910760087602e994aSatish Sampath
585565505b1a2c1d3099496af5910760087602e994aSatish Sampath    /**
586565505b1a2c1d3099496af5910760087602e994aSatish Sampath     * Launches the default web search activity with the query parameters if the given url string
587565505b1a2c1d3099496af5910760087602e994aSatish Sampath     * was identified as plain search terms and not URL/shortcut.
588565505b1a2c1d3099496af5910760087602e994aSatish Sampath     * @return true if the request was handled and web search activity was launched, false if not.
589565505b1a2c1d3099496af5910760087602e994aSatish Sampath     */
5900485170e03e079eb61b9dd52fc2c98da02fa7b2cBjorn Bringert    private boolean handleWebSearchRequest(String inUrl, Bundle appData, String extraData) {
591565505b1a2c1d3099496af5910760087602e994aSatish Sampath        if (inUrl == null) return false;
592565505b1a2c1d3099496af5910760087602e994aSatish Sampath
593565505b1a2c1d3099496af5910760087602e994aSatish Sampath        // In general, we shouldn't modify URL from Intent.
594565505b1a2c1d3099496af5910760087602e994aSatish Sampath        // But currently, we get the user-typed URL from search box as well.
595565505b1a2c1d3099496af5910760087602e994aSatish Sampath        String url = fixUrl(inUrl).trim();
596565505b1a2c1d3099496af5910760087602e994aSatish Sampath
597565505b1a2c1d3099496af5910760087602e994aSatish Sampath        // URLs and site specific search shortcuts are handled by the regular flow of control, so
598565505b1a2c1d3099496af5910760087602e994aSatish Sampath        // return early.
5995ee906c089567bca705e18561357510d7b55cb5aDan Egnor        if (Patterns.WEB_URL.matcher(url).matches()
600bc5b9f358a2b75bf3a104b9f5cd477ad2f6f740fSatish Sampath                || ACCEPTED_URI_SCHEMA.matcher(url).matches()
601565505b1a2c1d3099496af5910760087602e994aSatish Sampath                || parseUrlShortcut(url) != SHORTCUT_INVALID) {
602565505b1a2c1d3099496af5910760087602e994aSatish Sampath            return false;
603565505b1a2c1d3099496af5910760087602e994aSatish Sampath        }
604565505b1a2c1d3099496af5910760087602e994aSatish Sampath
6058d06e36fe80f516e04ad33ff8b446720e36cabfdLeon Scroggins        final ContentResolver cr = mResolver;
6068d06e36fe80f516e04ad33ff8b446720e36cabfdLeon Scroggins        final String newUrl = url;
607627d96f1564e9f95d8258958b35467057ff4c6b8Elliott Slaughter        if (mTabControl == null || !mTabControl.getCurrentWebView().isPrivateBrowsingEnabled()) {
608f0f03954b3092296c58dcb040e2dabd1696dd5c4Elliott Slaughter            new AsyncTask<Void, Void, Void>() {
609f0f03954b3092296c58dcb040e2dabd1696dd5c4Elliott Slaughter                @Override
610f0f03954b3092296c58dcb040e2dabd1696dd5c4Elliott Slaughter                protected Void doInBackground(Void... unused) {
611f0f03954b3092296c58dcb040e2dabd1696dd5c4Elliott Slaughter                        Browser.updateVisitedHistory(cr, newUrl, false);
612f0f03954b3092296c58dcb040e2dabd1696dd5c4Elliott Slaughter                        Browser.addSearchUrl(cr, newUrl);
613f0f03954b3092296c58dcb040e2dabd1696dd5c4Elliott Slaughter                    return null;
614f0f03954b3092296c58dcb040e2dabd1696dd5c4Elliott Slaughter                }
615f0f03954b3092296c58dcb040e2dabd1696dd5c4Elliott Slaughter            }.execute();
616f0f03954b3092296c58dcb040e2dabd1696dd5c4Elliott Slaughter        }
617565505b1a2c1d3099496af5910760087602e994aSatish Sampath
618565505b1a2c1d3099496af5910760087602e994aSatish Sampath        Intent intent = new Intent(Intent.ACTION_WEB_SEARCH);
619565505b1a2c1d3099496af5910760087602e994aSatish Sampath        intent.addCategory(Intent.CATEGORY_DEFAULT);
620565505b1a2c1d3099496af5910760087602e994aSatish Sampath        intent.putExtra(SearchManager.QUERY, url);
62115e9f2dc92cf1621f95071b3c740f46079aa0f3bSatish Sampath        if (appData != null) {
62215e9f2dc92cf1621f95071b3c740f46079aa0f3bSatish Sampath            intent.putExtra(SearchManager.APP_DATA, appData);
62315e9f2dc92cf1621f95071b3c740f46079aa0f3bSatish Sampath        }
6240485170e03e079eb61b9dd52fc2c98da02fa7b2cBjorn Bringert        if (extraData != null) {
6250485170e03e079eb61b9dd52fc2c98da02fa7b2cBjorn Bringert            intent.putExtra(SearchManager.EXTRA_DATA_KEY, extraData);
6260485170e03e079eb61b9dd52fc2c98da02fa7b2cBjorn Bringert        }
627cc63403643786905262f505ab5266d8e80b9924cGrace Kloba        intent.putExtra(Browser.EXTRA_APPLICATION_ID, getPackageName());
628552751ea92828f8b78b71533dbba70aa7c316d9dMattias Falk
629552751ea92828f8b78b71533dbba70aa7c316d9dMattias Falk        // can't be sure there is an activity for the Intent
630552751ea92828f8b78b71533dbba70aa7c316d9dMattias Falk        try {
631552751ea92828f8b78b71533dbba70aa7c316d9dMattias Falk            startActivity(intent);
632552751ea92828f8b78b71533dbba70aa7c316d9dMattias Falk        } catch (ActivityNotFoundException ex) {
633552751ea92828f8b78b71533dbba70aa7c316d9dMattias Falk            return false;
634552751ea92828f8b78b71533dbba70aa7c316d9dMattias Falk        }
635565505b1a2c1d3099496af5910760087602e994aSatish Sampath
636565505b1a2c1d3099496af5910760087602e994aSatish Sampath        return true;
637565505b1a2c1d3099496af5910760087602e994aSatish Sampath    }
638565505b1a2c1d3099496af5910760087602e994aSatish Sampath
63925ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima    private UrlData getUrlDataFromIntent(Intent intent) {
64058d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        String url = "";
641068e48b469f5abca53ee3da38f933cf2c25c93b8Grace Kloba        Map<String, String> headers = null;
6420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (intent != null) {
6430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            final String action = intent.getAction();
6440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (Intent.ACTION_VIEW.equals(action)) {
6450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                url = smartUrlFilter(intent.getData());
6460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (url != null && url.startsWith("content:")) {
6470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    /* Append mimetype so webview knows how to display */
6480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    String mimeType = intent.resolveType(getContentResolver());
6490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    if (mimeType != null) {
6500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        url += "?" + mimeType;
6510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
6520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
653068e48b469f5abca53ee3da38f933cf2c25c93b8Grace Kloba                if (url != null && url.startsWith("http")) {
65400f54c589fd38431efd42ea2a551a49e64d595d5Grace Kloba                    final Bundle pairs = intent
65500f54c589fd38431efd42ea2a551a49e64d595d5Grace Kloba                            .getBundleExtra(Browser.EXTRA_HEADERS);
6562d508edbf54ea74cd4e89be8b622b1cbd587464aGrace Kloba                    if (pairs != null && !pairs.isEmpty()) {
65700f54c589fd38431efd42ea2a551a49e64d595d5Grace Kloba                        Iterator<String> iter = pairs.keySet().iterator();
658068e48b469f5abca53ee3da38f933cf2c25c93b8Grace Kloba                        headers = new HashMap<String, String>();
65900f54c589fd38431efd42ea2a551a49e64d595d5Grace Kloba                        while (iter.hasNext()) {
66000f54c589fd38431efd42ea2a551a49e64d595d5Grace Kloba                            String key = iter.next();
66100f54c589fd38431efd42ea2a551a49e64d595d5Grace Kloba                            headers.put(key, pairs.getString(key));
662068e48b469f5abca53ee3da38f933cf2c25c93b8Grace Kloba                        }
663068e48b469f5abca53ee3da38f933cf2c25c93b8Grace Kloba                    }
66425ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima                }
6650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } else if (Intent.ACTION_SEARCH.equals(action)
6660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    || MediaStore.INTENT_ACTION_MEDIA_SEARCH.equals(action)
6670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    || Intent.ACTION_WEB_SEARCH.equals(action)) {
6680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                url = intent.getStringExtra(SearchManager.QUERY);
6690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (url != null) {
6700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    mLastEnteredUrl = url;
6710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // In general, we shouldn't modify URL from Intent.
6720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // But currently, we get the user-typed URL from search box as well.
6730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    url = fixUrl(url);
6740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    url = smartUrlFilter(url);
6758d06e36fe80f516e04ad33ff8b446720e36cabfdLeon Scroggins                    final ContentResolver cr = mResolver;
6768d06e36fe80f516e04ad33ff8b446720e36cabfdLeon Scroggins                    final String newUrl = url;
6778389e996e600cf51d85fa29b4de12f69e34ccd2dElliott Slaughter                    if (mTabControl == null
6788389e996e600cf51d85fa29b4de12f69e34ccd2dElliott Slaughter                            || mTabControl.getCurrentWebView() == null
6798389e996e600cf51d85fa29b4de12f69e34ccd2dElliott Slaughter                            || !mTabControl.getCurrentWebView().isPrivateBrowsingEnabled()) {
6808389e996e600cf51d85fa29b4de12f69e34ccd2dElliott Slaughter                        new AsyncTask<Void, Void, Void>() {
6818389e996e600cf51d85fa29b4de12f69e34ccd2dElliott Slaughter                            @Override
6828389e996e600cf51d85fa29b4de12f69e34ccd2dElliott Slaughter                            protected Void doInBackground(Void... unused) {
6838389e996e600cf51d85fa29b4de12f69e34ccd2dElliott Slaughter                                Browser.updateVisitedHistory(cr, newUrl, false);
6848389e996e600cf51d85fa29b4de12f69e34ccd2dElliott Slaughter                                return null;
6858389e996e600cf51d85fa29b4de12f69e34ccd2dElliott Slaughter                            }
6868389e996e600cf51d85fa29b4de12f69e34ccd2dElliott Slaughter                        }.execute();
6878389e996e600cf51d85fa29b4de12f69e34ccd2dElliott Slaughter                    }
6880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    String searchSource = "&source=android-" + GOOGLE_SEARCH_SOURCE_SUGGEST + "&";
6890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    if (url.contains(searchSource)) {
6900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        String source = null;
6910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        final Bundle appData = intent.getBundleExtra(SearchManager.APP_DATA);
6920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        if (appData != null) {
69310d1cca0c208d1f9db23893a8515685e04cfe224Bjorn Bringert                            source = appData.getString(Search.SOURCE);
6940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }
6950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        if (TextUtils.isEmpty(source)) {
6960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            source = GOOGLE_SEARCH_SOURCE_UNKNOWN;
6970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }
6980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        url = url.replace(searchSource, "&source=android-"+source+"&");
6990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
7000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
7010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
7020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
70358d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        return new UrlData(url, headers, intent);
7040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
70558d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    /* package */ void showVoiceTitleBar(String title) {
70658d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        mTitleBar.setInVoiceMode(true);
70758d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        mTitleBar.setDisplayTitle(title);
708a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb        mFakeTitleBar.setInVoiceMode(true);
709a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb        mFakeTitleBar.setDisplayTitle(title);
71058d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    }
71158d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    /* package */ void revertVoiceTitleBar() {
71258d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        mTitleBar.setInVoiceMode(false);
713003a5ddf3a7ff1b30bfd82cddc8da49cb9fedf15Leon Scroggins        mTitleBar.setDisplayTitle(mUrl);
714a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb        mFakeTitleBar.setInVoiceMode(false);
715a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb        mFakeTitleBar.setDisplayTitle(mUrl);
71658d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    }
7170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /* package */ static String fixUrl(String inUrl) {
718652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark        // FIXME: Converting the url to lower case
719652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark        // duplicates functionality in smartUrlFilter().
720652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark        // However, changing all current callers of fixUrl to
721652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark        // call smartUrlFilter in addition may have unwanted
722652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark        // consequences, and is deferred for now.
723652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark        int colon = inUrl.indexOf(':');
724652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark        boolean allLower = true;
725652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark        for (int index = 0; index < colon; index++) {
726652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark            char ch = inUrl.charAt(index);
727652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark            if (!Character.isLetter(ch)) {
728652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark                break;
729652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark            }
730652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark            allLower &= Character.isLowerCase(ch);
731652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark            if (index == colon - 1 && !allLower) {
732652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark                inUrl = inUrl.substring(0, colon).toLowerCase()
733652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark                        + inUrl.substring(colon);
734652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark            }
735652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark        }
7360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (inUrl.startsWith("http://") || inUrl.startsWith("https://"))
7370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return inUrl;
7380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (inUrl.startsWith("http:") ||
7390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                inUrl.startsWith("https:")) {
7400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (inUrl.startsWith("http:/") || inUrl.startsWith("https:/")) {
7410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                inUrl = inUrl.replaceFirst("/", "//");
7420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } else inUrl = inUrl.replaceFirst(":", "://");
7430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
7440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return inUrl;
7450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
7460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
74722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    @Override
74822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    protected void onResume() {
7490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        super.onResume();
75031a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort        if (LOGV_ENABLED) {
7510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Log.v(LOGTAG, "BrowserActivity.onResume: this=" + this);
7520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
7530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
7540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (!mActivityInPause) {
7550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Log.e(LOGTAG, "BrowserActivity is already resumed.");
7560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
7570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
7580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
7597bfa63b55644fbf2da1fe6a24b3be0267529202cMike Reed        mTabControl.resumeCurrentTab();
7600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mActivityInPause = false;
7617bfa63b55644fbf2da1fe6a24b3be0267529202cMike Reed        resumeWebViewTimers();
7620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
7630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mWakeLock.isHeld()) {
7640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mHandler.removeMessages(RELEASE_WAKELOCK);
7650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mWakeLock.release();
7660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
7670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
7680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        registerReceiver(mNetworkStateIntentReceiver,
7690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                         mNetworkStateChangedFilter);
7700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebView.enablePlatformNotifications();
7710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
7720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
7733bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    /**
7743bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     * Since the actual title bar is embedded in the WebView, and removing it
775fe87bd3a3897e4bad65bb3d284659ae2f4e57570Leon Scroggins     * would change its appearance, use a different TitleBar to show overlayed
776fe87bd3a3897e4bad65bb3d284659ae2f4e57570Leon Scroggins     * at the top of the screen, when the menu is open or the page is loading.
7773bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     */
778a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb    private TitleBarBase mFakeTitleBar;
7793bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins
7803bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    /**
7813bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     * Keeps track of whether the options menu is open.  This is important in
7823bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     * determining whether to show or hide the title bar overlay.
7833bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     */
7843bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    private boolean mOptionsMenuOpen;
7853bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins
7863bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    /**
7873bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     * Only meaningful when mOptionsMenuOpen is true.  This variable keeps track
7883bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     * of whether the configuration has changed.  The first onMenuOpened call
7893bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     * after a configuration change is simply a reopening of the same menu
7903bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     * (i.e. mIconView did not change).
7913bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     */
7923bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    private boolean mConfigChanged;
7933bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins
7943bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    /**
7953bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     * Whether or not the options menu is in its smaller, icon menu form.  When
7963bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     * true, we want the title bar overlay to be up.  When false, we do not.
7973bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     * Only meaningful if mOptionsMenuOpen is true.
7983bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     */
7993bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    private boolean mIconView;
8003bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins
801a81a764063d2f849fba0cbc3039f86e67c2960ddLeon Scroggins    @Override
802a81a764063d2f849fba0cbc3039f86e67c2960ddLeon Scroggins    public boolean onMenuOpened(int featureId, Menu menu) {
8033bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins        if (Window.FEATURE_OPTIONS_PANEL == featureId) {
8043bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins            if (mOptionsMenuOpen) {
8053bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                if (mConfigChanged) {
8063bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                    // We do not need to make any changes to the state of the
8073bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                    // title bar, since the only thing that happened was a
8083bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                    // change in orientation
8093bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                    mConfigChanged = false;
8103bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                } else {
8113bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                    if (mIconView) {
8123bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                        // Switching the menu to expanded view, so hide the
8133bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                        // title bar.
8143bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                        hideFakeTitleBar();
8153bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                        mIconView = false;
8163bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                    } else {
8173bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                        // Switching the menu back to icon view, so show the
8183bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                        // title bar once again.
8193bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                        showFakeTitleBar();
8203bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                        mIconView = true;
8213bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                    }
8223bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                }
8233bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins            } else {
8243bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                // The options menu is closed, so open it, and show the title
8253bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                showFakeTitleBar();
8263bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                mOptionsMenuOpen = true;
8273bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                mConfigChanged = false;
8283bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                mIconView = true;
8293bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins            }
8303bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins        }
831a81a764063d2f849fba0cbc3039f86e67c2960ddLeon Scroggins        return true;
832a81a764063d2f849fba0cbc3039f86e67c2960ddLeon Scroggins    }
833a81a764063d2f849fba0cbc3039f86e67c2960ddLeon Scroggins
834a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb    void showFakeTitleBar() {
835a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb        if (!isFakeTitleBarShowing() && mActiveTabsPage == null && !mActivityInPause) {
836847c25b877f1c912fe54ba7d3890df7ed3798e47Grace Kloba            WebView mainView = mTabControl.getCurrentWebView();
837847c25b877f1c912fe54ba7d3890df7ed3798e47Grace Kloba            // if there is no current WebView, don't show the faked title bar;
83865190702c53f2d3ceb8e3c88d707bd6ff874034cGrace Kloba            if (mainView == null) {
839a04645545690d9f637ccae4d043a5a1b8478a832Cary Clark                return;
840a04645545690d9f637ccae4d043a5a1b8478a832Cary Clark            }
84179e36d97b67bf06b1e0c0edf773882e93a3293e4Leon Scroggins            // Do not need to check for null, since the current tab will have
84279e36d97b67bf06b1e0c0edf773882e93a3293e4Leon Scroggins            // at least a main WebView, or we would have returned above.
8438e4fbf1b26c2cc05a56ba2d4e7d1eda7d1574e91Leon Scroggins III            if (isInCustomActionMode()) {
8448e4fbf1b26c2cc05a56ba2d4e7d1eda7d1574e91Leon Scroggins III                // Do not show the fake title bar, while a custom ActionMode
8458e4fbf1b26c2cc05a56ba2d4e7d1eda7d1574e91Leon Scroggins III                // (i.e. find or select) is showing.
84679e36d97b67bf06b1e0c0edf773882e93a3293e4Leon Scroggins                return;
84779e36d97b67bf06b1e0c0edf773882e93a3293e4Leon Scroggins            }
848a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb            if (mXLargeScreenSize) {
849a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb                mContentView.addView(mFakeTitleBar);
850a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb                mTabBar.onShowTitleBar();
851a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb            } else {
852a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb                WindowManager manager = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
853a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb
854a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb                // Add the title bar to the window manager so it can receive
855a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb                // touches
856a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb                // while the menu is up
857a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb                WindowManager.LayoutParams params =
858a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb                        new WindowManager.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
859a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb                                ViewGroup.LayoutParams.WRAP_CONTENT,
860a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb                                WindowManager.LayoutParams.TYPE_APPLICATION,
861a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb                                WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
862a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb                                PixelFormat.TRANSLUCENT);
863a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb                params.gravity = Gravity.TOP;
864a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb                boolean atTop = mainView.getScrollY() == 0;
865a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb                params.windowAnimations = atTop ? 0 : R.style.TitleBar;
866a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb                manager.addView(mFakeTitleBar, params);
867a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb            }
8683bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins        }
8693bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    }
8703bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins
8713bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    @Override
8723bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    public void onOptionsMenuClosed(Menu menu) {
8733bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins        mOptionsMenuOpen = false;
874a27ff19e24cb1c9fef5624dbc4554548349b5b31Leon Scroggins        if (!mInLoad) {
875a27ff19e24cb1c9fef5624dbc4554548349b5b31Leon Scroggins            hideFakeTitleBar();
876a27ff19e24cb1c9fef5624dbc4554548349b5b31Leon Scroggins        } else if (!mIconView) {
877a27ff19e24cb1c9fef5624dbc4554548349b5b31Leon Scroggins            // The page is currently loading, and we are in expanded mode, so
878a27ff19e24cb1c9fef5624dbc4554548349b5b31Leon Scroggins            // we were not showing the menu.  Show it once again.  It will be
879a27ff19e24cb1c9fef5624dbc4554548349b5b31Leon Scroggins            // removed when the page finishes.
880a27ff19e24cb1c9fef5624dbc4554548349b5b31Leon Scroggins            showFakeTitleBar();
881a27ff19e24cb1c9fef5624dbc4554548349b5b31Leon Scroggins        }
8823bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    }
88322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
884a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb    void stopScrolling() {
885a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb        ((ScrollWebView) mTabControl.getCurrentWebView()).stopScroll();
886a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb    }
887a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb
888a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb    void hideFakeTitleBar() {
889a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb        if (!isFakeTitleBarShowing()) return;
890a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb        if (mXLargeScreenSize) {
891a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb            mContentView.removeView(mFakeTitleBar);
892a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb            mTabBar.onHideTitleBar();
893a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb        } else {
894a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb            WindowManager.LayoutParams params =
895a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb                    (WindowManager.LayoutParams) mFakeTitleBar.getLayoutParams();
896a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb            WebView mainView = mTabControl.getCurrentWebView();
897a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb            // Although we decided whether or not to animate based on the
898a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb            // current
899a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb            // scroll position, the scroll position may have changed since the
900a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb            // fake title bar was displayed. Make sure it has the appropriate
901a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb            // animation/lack thereof before removing.
902a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb            params.windowAnimations =
903a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb                    mainView != null && mainView.getScrollY() == 0 ? 0 : R.style.TitleBar;
904a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb            WindowManager manager = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
905a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb            manager.updateViewLayout(mFakeTitleBar, params);
906a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb            manager.removeView(mFakeTitleBar);
907a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb        }
908a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb    }
909a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb
910a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb    boolean isFakeTitleBarShowing() {
911a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb        return (mFakeTitleBar.getParent() != null);
9123bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    }
9133bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins
9140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
915c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins     * Special method for the fake title bar to call when displaying its context
916c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins     * menu, since it is in its own Window, and its parent does not show a
917c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins     * context menu.
918c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins     */
919c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins    /* package */ void showTitleBarContextMenu() {
92065f4a3ce9e5c4a5227bbcbb995e5e15f1f85d3d7Cary Clark        if (null == mTitleBar.getParent()) {
92165f4a3ce9e5c4a5227bbcbb995e5e15f1f85d3d7Cary Clark            return;
92265f4a3ce9e5c4a5227bbcbb995e5e15f1f85d3d7Cary Clark        }
923c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins        openContextMenu(mTitleBar);
924c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins    }
925c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins
926b2b19f501ee05448ca81bddaaca70e9b2f51cb54Leon Scroggins    @Override
927b2b19f501ee05448ca81bddaaca70e9b2f51cb54Leon Scroggins    public void onContextMenuClosed(Menu menu) {
928b2b19f501ee05448ca81bddaaca70e9b2f51cb54Leon Scroggins        super.onContextMenuClosed(menu);
929b2b19f501ee05448ca81bddaaca70e9b2f51cb54Leon Scroggins        if (mInLoad) {
930b2b19f501ee05448ca81bddaaca70e9b2f51cb54Leon Scroggins            showFakeTitleBar();
931b2b19f501ee05448ca81bddaaca70e9b2f51cb54Leon Scroggins        }
932b2b19f501ee05448ca81bddaaca70e9b2f51cb54Leon Scroggins    }
933b2b19f501ee05448ca81bddaaca70e9b2f51cb54Leon Scroggins
934c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins    /**
9350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *  onSaveInstanceState(Bundle map)
9360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *  onSaveInstanceState is called right before onStop(). The map contains
9370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *  the saved state.
9380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
93922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    @Override
94022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    protected void onSaveInstanceState(Bundle outState) {
94131a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort        if (LOGV_ENABLED) {
9420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Log.v(LOGTAG, "BrowserActivity.onSaveInstanceState: this=" + this);
9430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
9440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // the default implementation requires each view to have an id. As the
9450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // browser handles the state itself and it doesn't use id for the views,
9460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // don't call the default implementation. Otherwise it will trigger the
9470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // warning like this, "couldn't save which view has focus because the
9480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // focused view XXX has no id".
9490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
9500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Save all the tabs
9510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mTabControl.saveState(outState);
9523d6df16f1c9a64cf2dc5b41a2078f4c49b0c296aElliott Slaughter
9533d6df16f1c9a64cf2dc5b41a2078f4c49b0c296aElliott Slaughter        // Save time so that we know how old incognito tabs (if any) are.
9543d6df16f1c9a64cf2dc5b41a2078f4c49b0c296aElliott Slaughter        outState.putSerializable("lastActiveDate", Calendar.getInstance());
9550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
9560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
95722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    @Override
95822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    protected void onPause() {
9590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        super.onPause();
9600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
9610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mActivityInPause) {
9620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Log.e(LOGTAG, "BrowserActivity is already paused.");
9630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
9640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
9650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
9667bfa63b55644fbf2da1fe6a24b3be0267529202cMike Reed        mTabControl.pauseCurrentTab();
9670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mActivityInPause = true;
9687bfa63b55644fbf2da1fe6a24b3be0267529202cMike Reed        if (mTabControl.getCurrentIndex() >= 0 && !pauseWebViewTimers()) {
9690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mWakeLock.acquire();
9700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mHandler.sendMessageDelayed(mHandler
9710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    .obtainMessage(RELEASE_WAKELOCK), WAKELOCK_TIMEOUT);
9720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
9730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
974a2ab6a7dc0f7023c1d7ebb1cbad397c5dc3d6453Leon Scroggins        // FIXME: This removes the active tabs page and resets the menu to
975a2ab6a7dc0f7023c1d7ebb1cbad397c5dc3d6453Leon Scroggins        // MAIN_MENU.  A better solution might be to do this work in onNewIntent
976a2ab6a7dc0f7023c1d7ebb1cbad397c5dc3d6453Leon Scroggins        // but then we would need to save it in onSaveInstanceState and restore
977a2ab6a7dc0f7023c1d7ebb1cbad397c5dc3d6453Leon Scroggins        // it in onCreate/onRestoreInstanceState
978a2ab6a7dc0f7023c1d7ebb1cbad397c5dc3d6453Leon Scroggins        if (mActiveTabsPage != null) {
979a2ab6a7dc0f7023c1d7ebb1cbad397c5dc3d6453Leon Scroggins            removeActiveTabPage(true);
980a2ab6a7dc0f7023c1d7ebb1cbad397c5dc3d6453Leon Scroggins        }
981a2ab6a7dc0f7023c1d7ebb1cbad397c5dc3d6453Leon Scroggins
9820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        cancelStopToast();
9830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
9840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // unregister network state listener
9850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        unregisterReceiver(mNetworkStateIntentReceiver);
9860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebView.disablePlatformNotifications();
9870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
9880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
98922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    @Override
99022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    protected void onDestroy() {
99131a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort        if (LOGV_ENABLED) {
9920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Log.v(LOGTAG, "BrowserActivity.onDestroy: this=" + this);
9930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
9940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        super.onDestroy();
9950923d69a8ca45222cabd82a80eaa88da9f132e9aGrace Kloba
9968d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins        if (mUploadMessage != null) {
9978d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins            mUploadMessage.onReceiveValue(null);
9988d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins            mUploadMessage = null;
9998d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins        }
10008d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins
10010923d69a8ca45222cabd82a80eaa88da9f132e9aGrace Kloba        if (mTabControl == null) return;
10020923d69a8ca45222cabd82a80eaa88da9f132e9aGrace Kloba
10031fc98a322e9df6b0e797c26de6b2cb23d69ad5d3Grace Kloba        // Remove the fake title bar if it is there
10041fc98a322e9df6b0e797c26de6b2cb23d69ad5d3Grace Kloba        hideFakeTitleBar();
10051fc98a322e9df6b0e797c26de6b2cb23d69ad5d3Grace Kloba
10060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Remove the current tab and sub window
100722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        Tab t = mTabControl.getCurrentTab();
1008fb5e77fac7b8b311fe72827183f8988f5ee92a5fPatrick Scott        if (t != null) {
1009fb5e77fac7b8b311fe72827183f8988f5ee92a5fPatrick Scott            dismissSubWindow(t);
1010fb5e77fac7b8b311fe72827183f8988f5ee92a5fPatrick Scott            removeTabFromContentView(t);
1011fb5e77fac7b8b311fe72827183f8988f5ee92a5fPatrick Scott        }
10120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Destroy all the tabs
10130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mTabControl.destroy();
10140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebIconDatabase.getInstance().close();
10150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
1016a7611811e0d744a7220b7bf80c8f795af5ea53edBjorn Bringert        // Stop watching the default geolocation permissions
1017a7611811e0d744a7220b7bf80c8f795af5ea53edBjorn Bringert        mSystemAllowGeolocationOrigins.stop();
1018a7611811e0d744a7220b7bf80c8f795af5ea53edBjorn Bringert        mSystemAllowGeolocationOrigins = null;
10190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
10200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
10210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    @Override
10220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public void onConfigurationChanged(Configuration newConfig) {
10233bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins        mConfigChanged = true;
10240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        super.onConfigurationChanged(newConfig);
10250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
10260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mPageInfoDialog != null) {
10270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mPageInfoDialog.dismiss();
10280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            showPageInfo(
10290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mPageInfoView,
1030c7b92f811dfa3572578ddc6714c98a03936d9ce5Leon Scroggins                mPageInfoFromShowSSLCertificateOnError);
10310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
10320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mSSLCertificateDialog != null) {
10330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mSSLCertificateDialog.dismiss();
10340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            showSSLCertificate(
10350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mSSLCertificateView);
10360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
10370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mSSLCertificateOnErrorDialog != null) {
10380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mSSLCertificateOnErrorDialog.dismiss();
10390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            showSSLCertificateOnError(
10400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mSSLCertificateOnErrorView,
10410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mSSLCertificateOnErrorHandler,
10420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mSSLCertificateOnErrorError);
10430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
10440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mHttpAuthenticationDialog != null) {
10450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            String title = ((TextView) mHttpAuthenticationDialog
10460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    .findViewById(com.android.internal.R.id.alertTitle)).getText()
10470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    .toString();
10480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            String name = ((TextView) mHttpAuthenticationDialog
10490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    .findViewById(R.id.username_edit)).getText().toString();
10500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            String password = ((TextView) mHttpAuthenticationDialog
10510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    .findViewById(R.id.password_edit)).getText().toString();
10520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            int focusId = mHttpAuthenticationDialog.getCurrentFocus()
10530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    .getId();
10540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mHttpAuthenticationDialog.dismiss();
10550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            showHttpAuthentication(mHttpAuthHandler, null, null, title,
10560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    name, password, focusId);
10570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
10580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
10590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
106022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    @Override
106122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    public void onLowMemory() {
10620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        super.onLowMemory();
10630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mTabControl.freeMemory();
10640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
10650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
1066ff4d92ca529f8b77db67d0aea5d9988d5e390211Cary Clark    private void resumeWebViewTimers() {
106722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        Tab tab = mTabControl.getCurrentTab();
1068ff4d92ca529f8b77db67d0aea5d9988d5e390211Cary Clark        if (tab == null) return; // monkey can trigger this
106922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        boolean inLoad = tab.inLoad();
107022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if ((!mActivityInPause && !inLoad) || (mActivityInPause && inLoad)) {
10710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            CookieSyncManager.getInstance().startSync();
107222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            WebView w = tab.getWebView();
10730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (w != null) {
10740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                w.resumeTimers();
10750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
10760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
10770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
10780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
10797bfa63b55644fbf2da1fe6a24b3be0267529202cMike Reed    private boolean pauseWebViewTimers() {
108022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        Tab tab = mTabControl.getCurrentTab();
108122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        boolean inLoad = tab.inLoad();
108222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mActivityInPause && !inLoad) {
10830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            CookieSyncManager.getInstance().stopSync();
10840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            WebView w = mTabControl.getCurrentWebView();
10850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (w != null) {
10860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                w.pauseTimers();
10870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
10880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return true;
10890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
10900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return false;
10910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
10920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
10930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
10940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Open the icon database and retain all the icons for visited sites.
10950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void retainIconsOnStartup() {
10960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final WebIconDatabase db = WebIconDatabase.getInstance();
10970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        db.open(getDir("icons", 0).getPath());
10982c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins        Cursor c = null;
10990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        try {
11002c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins            c = Browser.getAllBookmarks(mResolver);
11012c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins            if (c.moveToFirst()) {
11022c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins                int urlIndex = c.getColumnIndex(Browser.BookmarkColumns.URL);
11032c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins                do {
11042c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins                    String url = c.getString(urlIndex);
11052c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins                    db.retainIconForPageUrl(url);
11062c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins                } while (c.moveToNext());
11070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
11080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } catch (IllegalStateException e) {
11090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Log.e(LOGTAG, "retainIconsOnStartup", e);
11102c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins        } finally {
11112c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins            if (c!= null) c.close();
11120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
11130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
11140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
11150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Helper method for getting the top window.
11160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    WebView getTopWindow() {
11170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return mTabControl.getCurrentTopWebView();
11180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
11190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
112022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    TabControl getTabControl() {
112122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return mTabControl;
112222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
112322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
11240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    @Override
11250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public boolean onCreateOptionsMenu(Menu menu) {
11260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        super.onCreateOptionsMenu(menu);
11270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
11280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        MenuInflater inflater = getMenuInflater();
11290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        inflater.inflate(R.menu.browser, menu);
11300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mMenu = menu;
11310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        updateInLoadMenuItems();
11320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return true;
11330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
11340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
11350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
11360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * As the menu can be open when loading state changes
11370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * we must manually update the state of the stop/reload menu
11380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * item
11390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
11400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void updateInLoadMenuItems() {
11410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mMenu == null) {
11420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
11430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
1144e0a3666b5c0dca7352895fa8b9b4fbb2237df721Michael Kolb        MenuItem dest = mMenu.findItem(R.id.stop_reload_menu_id);
11450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        MenuItem src = mInLoad ?
11460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mMenu.findItem(R.id.stop_menu_id):
1147e0a3666b5c0dca7352895fa8b9b4fbb2237df721Michael Kolb                mMenu.findItem(R.id.reload_menu_id);
1148e0a3666b5c0dca7352895fa8b9b4fbb2237df721Michael Kolb        if (src != null) {
1149e0a3666b5c0dca7352895fa8b9b4fbb2237df721Michael Kolb            dest.setIcon(src.getIcon());
1150e0a3666b5c0dca7352895fa8b9b4fbb2237df721Michael Kolb            dest.setTitle(src.getTitle());
1151e0a3666b5c0dca7352895fa8b9b4fbb2237df721Michael Kolb        }
11520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
11530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
11540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    @Override
11550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public boolean onContextItemSelected(MenuItem item) {
11560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // chording is not an issue with context menus, but we use the same
11570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // options selector, so set mCanChord to true so we can access them.
11580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mCanChord = true;
11590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        int id = item.getItemId();
116096afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins        boolean result = true;
11610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        switch (id) {
1162c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins            // For the context menu from the title bar
1163c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins            case R.id.title_bar_copy_page_url:
116496afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                Tab currentTab = mTabControl.getCurrentTab();
116596afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                if (null == currentTab) {
116696afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                    result = false;
116796afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                    break;
1168c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins                }
116996afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                WebView mainView = currentTab.getWebView();
117096afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                if (null == mainView) {
117196afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                    result = false;
117296afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                    break;
1173c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins                }
117496afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                copy(mainView.getUrl());
1175c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins                break;
11760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // -- Browser context menu
11770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.open_context_menu_id:
11780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.bookmark_context_menu_id:
11790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.save_link_context_menu_id:
11800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.share_link_context_menu_id:
11810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.copy_link_context_menu_id:
1182c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins                final WebView webView = getTopWindow();
1183c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins                if (null == webView) {
118496afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                    result = false;
118596afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                    break;
1186c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins                }
1187c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins                final HashMap hrefMap = new HashMap();
1188c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins                hrefMap.put("webview", webView);
1189c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins                final Message msg = mHandler.obtainMessage(
1190c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins                        FOCUS_NODE_HREF, id, 0, hrefMap);
11910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                webView.requestFocusNodeHref(msg);
11920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
11930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
11940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            default:
11950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // For other context menus
119696afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                result = onOptionsItemSelected(item);
11970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
11980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mCanChord = false;
119996afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins        return result;
12000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
12010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
12020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private Bundle createGoogleSearchSourceBundle(String source) {
12030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        Bundle bundle = new Bundle();
120410d1cca0c208d1f9db23893a8515685e04cfe224Bjorn Bringert        bundle.putString(Search.SOURCE, source);
12050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return bundle;
12060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
12070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
12088ad299270a97dfa3f9bcb956096bc152498fb727Leon Scroggins    /* package */ void editUrl() {
120968579393973f745fc65a2781061af9bb8f2d7020Leon Scroggins        if (mOptionsMenuOpen) closeOptionsMenu();
12105bbe98025a2c606a35c91b826760020890daadb1Leon Scroggins        String url = (getTopWindow() == null) ? null : getTopWindow().getUrl();
121183f473462fcd7869031a423c02b957c6e938a2f6Grace Kloba        startSearch(mSettings.getHomePage().equals(url) ? null : url, true,
12128ad299270a97dfa3f9bcb956096bc152498fb727Leon Scroggins                null, false);
12130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
12140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
12158ad299270a97dfa3f9bcb956096bc152498fb727Leon Scroggins    /**
12168ad299270a97dfa3f9bcb956096bc152498fb727Leon Scroggins     * Overriding this to insert a local information bundle
12178ad299270a97dfa3f9bcb956096bc152498fb727Leon Scroggins     */
12180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    @Override
12190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public void startSearch(String initialQuery, boolean selectInitialQuery,
12200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Bundle appSearchData, boolean globalSearch) {
12210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (appSearchData == null) {
12220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            appSearchData = createGoogleSearchSourceBundle(GOOGLE_SEARCH_SOURCE_TYPE);
12230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
12240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        super.startSearch(initialQuery, selectInitialQuery, appSearchData, globalSearch);
12250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
12260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
12271f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins    /**
12281f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins     * Switch tabs.  Called by the TitleBarSet when sliding the title bar
12291f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins     * results in changing tabs.
1230160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins     * @param index Index of the tab to change to, as defined by
1231160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins     *              mTabControl.getTabIndex(Tab t).
1232160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins     * @return boolean True if we successfully switched to a different tab.  If
1233160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins     *                 the indexth tab is null, or if that tab is the same as
1234160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins     *                 the current one, return false.
12351f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins     */
1236160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins    /* package */ boolean switchToTab(int index) {
123722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        Tab tab = mTabControl.getTab(index);
123822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        Tab currentTab = mTabControl.getCurrentTab();
12391f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins        if (tab == null || tab == currentTab) {
1240160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins            return false;
12411f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins        }
12421f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins        if (currentTab != null) {
12431f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins            // currentTab may be null if it was just removed.  In that case,
12441f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins            // we do not need to remove it
12451f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins            removeTabFromContentView(currentTab);
12461f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins        }
12471f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins        mTabControl.setCurrentTab(tab);
12481f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins        attachTabToContentView(tab);
1249eb6eef4c45df2d65c3e70660493a147a2be405e3Grace Kloba        resetTitleIconAndProgress();
1250eb6eef4c45df2d65c3e70660493a147a2be405e3Grace Kloba        updateLockIconToLatest();
1251160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins        return true;
12521f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins    }
12531f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins
125422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /* package */ Tab openTabToHomePage() {
12550a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins        return openTabAndShow(mSettings.getHomePage(), false, null);
12560a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins    }
12570a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins
12581f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins    /* package */ void closeCurrentWindow() {
125922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        final Tab current = mTabControl.getCurrentTab();
1260160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins        if (mTabControl.getTabCount() == 1) {
1261304442375719effd41dbd53ae62de7a8d0cec7d9Leon Scroggins            // This is the last tab.  Open a new one, with the home
1262304442375719effd41dbd53ae62de7a8d0cec7d9Leon Scroggins            // page and close the current one.
126322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            openTabToHomePage();
1264160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins            closeTab(current);
1265160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins            return;
1266160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins        }
126722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        final Tab parent = current.getParentTab();
12681f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins        int indexToShow = -1;
12691f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins        if (parent != null) {
12701f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins            indexToShow = mTabControl.getTabIndex(parent);
12711f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins        } else {
1272160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins            final int currentIndex = mTabControl.getCurrentIndex();
1273160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins            // Try to move to the tab to the right
1274160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins            indexToShow = currentIndex + 1;
1275160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins            if (indexToShow > mTabControl.getTabCount() - 1) {
1276160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins                // Try to move to the tab to the left
1277160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins                indexToShow = currentIndex - 1;
12781f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins            }
12791f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins        }
1280160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins        if (switchToTab(indexToShow)) {
1281160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins            // Close window
1282160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins            closeTab(current);
1283160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins        }
12841f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins    }
12851f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins
12860a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins    private ActiveTabsPage mActiveTabsPage;
12870a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins
12880a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins    /**
12890a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins     * Remove the active tabs page.
12900a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins     * @param needToAttach If true, the active tabs page did not attach a tab
12910a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins     *                     to the content view, so we need to do that here.
12920a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins     */
12930a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins    /* package */ void removeActiveTabPage(boolean needToAttach) {
12940a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins        mContentView.removeView(mActiveTabsPage);
1295d746a94137a87ffcc1fcefdac9a3764c3bc3f5cdLeon Scroggins        mTitleBar.setVisibility(View.VISIBLE);
12960a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins        mActiveTabsPage = null;
12970a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins        mMenuState = R.id.MAIN_MENU;
12980a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins        if (needToAttach) {
12990a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins            attachTabToContentView(mTabControl.getCurrentTab());
13000a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins        }
13010a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins        getTopWindow().requestFocus();
13020a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins    }
13030a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins
13048e4fbf1b26c2cc05a56ba2d4e7d1eda7d1574e91Leon Scroggins III    @Override
13058e4fbf1b26c2cc05a56ba2d4e7d1eda7d1574e91Leon Scroggins III    public ActionMode onStartActionMode(ActionMode.Callback callback) {
13064fc12cbfe150afe12059ceb5bfa4a497ef20072dLeon Scroggins        mActionMode = super.onStartActionMode(callback);
13074fc12cbfe150afe12059ceb5bfa4a497ef20072dLeon Scroggins        hideFakeTitleBar();
13084fc12cbfe150afe12059ceb5bfa4a497ef20072dLeon Scroggins        // Would like to change the MENU, but onEndActionMode may not be called
13094fc12cbfe150afe12059ceb5bfa4a497ef20072dLeon Scroggins        return mActionMode;
131001cfcdd0b77d672f5c09d98af683c6732c8250d8Cary Clark    }
131101cfcdd0b77d672f5c09d98af683c6732c8250d8Cary Clark
13120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    @Override
13130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public boolean onOptionsItemSelected(MenuItem item) {
1314ed217745066c160f785626e9a15ebe70af5e25e4Michael Kolb        // check the action bar button before mCanChord check, as the prepare call
1315ed217745066c160f785626e9a15ebe70af5e25e4Michael Kolb        // doesn't come for action bar buttons
1316ed217745066c160f785626e9a15ebe70af5e25e4Michael Kolb        if (item.getItemId() == R.id.newtab) {
1317300b7f0951f3688a8e41f190b57cbf8b3bc06170Michael Kolb            openTabToHomePage();
1318300b7f0951f3688a8e41f190b57cbf8b3bc06170Michael Kolb            mHandler.sendMessage(mHandler.obtainMessage(OPEN_BOOKMARKS));
1319ed217745066c160f785626e9a15ebe70af5e25e4Michael Kolb            return true;
1320ed217745066c160f785626e9a15ebe70af5e25e4Michael Kolb        }
13210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (!mCanChord) {
13220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // The user has already fired a shortcut with this hold down of the
13230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // menu key.
13240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return false;
13250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
13261f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins        if (null == getTopWindow()) {
13270d7ae0ed82e21d472cde8cf92b5657d8ee8ca0d8Leon Scroggins            return false;
13280d7ae0ed82e21d472cde8cf92b5657d8ee8ca0d8Leon Scroggins        }
13296ee9c498b8cf648f1507281ed5a1834ba3390907Grace Kloba        if (mMenuIsDown) {
13306ee9c498b8cf648f1507281ed5a1834ba3390907Grace Kloba            // The shortcut action consumes the MENU. Even if it is still down,
13316ee9c498b8cf648f1507281ed5a1834ba3390907Grace Kloba            // it won't trigger the next shortcut action. In the case of the
13326ee9c498b8cf648f1507281ed5a1834ba3390907Grace Kloba            // shortcut action triggering a new activity, like Bookmarks, we
13336ee9c498b8cf648f1507281ed5a1834ba3390907Grace Kloba            // won't get onKeyUp for MENU. So it is important to reset it here.
13346ee9c498b8cf648f1507281ed5a1834ba3390907Grace Kloba            mMenuIsDown = false;
13356ee9c498b8cf648f1507281ed5a1834ba3390907Grace Kloba        }
13360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        switch (item.getItemId()) {
13370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // -- Main menu
1338a81a764063d2f849fba0cbc3039f86e67c2960ddLeon Scroggins            case R.id.new_tab_menu_id:
13390a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins                openTabToHomePage();
1340a81a764063d2f849fba0cbc3039f86e67c2960ddLeon Scroggins                break;
1341a81a764063d2f849fba0cbc3039f86e67c2960ddLeon Scroggins
1342ae62fd48652f989335db21a03d8289ecc5b57e88Michael Kolb            case R.id.incognito_menu_id:
1343ae62fd48652f989335db21a03d8289ecc5b57e88Michael Kolb                openIncognitoTab();
1344ae62fd48652f989335db21a03d8289ecc5b57e88Michael Kolb                break;
1345ae62fd48652f989335db21a03d8289ecc5b57e88Michael Kolb
134664b80f3efd95d7b5192731e995ccde79c4c6c11fLeon Scroggins            case R.id.goto_menu_id:
13478ad299270a97dfa3f9bcb956096bc152498fb727Leon Scroggins                editUrl();
1348b3a5bedeede968b53363a6c517f92bc2484bb42dLeon Scroggins                break;
1349b3a5bedeede968b53363a6c517f92bc2484bb42dLeon Scroggins
1350b3a5bedeede968b53363a6c517f92bc2484bb42dLeon Scroggins            case R.id.bookmarks_menu_id:
135168792c84eded7f83e2f086d3efe81f9cfc07f9c3Michael Kolb                bookmarksOrHistoryPicker(false, false);
13520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
13530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
13540a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins            case R.id.active_tabs_menu_id:
13550a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins                mActiveTabsPage = new ActiveTabsPage(this, mTabControl);
13560a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins                removeTabFromContentView(mTabControl.getCurrentTab());
1357d746a94137a87ffcc1fcefdac9a3764c3bc3f5cdLeon Scroggins                mTitleBar.setVisibility(View.GONE);
135843de61666cfc98a3acc41c7161a1a8b0bdb2b72bLeon Scroggins                hideFakeTitleBar();
13590a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins                mContentView.addView(mActiveTabsPage, COVER_SCREEN_PARAMS);
13600a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins                mActiveTabsPage.requestFocus();
13610a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins                mMenuState = EMPTY_MENU;
13620a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins                break;
13630a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins
13641f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins            case R.id.add_bookmark_menu_id:
1365571b3762a5eb9e492283e0a1e437edd209fdc0deLeon Scroggins                bookmarkCurrentPage();
13660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
13670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
13680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.stop_reload_menu_id:
13690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (mInLoad) {
13700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    stopLoading();
13710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                } else {
13720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    getTopWindow().reload();
13730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
13740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
13750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
13760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.back_menu_id:
13770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                getTopWindow().goBack();
13780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
13790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
13800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.forward_menu_id:
13810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                getTopWindow().goForward();
13820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
13830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
13840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.close_menu_id:
13850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // Close the subwindow if it exists.
13860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (mTabControl.getCurrentSubWindow() != null) {
13870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    dismissSubWindow(mTabControl.getCurrentTab());
13880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    break;
13890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
13901f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                closeCurrentWindow();
13910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
13920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
13930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.homepage_menu_id:
139422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                Tab current = mTabControl.getCurrentTab();
13950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (current != null) {
13960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    dismissSubWindow(current);
139792472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins                    loadUrl(current.getWebView(), mSettings.getHomePage());
13980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
13990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
14000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
14010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.preferences_menu_id:
14020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                Intent intent = new Intent(this,
14030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        BrowserPreferencesPage.class);
1404d530494de9c182af4aff97ddd46343b32594da51Leon Scroggins                intent.putExtra(BrowserPreferencesPage.CURRENT_PAGE,
1405d530494de9c182af4aff97ddd46343b32594da51Leon Scroggins                        getTopWindow().getUrl());
14060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                startActivityForResult(intent, PREFERENCES_PAGE);
14070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
14080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
14090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.find_menu_id:
14104fc12cbfe150afe12059ceb5bfa4a497ef20072dLeon Scroggins                getTopWindow().showFindDialog(null);
14110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
14120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
14130ced08c2332b6e3af5bc31a12568840e9160bb6aElliott Slaughter            case R.id.save_webarchive_menu_id:
14140ced08c2332b6e3af5bc31a12568840e9160bb6aElliott Slaughter                if (LOGD_ENABLED) {
14150ced08c2332b6e3af5bc31a12568840e9160bb6aElliott Slaughter                    Log.d(LOGTAG, "Save as Web Archive");
14160ced08c2332b6e3af5bc31a12568840e9160bb6aElliott Slaughter                }
1417aba242c3435b444fdc7b0c7620175d3aa6358017Elliott Slaughter                String state = Environment.getExternalStorageState();
1418aba242c3435b444fdc7b0c7620175d3aa6358017Elliott Slaughter                if (Environment.MEDIA_MOUNTED.equals(state)) {
1419aba242c3435b444fdc7b0c7620175d3aa6358017Elliott Slaughter                    String directory = Environment.getExternalStoragePublicDirectory(
1420aba242c3435b444fdc7b0c7620175d3aa6358017Elliott Slaughter                            Environment.DIRECTORY_DOWNLOADS).getAbsolutePath() + File.separator;
1421aba242c3435b444fdc7b0c7620175d3aa6358017Elliott Slaughter                    getTopWindow().saveWebArchive(directory, true, new ValueCallback<String>() {
1422aba242c3435b444fdc7b0c7620175d3aa6358017Elliott Slaughter                        @Override
1423aba242c3435b444fdc7b0c7620175d3aa6358017Elliott Slaughter                        public void onReceiveValue(String value) {
1424aba242c3435b444fdc7b0c7620175d3aa6358017Elliott Slaughter                            if (value != null) {
1425aba242c3435b444fdc7b0c7620175d3aa6358017Elliott Slaughter                                Toast.makeText(BrowserActivity.this, R.string.webarchive_saved,
1426aba242c3435b444fdc7b0c7620175d3aa6358017Elliott Slaughter                                        Toast.LENGTH_SHORT).show();
1427aba242c3435b444fdc7b0c7620175d3aa6358017Elliott Slaughter                            } else {
1428aba242c3435b444fdc7b0c7620175d3aa6358017Elliott Slaughter                                Toast.makeText(BrowserActivity.this, R.string.webarchive_failed,
1429aba242c3435b444fdc7b0c7620175d3aa6358017Elliott Slaughter                                        Toast.LENGTH_SHORT).show();
1430aba242c3435b444fdc7b0c7620175d3aa6358017Elliott Slaughter                            }
14310ced08c2332b6e3af5bc31a12568840e9160bb6aElliott Slaughter                        }
1432aba242c3435b444fdc7b0c7620175d3aa6358017Elliott Slaughter                    });
1433aba242c3435b444fdc7b0c7620175d3aa6358017Elliott Slaughter                } else {
1434aba242c3435b444fdc7b0c7620175d3aa6358017Elliott Slaughter                    Toast.makeText(BrowserActivity.this, R.string.webarchive_failed,
1435aba242c3435b444fdc7b0c7620175d3aa6358017Elliott Slaughter                            Toast.LENGTH_SHORT).show();
1436aba242c3435b444fdc7b0c7620175d3aa6358017Elliott Slaughter                }
14370ced08c2332b6e3af5bc31a12568840e9160bb6aElliott Slaughter                break;
14380ced08c2332b6e3af5bc31a12568840e9160bb6aElliott Slaughter
14390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.page_info_menu_id:
14400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                showPageInfo(mTabControl.getCurrentTab(), false);
14410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
14420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
14430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.classic_history_menu_id:
144468792c84eded7f83e2f086d3efe81f9cfc07f9c3Michael Kolb                bookmarksOrHistoryPicker(true, false);
14450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
14460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
144796afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins            case R.id.title_bar_share_page_url:
14480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.share_page_menu_id:
144996afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                Tab currentTab = mTabControl.getCurrentTab();
145096afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                if (null == currentTab) {
145196afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                    mCanChord = false;
145296afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                    return false;
145396afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                }
145496afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                currentTab.populatePickerData();
145596afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                sharePage(this, currentTab.getTitle(),
145696afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                        currentTab.getUrl(), currentTab.getFavicon(),
145787cc65d95c80c5e3a1c343ad5177a7dc2de874f6Ben Murdoch                        createScreenshot(currentTab.getWebView(), getDesiredThumbnailWidth(this),
145887cc65d95c80c5e3a1c343ad5177a7dc2de874f6Ben Murdoch                                getDesiredThumbnailHeight(this)));
14590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
14600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
14610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.dump_nav_menu_id:
14620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                getTopWindow().debugDump();
14630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
14640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
14657a8b88b0e0f20544df5ee34b798398603261b733Andrei Popescu            case R.id.dump_counters_menu_id:
14667a8b88b0e0f20544df5ee34b798398603261b733Andrei Popescu                getTopWindow().dumpV8Counters();
14677a8b88b0e0f20544df5ee34b798398603261b733Andrei Popescu                break;
14687a8b88b0e0f20544df5ee34b798398603261b733Andrei Popescu
14690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.zoom_in_menu_id:
14700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                getTopWindow().zoomIn();
14710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
14720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
14730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.zoom_out_menu_id:
14740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                getTopWindow().zoomOut();
14750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
14760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
14770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.view_downloads_menu_id:
14780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                viewDownloads(null);
14790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
14800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
14810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.window_one_menu_id:
14820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.window_two_menu_id:
14830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.window_three_menu_id:
14840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.window_four_menu_id:
14850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.window_five_menu_id:
14860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.window_six_menu_id:
14870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.window_seven_menu_id:
14880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.window_eight_menu_id:
14890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                {
14900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    int menuid = item.getItemId();
14910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    for (int id = 0; id < WINDOW_SHORTCUT_ID_ARRAY.length; id++) {
14920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        if (WINDOW_SHORTCUT_ID_ARRAY[id] == menuid) {
149322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            Tab desiredTab = mTabControl.getTab(id);
14940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            if (desiredTab != null &&
14950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    desiredTab != mTabControl.getCurrentTab()) {
14961f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                                switchToTab(id);
14970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            }
14980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            break;
14990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }
15000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
15010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
15020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
15030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
15040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            default:
15050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (!super.onOptionsItemSelected(item)) {
15060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    return false;
15070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
15080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // Otherwise fall through.
15090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
15100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mCanChord = false;
15110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return true;
15120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
15130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
1514571b3762a5eb9e492283e0a1e437edd209fdc0deLeon Scroggins    /* package */ void bookmarkCurrentPage() {
1515571b3762a5eb9e492283e0a1e437edd209fdc0deLeon Scroggins        Intent i = new Intent(BrowserActivity.this,
1516571b3762a5eb9e492283e0a1e437edd209fdc0deLeon Scroggins                AddBookmarkPage.class);
1517571b3762a5eb9e492283e0a1e437edd209fdc0deLeon Scroggins        WebView w = getTopWindow();
1518571b3762a5eb9e492283e0a1e437edd209fdc0deLeon Scroggins        i.putExtra("url", w.getUrl());
1519571b3762a5eb9e492283e0a1e437edd209fdc0deLeon Scroggins        i.putExtra("title", w.getTitle());
1520571b3762a5eb9e492283e0a1e437edd209fdc0deLeon Scroggins        i.putExtra("touch_icon_url", w.getTouchIconUrl());
152187cc65d95c80c5e3a1c343ad5177a7dc2de874f6Ben Murdoch        i.putExtra("thumbnail", createScreenshot(w, getDesiredThumbnailWidth(this),
152287cc65d95c80c5e3a1c343ad5177a7dc2de874f6Ben Murdoch                getDesiredThumbnailHeight(this)));
1523eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch        i.putExtra("url_editable", false);
1524571b3762a5eb9e492283e0a1e437edd209fdc0deLeon Scroggins        startActivity(i);
1525571b3762a5eb9e492283e0a1e437edd209fdc0deLeon Scroggins    }
1526571b3762a5eb9e492283e0a1e437edd209fdc0deLeon Scroggins
15278e4fbf1b26c2cc05a56ba2d4e7d1eda7d1574e91Leon Scroggins III    /*
15288e4fbf1b26c2cc05a56ba2d4e7d1eda7d1574e91Leon Scroggins III     * True if a custom ActionMode (i.e. find or select) is in use.
15298e4fbf1b26c2cc05a56ba2d4e7d1eda7d1574e91Leon Scroggins III     */
15308e4fbf1b26c2cc05a56ba2d4e7d1eda7d1574e91Leon Scroggins III    private boolean isInCustomActionMode() {
15318e4fbf1b26c2cc05a56ba2d4e7d1eda7d1574e91Leon Scroggins III        return mActionMode != null;
153201cfcdd0b77d672f5c09d98af683c6732c8250d8Cary Clark    }
153301cfcdd0b77d672f5c09d98af683c6732c8250d8Cary Clark
15348e4fbf1b26c2cc05a56ba2d4e7d1eda7d1574e91Leon Scroggins III    /*
15354fc12cbfe150afe12059ceb5bfa4a497ef20072dLeon Scroggins     * End the current ActionMode.
15368e4fbf1b26c2cc05a56ba2d4e7d1eda7d1574e91Leon Scroggins III     */
15378e4fbf1b26c2cc05a56ba2d4e7d1eda7d1574e91Leon Scroggins III    void endActionMode() {
15388e4fbf1b26c2cc05a56ba2d4e7d1eda7d1574e91Leon Scroggins III        if (mActionMode != null) {
15394fc12cbfe150afe12059ceb5bfa4a497ef20072dLeon Scroggins            ActionMode mode = mActionMode;
15404fc12cbfe150afe12059ceb5bfa4a497ef20072dLeon Scroggins            onEndActionMode();
15414fc12cbfe150afe12059ceb5bfa4a497ef20072dLeon Scroggins            mode.finish();
15428e4fbf1b26c2cc05a56ba2d4e7d1eda7d1574e91Leon Scroggins III        }
154301cfcdd0b77d672f5c09d98af683c6732c8250d8Cary Clark    }
154401cfcdd0b77d672f5c09d98af683c6732c8250d8Cary Clark
1545211ba54a3052f7e68bf8af035ea1ef4e9445130cLeon Scroggins III    /*
15468e4fbf1b26c2cc05a56ba2d4e7d1eda7d1574e91Leon Scroggins III     * Called by find and select when they are finished.  Replace title bars
15478e4fbf1b26c2cc05a56ba2d4e7d1eda7d1574e91Leon Scroggins III     * as necessary.
1548211ba54a3052f7e68bf8af035ea1ef4e9445130cLeon Scroggins III     */
15498e4fbf1b26c2cc05a56ba2d4e7d1eda7d1574e91Leon Scroggins III    public void onEndActionMode() {
15508e4fbf1b26c2cc05a56ba2d4e7d1eda7d1574e91Leon Scroggins III        if (!isInCustomActionMode()) return;
155179e36d97b67bf06b1e0c0edf773882e93a3293e4Leon Scroggins        if (mInLoad) {
155279e36d97b67bf06b1e0c0edf773882e93a3293e4Leon Scroggins            // The title bar was hidden, because otherwise it would cover up the
1553a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb            // find or select dialog. Now that the dialog has been removed,
155401cfcdd0b77d672f5c09d98af683c6732c8250d8Cary Clark            // show the fake title bar once again.
155579e36d97b67bf06b1e0c0edf773882e93a3293e4Leon Scroggins            showFakeTitleBar();
155679e36d97b67bf06b1e0c0edf773882e93a3293e4Leon Scroggins        }
15574fc12cbfe150afe12059ceb5bfa4a497ef20072dLeon Scroggins        // Would like to return the menu state to normal, but this does not
15584fc12cbfe150afe12059ceb5bfa4a497ef20072dLeon Scroggins        // necessarily get called.
15598e4fbf1b26c2cc05a56ba2d4e7d1eda7d1574e91Leon Scroggins III        mActionMode = null;
15600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
15610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
15628e4fbf1b26c2cc05a56ba2d4e7d1eda7d1574e91Leon Scroggins III    // For select and find, we keep track of the ActionMode so that
15638e4fbf1b26c2cc05a56ba2d4e7d1eda7d1574e91Leon Scroggins III    // finish() can be called as desired.
15648e4fbf1b26c2cc05a56ba2d4e7d1eda7d1574e91Leon Scroggins III    private ActionMode mActionMode;
15658e4fbf1b26c2cc05a56ba2d4e7d1eda7d1574e91Leon Scroggins III
156622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    @Override
156722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    public boolean onPrepareOptionsMenu(Menu menu) {
15680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // This happens when the user begins to hold down the menu key, so
15690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // allow them to chord to get a shortcut.
15700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mCanChord = true;
15710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Note: setVisible will decide whether an item is visible; while
15720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // setEnabled() will decide whether an item is enabled, which also means
15730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // whether the matching shortcut key will function.
15740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        super.onPrepareOptionsMenu(menu);
15750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        switch (mMenuState) {
15760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case EMPTY_MENU:
15770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (mCurrentMenuState != mMenuState) {
15780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    menu.setGroupVisible(R.id.MAIN_MENU, false);
15790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    menu.setGroupEnabled(R.id.MAIN_MENU, false);
15800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    menu.setGroupEnabled(R.id.MAIN_SHORTCUT_MENU, false);
15810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
15820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
15830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            default:
15840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (mCurrentMenuState != mMenuState) {
15850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    menu.setGroupVisible(R.id.MAIN_MENU, true);
15860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    menu.setGroupEnabled(R.id.MAIN_MENU, true);
15870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    menu.setGroupEnabled(R.id.MAIN_SHORTCUT_MENU, true);
15880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
15890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                final WebView w = getTopWindow();
15900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                boolean canGoBack = false;
15910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                boolean canGoForward = false;
15920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                boolean isHome = false;
15930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (w != null) {
15940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    canGoBack = w.canGoBack();
15950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    canGoForward = w.canGoForward();
15960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    isHome = mSettings.getHomePage().equals(w.getUrl());
15970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
15980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                final MenuItem back = menu.findItem(R.id.back_menu_id);
15990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                back.setEnabled(canGoBack);
16000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
16010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                final MenuItem home = menu.findItem(R.id.homepage_menu_id);
16020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                home.setEnabled(!isHome);
16030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
1604e0a3666b5c0dca7352895fa8b9b4fbb2237df721Michael Kolb                final MenuItem forward = menu.findItem(R.id.forward_menu_id);
1605e0a3666b5c0dca7352895fa8b9b4fbb2237df721Michael Kolb                forward.setEnabled(canGoForward);
16060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
1607ed217745066c160f785626e9a15ebe70af5e25e4Michael Kolb                if (!mXLargeScreenSize) {
1608ed217745066c160f785626e9a15ebe70af5e25e4Michael Kolb                    final MenuItem newtab = menu.findItem(R.id.new_tab_menu_id);
1609ed217745066c160f785626e9a15ebe70af5e25e4Michael Kolb                    newtab.setEnabled(mTabControl.canCreateNewTab());
1610ed217745066c160f785626e9a15ebe70af5e25e4Michael Kolb                }
1611a81a764063d2f849fba0cbc3039f86e67c2960ddLeon Scroggins
16120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // decide whether to show the share link option
16130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                PackageManager pm = getPackageManager();
16140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                Intent send = new Intent(Intent.ACTION_SEND);
16150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                send.setType("text/plain");
16160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                ResolveInfo ri = pm.resolveActivity(send, PackageManager.MATCH_DEFAULT_ONLY);
16170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.share_page_menu_id).setVisible(ri != null);
16180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
16190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                boolean isNavDump = mSettings.isNavDump();
16200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                final MenuItem nav = menu.findItem(R.id.dump_nav_menu_id);
16210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                nav.setVisible(isNavDump);
16220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                nav.setEnabled(isNavDump);
16237a8b88b0e0f20544df5ee34b798398603261b733Andrei Popescu
16247a8b88b0e0f20544df5ee34b798398603261b733Andrei Popescu                boolean showDebugSettings = mSettings.showDebugSettings();
16257a8b88b0e0f20544df5ee34b798398603261b733Andrei Popescu                final MenuItem counter = menu.findItem(R.id.dump_counters_menu_id);
16267a8b88b0e0f20544df5ee34b798398603261b733Andrei Popescu                counter.setVisible(showDebugSettings);
16277a8b88b0e0f20544df5ee34b798398603261b733Andrei Popescu                counter.setEnabled(showDebugSettings);
16287a8b88b0e0f20544df5ee34b798398603261b733Andrei Popescu
16290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
16300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
16310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mCurrentMenuState = mMenuState;
16320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return true;
16330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
16340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
16350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    @Override
16360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public void onCreateContextMenu(ContextMenu menu, View v,
16370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ContextMenuInfo menuInfo) {
1638571b3762a5eb9e492283e0a1e437edd209fdc0deLeon Scroggins        if (v instanceof TitleBarBase) {
16394e9f89b0a64395133b9160dcb4533d2dc62a424fLeon Scroggins            return;
16404e9f89b0a64395133b9160dcb4533d2dc62a424fLeon Scroggins        }
16410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebView webview = (WebView) v;
16420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebView.HitTestResult result = webview.getHitTestResult();
16430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (result == null) {
16440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
16450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
16460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
16470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        int type = result.getType();
16480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (type == WebView.HitTestResult.UNKNOWN_TYPE) {
16490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Log.w(LOGTAG,
16500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    "We should not show context menu when nothing is touched");
16510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
16520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
16530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (type == WebView.HitTestResult.EDIT_TEXT_TYPE) {
16540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // let TextView handles context menu
16550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
16560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
16570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
16580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Note, http://b/issue?id=1106666 is requesting that
16590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // an inflated menu can be used again. This is not available
16600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // yet, so inflate each time (yuk!)
16610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        MenuInflater inflater = getMenuInflater();
16620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        inflater.inflate(R.menu.browsercontext, menu);
16630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
16640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Show the correct menu group
16659e997c7c92175c8e24cef90e265cc35fd9b8710eLeon Scroggins III        final String extra = result.getExtra();
16660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        menu.setGroupVisible(R.id.PHONE_MENU,
16670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                type == WebView.HitTestResult.PHONE_TYPE);
16680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        menu.setGroupVisible(R.id.EMAIL_MENU,
16690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                type == WebView.HitTestResult.EMAIL_TYPE);
16700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        menu.setGroupVisible(R.id.GEO_MENU,
16710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                type == WebView.HitTestResult.GEO_TYPE);
16720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        menu.setGroupVisible(R.id.IMAGE_MENU,
16730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                type == WebView.HitTestResult.IMAGE_TYPE
16740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                || type == WebView.HitTestResult.SRC_IMAGE_ANCHOR_TYPE);
16750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        menu.setGroupVisible(R.id.ANCHOR_MENU,
16760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                type == WebView.HitTestResult.SRC_ANCHOR_TYPE
16770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                || type == WebView.HitTestResult.SRC_IMAGE_ANCHOR_TYPE);
16780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
16790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Setup custom handling depending on the type
16800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        switch (type) {
16810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case WebView.HitTestResult.PHONE_TYPE:
16820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.setHeaderTitle(Uri.decode(extra));
16830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.dial_context_menu_id).setIntent(
16840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new Intent(Intent.ACTION_VIEW, Uri
16850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                .parse(WebView.SCHEME_TEL + extra)));
16860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                Intent addIntent = new Intent(Intent.ACTION_INSERT_OR_EDIT);
16870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                addIntent.putExtra(Insert.PHONE, Uri.decode(extra));
16885e335a381a0cd66e94117b202c1f34f5cb29c9b8Cary Clark                addIntent.setType(ContactsContract.Contacts.CONTENT_ITEM_TYPE);
16890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.add_contact_context_menu_id).setIntent(
16900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        addIntent);
16910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.copy_phone_context_menu_id).setOnMenuItemClickListener(
16920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new Copy(extra));
16930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
16940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
16950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case WebView.HitTestResult.EMAIL_TYPE:
16960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.setHeaderTitle(extra);
16970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.email_context_menu_id).setIntent(
16980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new Intent(Intent.ACTION_VIEW, Uri
16990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                .parse(WebView.SCHEME_MAILTO + extra)));
17000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.copy_mail_context_menu_id).setOnMenuItemClickListener(
17010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new Copy(extra));
17020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
17030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
17040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case WebView.HitTestResult.GEO_TYPE:
17050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.setHeaderTitle(extra);
17060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.map_context_menu_id).setIntent(
17070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new Intent(Intent.ACTION_VIEW, Uri
17080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                .parse(WebView.SCHEME_GEO
17090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        + URLEncoder.encode(extra))));
17100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.copy_geo_context_menu_id).setOnMenuItemClickListener(
17110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new Copy(extra));
17120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
17130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
17140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case WebView.HitTestResult.SRC_ANCHOR_TYPE:
17150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case WebView.HitTestResult.SRC_IMAGE_ANCHOR_TYPE:
17160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                TextView titleView = (TextView) LayoutInflater.from(this)
17170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        .inflate(android.R.layout.browser_link_context_header,
17180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        null);
17190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                titleView.setText(extra);
17200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.setHeaderView(titleView);
17210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // decide whether to show the open link in new tab option
17229e997c7c92175c8e24cef90e265cc35fd9b8710eLeon Scroggins III                boolean showNewTab = mTabControl.canCreateNewTab();
17239e997c7c92175c8e24cef90e265cc35fd9b8710eLeon Scroggins III                MenuItem newTabItem
17249e997c7c92175c8e24cef90e265cc35fd9b8710eLeon Scroggins III                        = menu.findItem(R.id.open_newtab_context_menu_id);
17259e997c7c92175c8e24cef90e265cc35fd9b8710eLeon Scroggins III                newTabItem.setVisible(showNewTab);
17269e997c7c92175c8e24cef90e265cc35fd9b8710eLeon Scroggins III                if (showNewTab) {
17279e997c7c92175c8e24cef90e265cc35fd9b8710eLeon Scroggins III                    newTabItem.setOnMenuItemClickListener(
17289e997c7c92175c8e24cef90e265cc35fd9b8710eLeon Scroggins III                            new MenuItem.OnMenuItemClickListener() {
17299e997c7c92175c8e24cef90e265cc35fd9b8710eLeon Scroggins III                                public boolean onMenuItemClick(MenuItem item) {
17309e997c7c92175c8e24cef90e265cc35fd9b8710eLeon Scroggins III                                    final Tab parent = mTabControl.getCurrentTab();
173168792c84eded7f83e2f086d3efe81f9cfc07f9c3Michael Kolb                                    final Tab newTab = openTab(extra, false);
17329e997c7c92175c8e24cef90e265cc35fd9b8710eLeon Scroggins III                                    if (newTab != parent) {
17339e997c7c92175c8e24cef90e265cc35fd9b8710eLeon Scroggins III                                        parent.addChildTab(newTab);
17349e997c7c92175c8e24cef90e265cc35fd9b8710eLeon Scroggins III                                    }
17359e997c7c92175c8e24cef90e265cc35fd9b8710eLeon Scroggins III                                    return true;
17369e997c7c92175c8e24cef90e265cc35fd9b8710eLeon Scroggins III                                }
17379e997c7c92175c8e24cef90e265cc35fd9b8710eLeon Scroggins III                            });
17389e997c7c92175c8e24cef90e265cc35fd9b8710eLeon Scroggins III                }
1739de353621650d17a412b6ffe2cbf0366db5f11c40Ben Murdoch                menu.findItem(R.id.bookmark_context_menu_id).setVisible(
1740de353621650d17a412b6ffe2cbf0366db5f11c40Ben Murdoch                        Bookmarks.urlHasAcceptableScheme(extra));
17410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                PackageManager pm = getPackageManager();
17420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                Intent send = new Intent(Intent.ACTION_SEND);
17430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                send.setType("text/plain");
17440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                ResolveInfo ri = pm.resolveActivity(send, PackageManager.MATCH_DEFAULT_ONLY);
17450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.share_link_context_menu_id).setVisible(ri != null);
17460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (type == WebView.HitTestResult.SRC_ANCHOR_TYPE) {
17470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    break;
17480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
17490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // otherwise fall through to handle image part
17500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case WebView.HitTestResult.IMAGE_TYPE:
17510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (type == WebView.HitTestResult.IMAGE_TYPE) {
17520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    menu.setHeaderTitle(extra);
17530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
17540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.view_image_context_menu_id).setIntent(
17550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new Intent(Intent.ACTION_VIEW, Uri.parse(extra)));
17560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.download_context_menu_id).
17570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        setOnMenuItemClickListener(new Download(extra));
17584f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                menu.findItem(R.id.set_wallpaper_context_menu_id).
17594f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                        setOnMenuItemClickListener(new SetAsWallpaper(extra));
17600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
17610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
17620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            default:
17630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                Log.w(LOGTAG, "We should not get here.");
17640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
17650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
1766b2b19f501ee05448ca81bddaaca70e9b2f51cb54Leon Scroggins        hideFakeTitleBar();
17670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
17680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
17690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Attach the given tab to the content view.
1770c928c30a51eee84b40cb7045842c288c1cfafff0Grace Kloba    // this should only be called for the current tab.
177122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private void attachTabToContentView(Tab t) {
17722bc69918d97a767a02132090e58718077381ba1aSteve Block        // Attach the container that contains the main WebView and any other UI
17732bc69918d97a767a02132090e58718077381ba1aSteve Block        // associated with the tab.
1774d0119535d0c490e087be114ae8fd1639bb1945dcPatrick Scott        t.attachTabToContentView(mContentView);
1775bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch
1776bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch        if (mShouldShowErrorConsole) {
177722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            ErrorConsoleView errorConsole = t.getErrorConsole(true);
1778bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch            if (errorConsole.numberOfErrors() == 0) {
1779bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch                errorConsole.showConsole(ErrorConsoleView.SHOW_NONE);
1780bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch            } else {
1781bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch                errorConsole.showConsole(ErrorConsoleView.SHOW_MINIMIZED);
1782bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch            }
1783bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch
1784bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch            mErrorConsoleContainer.addView(errorConsole,
178515b8ec6b226f4d57307716e1f495e10a91f8cbf4Romain Guy                    new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
1786bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch                                                  ViewGroup.LayoutParams.WRAP_CONTENT));
1787bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch        }
1788bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch
1789a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb        WebView view = t.getWebView();
1790a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb        view.setEmbeddedTitleBar(mTitleBar);
179158d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        if (t.isInVoiceSearchMode()) {
179258d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins            showVoiceTitleBar(t.getVoiceDisplayTitle());
179358d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        } else {
179458d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins            revertVoiceTitleBar();
179558d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        }
17960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Request focus on the top window.
17970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        t.getTopWindow().requestFocus();
1798a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb        if (mTabControl.getTabChangeListener() != null) {
1799a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb            mTabControl.getTabChangeListener().onCurrentTab(t);
1800a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb        }
18010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
18020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
18030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Attach a sub window to the main WebView of the given tab.
180422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void attachSubWindow(Tab t) {
1805d0119535d0c490e087be114ae8fd1639bb1945dcPatrick Scott        t.attachSubWindow(mContentView);
1806d0119535d0c490e087be114ae8fd1639bb1945dcPatrick Scott        getTopWindow().requestFocus();
18070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
18080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
18090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Remove the given tab from the content view.
181022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private void removeTabFromContentView(Tab t) {
18112bc69918d97a767a02132090e58718077381ba1aSteve Block        // Remove the container that contains the main WebView.
1812d0119535d0c490e087be114ae8fd1639bb1945dcPatrick Scott        t.removeTabFromContentView(mContentView);
1813bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch
181422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        ErrorConsoleView errorConsole = t.getErrorConsole(false);
181522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (errorConsole != null) {
181622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mErrorConsoleContainer.removeView(errorConsole);
1817bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch        }
1818bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch
1819a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb        WebView view = t.getWebView();
1820a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb        if (view != null) {
1821a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb            view.setEmbeddedTitleBar(null);
1822bb85b9016201d45ea939d7cb7edd0ba6616a111cLeon Scroggins        }
18230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
18240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
18250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Remove the sub window if it exists. Also called by TabControl when the
18260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // user clicks the 'X' to dismiss a sub window.
182722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /* package */ void dismissSubWindow(Tab t) {
1828d0119535d0c490e087be114ae8fd1639bb1945dcPatrick Scott        t.removeSubWindow(mContentView);
182922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // dismiss the subwindow. This will destroy the WebView.
183022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        t.dismissSubWindow();
1831d0119535d0c490e087be114ae8fd1639bb1945dcPatrick Scott        getTopWindow().requestFocus();
18320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
18330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
18341f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins    // A wrapper function of {@link #openTabAndShow(UrlData, boolean, String)}
183525ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima    // that accepts url as string.
183622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private Tab openTabAndShow(String url, boolean closeOnExit, String appId) {
18371f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins        return openTabAndShow(new UrlData(url), closeOnExit, appId);
18380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
18390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
18400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // This method does a ton of stuff. It will attempt to create a new tab
18410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // if we haven't reached MAX_TABS. Otherwise it uses the current tab. If
18421f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins    // url isn't null, it will load the given url.
184322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /* package */Tab openTabAndShow(UrlData urlData, boolean closeOnExit,
184422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            String appId) {
184522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        final Tab currentTab = mTabControl.getCurrentTab();
184622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mTabControl.canCreateNewTab()) {
184722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            final Tab tab = mTabControl.createNewTab(closeOnExit, appId,
1848f0f03954b3092296c58dcb040e2dabd1696dd5c4Elliott Slaughter                    urlData.mUrl, false);
18491f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins            WebView webview = tab.getWebView();
18500a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins            // If the last tab was removed from the active tabs page, currentTab
18510a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins            // will be null.
18520a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins            if (currentTab != null) {
18530a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins                removeTabFromContentView(currentTab);
18540a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins            }
18558bbd69f50abd537bfe7eb314b3a3e20241ac22bdPatrick Scott            // We must set the new tab as the current tab to reflect the old
18568bbd69f50abd537bfe7eb314b3a3e20241ac22bdPatrick Scott            // animation behavior.
18578bbd69f50abd537bfe7eb314b3a3e20241ac22bdPatrick Scott            mTabControl.setCurrentTab(tab);
1858eb6eef4c45df2d65c3e70660493a147a2be405e3Grace Kloba            attachTabToContentView(tab);
1859160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins            if (!urlData.isEmpty()) {
18609d53da05812f959745810a33bb4e06b273393c42Patrick Scott                loadUrlDataIn(tab, urlData);
18610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
18621f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins            return tab;
186364b80f3efd95d7b5192731e995ccde79c4c6c11fLeon Scroggins        } else {
18641f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins            // Get rid of the subwindow if it exists
18651f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins            dismissSubWindow(currentTab);
18661f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins            if (!urlData.isEmpty()) {
18671f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                // Load the given url.
18689d53da05812f959745810a33bb4e06b273393c42Patrick Scott                loadUrlDataIn(currentTab, urlData);
18690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
187058d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins            return currentTab;
18710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
18720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
18730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
187468792c84eded7f83e2f086d3efe81f9cfc07f9c3Michael Kolb    private Tab openTab(String url, boolean forceForeground) {
187568792c84eded7f83e2f086d3efe81f9cfc07f9c3Michael Kolb        if (mSettings.openInBackground() && !forceForeground) {
187622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            Tab t = mTabControl.createNewTab();
18770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (t != null) {
18781f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                WebView view = t.getWebView();
187992472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins                loadUrl(view, url);
18800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
1881c9181841c7ed6b9f7dfc953eab8dc7ba1047022cGrace Kloba            return t;
18820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
18831f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins            return openTabAndShow(url, false, null);
18840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
18850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
18860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
1887f0f03954b3092296c58dcb040e2dabd1696dd5c4Elliott Slaughter    /* package */ Tab openIncognitoTab() {
1888f0f03954b3092296c58dcb040e2dabd1696dd5c4Elliott Slaughter        if (mTabControl.canCreateNewTab()) {
1889f0f03954b3092296c58dcb040e2dabd1696dd5c4Elliott Slaughter            Tab currentTab = mTabControl.getCurrentTab();
1890f0f03954b3092296c58dcb040e2dabd1696dd5c4Elliott Slaughter            Tab tab = mTabControl.createNewTab(false, null, null, true);
1891f0f03954b3092296c58dcb040e2dabd1696dd5c4Elliott Slaughter            if (currentTab != null) {
1892f0f03954b3092296c58dcb040e2dabd1696dd5c4Elliott Slaughter                removeTabFromContentView(currentTab);
1893f0f03954b3092296c58dcb040e2dabd1696dd5c4Elliott Slaughter            }
1894f0f03954b3092296c58dcb040e2dabd1696dd5c4Elliott Slaughter            mTabControl.setCurrentTab(tab);
1895f0f03954b3092296c58dcb040e2dabd1696dd5c4Elliott Slaughter            attachTabToContentView(tab);
1896f0f03954b3092296c58dcb040e2dabd1696dd5c4Elliott Slaughter            return tab;
1897f0f03954b3092296c58dcb040e2dabd1696dd5c4Elliott Slaughter        }
1898f0f03954b3092296c58dcb040e2dabd1696dd5c4Elliott Slaughter        return null;
1899f0f03954b3092296c58dcb040e2dabd1696dd5c4Elliott Slaughter    }
1900f0f03954b3092296c58dcb040e2dabd1696dd5c4Elliott Slaughter
19010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private class Copy implements OnMenuItemClickListener {
19020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        private CharSequence mText;
19030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
19040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public boolean onMenuItemClick(MenuItem item) {
19050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            copy(mText);
19060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return true;
19070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
19080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
19090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public Copy(CharSequence toCopy) {
19100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mText = toCopy;
19110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
19120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
19130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
19140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private class Download implements OnMenuItemClickListener {
19150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        private String mText;
19160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
19170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public boolean onMenuItemClick(MenuItem item) {
19180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            onDownloadStartNoStream(mText, null, null, null, -1);
19190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return true;
19200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
19210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
19220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public Download(String toDownload) {
19230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mText = toDownload;
19240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
19250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
19260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
19274f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch    private class SetAsWallpaper extends Thread implements
19284f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch            OnMenuItemClickListener, DialogInterface.OnCancelListener {
19294f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch        private URL mUrl;
19304f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch        private ProgressDialog mWallpaperProgress;
19314f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch        private boolean mCanceled = false;
19324f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch
19334f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch        public SetAsWallpaper(String url) {
19344f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch            try {
19354f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                mUrl = new URL(url);
19364f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch            } catch (MalformedURLException e) {
19374f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                mUrl = null;
19384f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch            }
19394f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch        }
19404f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch
19414f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch        public void onCancel(DialogInterface dialog) {
19424f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch            mCanceled = true;
19434f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch        }
19444f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch
19454f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch        public boolean onMenuItemClick(MenuItem item) {
19464f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch            if (mUrl != null) {
19474f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                // The user may have tried to set a image with a large file size as their
19484f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                // background so it may take a few moments to perform the operation. Display
19494f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                // a progress spinner while it is working.
19504f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                mWallpaperProgress = new ProgressDialog(BrowserActivity.this);
19514f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                mWallpaperProgress.setIndeterminate(true);
19524f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                mWallpaperProgress.setMessage(getText(R.string.progress_dialog_setting_wallpaper));
19534f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                mWallpaperProgress.setCancelable(true);
19544f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                mWallpaperProgress.setOnCancelListener(this);
19554f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                mWallpaperProgress.show();
19564f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                start();
19574f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch            }
19584f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch            return true;
19594f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch        }
19604f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch
1961e0a3666b5c0dca7352895fa8b9b4fbb2237df721Michael Kolb        @Override
19624f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch        public void run() {
19634f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch            Drawable oldWallpaper = BrowserActivity.this.getWallpaper();
19644f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch            try {
19654f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                // TODO: This will cause the resource to be downloaded again, when we
19664f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                // should in most cases be able to grab it from the cache. To fix this
19674f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                // we should query WebCore to see if we can access a cached version and
19684f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                // instead open an input stream on that. This pattern could also be used
19694f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                // in the download manager where the same problem exists.
19704f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                InputStream inputstream = mUrl.openStream();
19714f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                if (inputstream != null) {
19724f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                    setWallpaper(inputstream);
19734f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                }
19744f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch            } catch (IOException e) {
19754f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                Log.e(LOGTAG, "Unable to set new wallpaper");
19764f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                // Act as though the user canceled the operation so we try to
19774f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                // restore the old wallpaper.
19784f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                mCanceled = true;
19794f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch            }
19804f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch
19814f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch            if (mCanceled) {
19824f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                // Restore the old wallpaper if the user cancelled whilst we were setting
19834f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                // the new wallpaper.
19844f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                int width = oldWallpaper.getIntrinsicWidth();
19854f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                int height = oldWallpaper.getIntrinsicHeight();
19864f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                Bitmap bm = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);
19874f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                Canvas canvas = new Canvas(bm);
19884f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                oldWallpaper.setBounds(0, 0, width, height);
19894f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                oldWallpaper.draw(canvas);
19904f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                try {
19914f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                    setWallpaper(bm);
19924f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                } catch (IOException e) {
19934f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                    Log.e(LOGTAG, "Unable to restore old wallpaper.");
19944f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                }
19954f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                mCanceled = false;
19964f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch            }
19974f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch
19984f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch            if (mWallpaperProgress.isShowing()) {
19994f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                mWallpaperProgress.dismiss();
20004f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch            }
20014f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch        }
20024f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch    }
20034f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch
20040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void copy(CharSequence text) {
200580f32627140aefe828ad539f66fc439d1580bae7Dianne Hackborn        ClipboardManager cm = (ClipboardManager)getSystemService(Context.CLIPBOARD_SERVICE);
200680f32627140aefe828ad539f66fc439d1580bae7Dianne Hackborn        cm.setText(text);
20070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
20080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
20090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
20100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Resets the browser title-view to whatever it must be
20110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * (for example, if we had a loading error)
20120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * When we have a new page, we call resetTitle, when we
20130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * have to reset the titlebar to whatever it used to be
20140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * (for example, if the user chose to stop loading), we
20150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * call resetTitleAndRevertLockIcon.
20160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
20170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /* package */ void resetTitleAndRevertLockIcon() {
201822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mTabControl.getCurrentTab().revertLockIcon();
201922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        updateLockIconToLatest();
20200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        resetTitleIconAndProgress();
20210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
20220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
20230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
20240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Reset the title, favicon, and progress.
20250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
20260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void resetTitleIconAndProgress() {
20270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebView current = mTabControl.getCurrentWebView();
20280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (current == null) {
20290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
20300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
20310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        resetTitleAndIcon(current);
20320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        int progress = current.getProgress();
203322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        current.getWebChromeClient().onProgressChanged(current, progress);
20340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
20350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
20360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Reset the title and the icon based on the given item.
20370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void resetTitleAndIcon(WebView view) {
20380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebHistoryItem item = view.copyBackForwardList().getCurrentItem();
20390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (item != null) {
204068579393973f745fc65a2781061af9bb8f2d7020Leon Scroggins            setUrlTitle(item.getUrl(), item.getTitle());
20410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            setFavicon(item.getFavicon());
20420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
204368579393973f745fc65a2781061af9bb8f2d7020Leon Scroggins            setUrlTitle(null, null);
20440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            setFavicon(null);
20450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
20460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
20470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
20480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
20490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Sets a title composed of the URL and the title string.
20500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param url The URL of the site being loaded.
20510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param title The title of the site being loaded.
20520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
205322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void setUrlTitle(String url, String title) {
20540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mUrl = url;
20550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mTitle = title;
20560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
205758d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        // If we are in voice search mode, the title has already been set.
205858d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        if (mTabControl.getCurrentTab().isInVoiceSearchMode()) return;
205958d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        mTitleBar.setDisplayTitle(url);
2060a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb        mFakeTitleBar.setDisplayTitle(url);
20610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
20620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
20630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
20640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param url The URL to build a title version of the URL from.
20650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @return The title version of the URL or null if fails.
20660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * The title version of the URL can be either the URL hostname,
20670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * or the hostname with an "https://" prefix (for secure URLs),
20680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * or an empty string if, for example, the URL in question is a
20690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * file:// URL with no hostname.
20700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
207132e14a6deccfa75490b3032bb4ddd5ae90f89de8Leon Scroggins    /* package */ static String buildTitleUrl(String url) {
20720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String titleUrl = null;
20730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
20740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (url != null) {
20750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            try {
20760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // parse the url string
20770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                URL urlObj = new URL(url);
20780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (urlObj != null) {
20790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    titleUrl = "";
20800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
20810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    String protocol = urlObj.getProtocol();
20820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    String host = urlObj.getHost();
20830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
20840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    if (host != null && 0 < host.length()) {
20850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        titleUrl = host;
20860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        if (protocol != null) {
20870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            // if a secure site, add an "https://" prefix!
20880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            if (protocol.equalsIgnoreCase("https")) {
20890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                titleUrl = protocol + "://" + host;
20900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            }
20910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }
20920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
20930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
20940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } catch (MalformedURLException e) {}
20950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
20960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
20970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return titleUrl;
20980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
20990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
21000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Set the favicon in the title bar.
210122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void setFavicon(Bitmap icon) {
210268579393973f745fc65a2781061af9bb8f2d7020Leon Scroggins        mTitleBar.setFavicon(icon);
2103a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb        mFakeTitleBar.setFavicon(icon);
21040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
21050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
21060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
21070a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins     * Close the tab, remove its associated title bar, and adjust mTabControl's
21080a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins     * current tab to a valid value.
21091f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins     */
211022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /* package */ void closeTab(Tab t) {
21110a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins        int currentIndex = mTabControl.getCurrentIndex();
21120a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins        int removeIndex = mTabControl.getTabIndex(t);
21131f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins        mTabControl.removeTab(t);
21140a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins        if (currentIndex >= removeIndex && currentIndex != 0) {
21150a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins            currentIndex--;
21160a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins        }
21170a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins        mTabControl.setCurrentTab(mTabControl.getTab(currentIndex));
2118a5bf1deca120315a2643ea5b010f94d853461b15Andrei Popescu        resetTitleIconAndProgress();
2119654899b4b7a280efc01aac4977b74369024e5c94Leon Scroggins        updateLockIconToLatest();
2120e440a88fd81c86d1ca6fc18b8b3f68e383e574b4Elliott Slaughter
2121e440a88fd81c86d1ca6fc18b8b3f68e383e574b4Elliott Slaughter        if (!mTabControl.hasAnyOpenIncognitoTabs()) {
2122e440a88fd81c86d1ca6fc18b8b3f68e383e574b4Elliott Slaughter            WebView.cleanupPrivateBrowsingFiles(this);
2123e440a88fd81c86d1ca6fc18b8b3f68e383e574b4Elliott Slaughter        }
21240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
21250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
2126dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins    /* package */ void goBackOnePageOrQuit() {
212722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        Tab current = mTabControl.getCurrentTab();
21280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (current == null) {
21290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            /*
21300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project             * Instead of finishing the activity, simply push this to the back
21310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project             * of the stack and let ActivityManager to choose the foreground
21320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project             * activity. As BrowserActivity is singleTask, it will be always the
21330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project             * root of the task. So we can use either true or false for
21340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project             * moveTaskToBack().
21350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project             */
21360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            moveTaskToBack(true);
213700d85e74921459b34e70eb93368245b4c0a9bf5fGrace Kloba            return;
21380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
21390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebView w = current.getWebView();
21400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (w.canGoBack()) {
21410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            w.goBack();
21420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
21430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Check to see if we are closing a window that was created by
21440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // another window. If so, we switch back to that window.
214522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            Tab parent = current.getParentTab();
21460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (parent != null) {
21471f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                switchToTab(mTabControl.getTabIndex(parent));
21481f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                // Now we close the other tab
21491f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                closeTab(current);
21500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } else {
21510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (current.closeOnExit()) {
215222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    // force the tab's inLoad() to be false as we are going to
215322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    // either finish the activity or remove the tab. This will
215422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    // ensure pauseWebViewTimers() taking action.
215522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    mTabControl.getCurrentTab().clearInLoad();
21560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    if (mTabControl.getTabCount() == 1) {
21570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        finish();
21580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        return;
21590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
21607bfa63b55644fbf2da1fe6a24b3be0267529202cMike Reed                    // call pauseWebViewTimers() now, we won't be able to call
21617bfa63b55644fbf2da1fe6a24b3be0267529202cMike Reed                    // it in onPause() as the WebView won't be valid.
2162ec1b5ad8d8283b1fbbc5d7fa1cd50ef95b9e594dGrace Kloba                    // Temporarily change mActivityInPause to be true as
2163ec1b5ad8d8283b1fbbc5d7fa1cd50ef95b9e594dGrace Kloba                    // pauseWebViewTimers() will do nothing if mActivityInPause
2164ec1b5ad8d8283b1fbbc5d7fa1cd50ef95b9e594dGrace Kloba                    // is false.
2165918e1d78b2db6ef21c71a07868572d9cda498476Grace Kloba                    boolean savedState = mActivityInPause;
2166918e1d78b2db6ef21c71a07868572d9cda498476Grace Kloba                    if (savedState) {
2167ec1b5ad8d8283b1fbbc5d7fa1cd50ef95b9e594dGrace Kloba                        Log.e(LOGTAG, "BrowserActivity is already paused "
2168ec1b5ad8d8283b1fbbc5d7fa1cd50ef95b9e594dGrace Kloba                                + "while handing goBackOnePageOrQuit.");
2169918e1d78b2db6ef21c71a07868572d9cda498476Grace Kloba                    }
2170918e1d78b2db6ef21c71a07868572d9cda498476Grace Kloba                    mActivityInPause = true;
21717bfa63b55644fbf2da1fe6a24b3be0267529202cMike Reed                    pauseWebViewTimers();
2172918e1d78b2db6ef21c71a07868572d9cda498476Grace Kloba                    mActivityInPause = savedState;
21730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    removeTabFromContentView(current);
21740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    mTabControl.removeTab(current);
21750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
21760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                /*
21770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                 * Instead of finishing the activity, simply push this to the back
21780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                 * of the stack and let ActivityManager to choose the foreground
21790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                 * activity. As BrowserActivity is singleTask, it will be always the
21800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                 * root of the task. So we can use either true or false for
21810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                 * moveTaskToBack().
21820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                 */
21830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                moveTaskToBack(true);
21840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
21850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
21860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
21870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
218822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    boolean isMenuDown() {
218922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return mMenuIsDown;
219022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
219122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
21925942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba    @Override
21935942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba    public boolean onKeyDown(int keyCode, KeyEvent event) {
2194f65b50ddd2f7ed1205002d74082fff1ac2336d5cLeon Scroggins        // Even if MENU is already held down, we need to call to super to open
2195f65b50ddd2f7ed1205002d74082fff1ac2336d5cLeon Scroggins        // the IME on long press.
2196f65b50ddd2f7ed1205002d74082fff1ac2336d5cLeon Scroggins        if (KeyEvent.KEYCODE_MENU == keyCode) {
2197f65b50ddd2f7ed1205002d74082fff1ac2336d5cLeon Scroggins            mMenuIsDown = true;
2198f65b50ddd2f7ed1205002d74082fff1ac2336d5cLeon Scroggins            return super.onKeyDown(keyCode, event);
2199f65b50ddd2f7ed1205002d74082fff1ac2336d5cLeon Scroggins        }
22005942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba        // The default key mode is DEFAULT_KEYS_SEARCH_LOCAL. As the MENU is
22015942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba        // still down, we don't want to trigger the search. Pretend to consume
22025942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba        // the key and do nothing.
22035942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba        if (mMenuIsDown) return true;
22045942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba
22055942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba        switch(keyCode) {
22065942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba            case KeyEvent.KEYCODE_SPACE:
2207da0fe556a00773ce2af25eb6dcc5442bd08c7addGrace Kloba                // WebView/WebTextView handle the keys in the KeyDown. As
2208da0fe556a00773ce2af25eb6dcc5442bd08c7addGrace Kloba                // the Activity's shortcut keys are only handled when WebView
2209da0fe556a00773ce2af25eb6dcc5442bd08c7addGrace Kloba                // doesn't, have to do it in onKeyDown instead of onKeyUp.
2210da0fe556a00773ce2af25eb6dcc5442bd08c7addGrace Kloba                if (event.isShiftPressed()) {
2211da0fe556a00773ce2af25eb6dcc5442bd08c7addGrace Kloba                    getTopWindow().pageUp(false);
2212da0fe556a00773ce2af25eb6dcc5442bd08c7addGrace Kloba                } else {
2213da0fe556a00773ce2af25eb6dcc5442bd08c7addGrace Kloba                    getTopWindow().pageDown(false);
2214da0fe556a00773ce2af25eb6dcc5442bd08c7addGrace Kloba                }
22155942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                return true;
22165942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba            case KeyEvent.KEYCODE_BACK:
22175942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                if (event.getRepeatCount() == 0) {
22185942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                    event.startTracking();
22195942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                    return true;
22205942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                } else if (mCustomView == null && mActiveTabsPage == null
22215942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                        && event.isLongPress()) {
222268792c84eded7f83e2f086d3efe81f9cfc07f9c3Michael Kolb                    bookmarksOrHistoryPicker(true, false);
22235942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                    return true;
22240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
22255942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                break;
22260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
22275942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba        return super.onKeyDown(keyCode, event);
22280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
22290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
22305942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba    @Override
22315942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba    public boolean onKeyUp(int keyCode, KeyEvent event) {
22325942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba        switch(keyCode) {
22335942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba            case KeyEvent.KEYCODE_MENU:
22345942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                mMenuIsDown = false;
22355942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                break;
22365942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba            case KeyEvent.KEYCODE_BACK:
22375942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                if (event.isTracking() && !event.isCanceled()) {
22385942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                    if (mCustomView != null) {
22395942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                        // if a custom view is showing, hide it
224022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        mTabControl.getCurrentWebView().getWebChromeClient()
224122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                .onHideCustomView();
22425942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                    } else if (mActiveTabsPage != null) {
22435942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                        // if tab page is showing, hide it
22445942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                        removeActiveTabPage(true);
22450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    } else {
22465942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                        WebView subwindow = mTabControl.getCurrentSubWindow();
22475942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                        if (subwindow != null) {
22485942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                            if (subwindow.canGoBack()) {
22495942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                                subwindow.goBack();
22505942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                            } else {
22515942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                                dismissSubWindow(mTabControl.getCurrentTab());
22525942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                            }
22535942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                        } else {
22545942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                            goBackOnePageOrQuit();
22555942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                        }
22560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
22575942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                    return true;
22585942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                }
22595942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                break;
22600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
22615942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba        return super.onKeyUp(keyCode, event);
22620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
22630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
226468579393973f745fc65a2781061af9bb8f2d7020Leon Scroggins    /* package */ void stopLoading() {
2265b7cc8b439dc595dc48e1c2183b35d23ad72dfbe5Ben Murdoch        mDidStopLoad = true;
22660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        resetTitleAndRevertLockIcon();
22670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebView w = getTopWindow();
22680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        w.stopLoading();
226922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // FIXME: before refactor, it is using mWebViewClient. So I keep the
227022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // same logic here. But for subwindow case, should we call into the main
227122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // WebView's onPageFinished as we never call its onPageStarted and if
227222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // the page finishes itself, we don't call onPageFinished.
227322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mTabControl.getCurrentWebView().getWebViewClient().onPageFinished(w,
227422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                w.getUrl());
22750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
22760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        cancelStopToast();
22770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mStopToast = Toast
22780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .makeText(this, R.string.stopping, Toast.LENGTH_SHORT);
22790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mStopToast.show();
22800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
22810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
228222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    boolean didUserStopLoading() {
228322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return mDidStopLoad;
228422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
228522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
22860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void cancelStopToast() {
22870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mStopToast != null) {
22880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mStopToast.cancel();
22890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mStopToast = null;
22900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
22910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
22920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
229322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // called by a UI or non-UI thread to post the message
229422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    public void postMessage(int what, int arg1, int arg2, Object obj,
229522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            long delayMillis) {
229622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mHandler.sendMessageDelayed(mHandler.obtainMessage(what, arg1, arg2,
229722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                obj), delayMillis);
229822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
229922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
230022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // called by a UI or non-UI thread to remove the message
230122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void removeMessages(int what, Object object) {
230222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mHandler.removeMessages(what, object);
23030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
23040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
23050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // public message ids
23060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public final static int LOAD_URL                = 1001;
23070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public final static int STOP_LOAD               = 1002;
23080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
23090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Message Ids
23100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private static final int FOCUS_NODE_HREF         = 102;
231192c18a52ca7a79c114028b5ba22c3dfe443bd1a4Grace Kloba    private static final int RELEASE_WAKELOCK        = 107;
23120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
231322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    static final int UPDATE_BOOKMARK_THUMBNAIL       = 108;
23142694e23a55d5ca526fc29534a80a200e2c58698bBen Murdoch
2315eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch    private static final int TOUCH_ICON_DOWNLOADED   = 109;
2316eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch
2317300b7f0951f3688a8e41f190b57cbf8b3bc06170Michael Kolb    private static final int OPEN_BOOKMARKS = 201;
2318300b7f0951f3688a8e41f190b57cbf8b3bc06170Michael Kolb
23190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Private handler for handling javascript and saving passwords
23200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private Handler mHandler = new Handler() {
23210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
2322e0a3666b5c0dca7352895fa8b9b4fbb2237df721Michael Kolb        @Override
23230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public void handleMessage(Message msg) {
23240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            switch (msg.what) {
2325300b7f0951f3688a8e41f190b57cbf8b3bc06170Michael Kolb                case OPEN_BOOKMARKS:
2326300b7f0951f3688a8e41f190b57cbf8b3bc06170Michael Kolb                    bookmarksOrHistoryPicker(false, false);
2327300b7f0951f3688a8e41f190b57cbf8b3bc06170Michael Kolb                    break;
23280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                case FOCUS_NODE_HREF:
23292694e23a55d5ca526fc29534a80a200e2c58698bBen Murdoch                {
23300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    String url = (String) msg.getData().get("url");
233190d088caeee718f89755ee9c25249ba6da15ab97Ben Murdoch                    String title = (String) msg.getData().get("title");
23320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    if (url == null || url.length() == 0) {
23330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        break;
23340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
23350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    HashMap focusNodeMap = (HashMap) msg.obj;
23360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    WebView view = (WebView) focusNodeMap.get("webview");
23370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // Only apply the action if the top window did not change.
23380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    if (getTopWindow() != view) {
23390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        break;
23400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
23410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    switch (msg.arg1) {
23420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        case R.id.open_context_menu_id:
23430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        case R.id.view_image_context_menu_id:
234492472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins                            loadUrlFromContext(getTopWindow(), url);
23450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            break;
23460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        case R.id.bookmark_context_menu_id:
23470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            Intent intent = new Intent(BrowserActivity.this,
23480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    AddBookmarkPage.class);
23490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            intent.putExtra("url", url);
235090d088caeee718f89755ee9c25249ba6da15ab97Ben Murdoch                            intent.putExtra("title", title);
23510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            startActivity(intent);
23520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            break;
23530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        case R.id.share_link_context_menu_id:
23543e20445506307d2c8d699e1d17fb82a0cedde1d0Leon Scroggins                            sharePage(BrowserActivity.this, title, url, null,
235596afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                                    null);
23560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            break;
23570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        case R.id.copy_link_context_menu_id:
23580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            copy(url);
23590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            break;
23600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        case R.id.save_link_context_menu_id:
23610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        case R.id.download_context_menu_id:
23620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            onDownloadStartNoStream(url, null, null, null, -1);
23630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            break;
23640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
23650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    break;
23662694e23a55d5ca526fc29534a80a200e2c58698bBen Murdoch                }
23670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
23680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                case LOAD_URL:
236992472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins                    loadUrlFromContext(getTopWindow(), (String) msg.obj);
23700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    break;
23710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
23720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                case STOP_LOAD:
23730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    stopLoading();
23740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    break;
23750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
23760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                case RELEASE_WAKELOCK:
23770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    if (mWakeLock.isHeld()) {
23780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        mWakeLock.release();
23795d0e02e646e46b14289168f75c2a8f6ed43cac54Grace Kloba                        // if we reach here, Browser should be still in the
23805d0e02e646e46b14289168f75c2a8f6ed43cac54Grace Kloba                        // background loading after WAKELOCK_TIMEOUT (5-min).
23815d0e02e646e46b14289168f75c2a8f6ed43cac54Grace Kloba                        // To avoid burning the battery, stop loading.
23825d0e02e646e46b14289168f75c2a8f6ed43cac54Grace Kloba                        mTabControl.stopAllLoading();
23830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
23840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    break;
23852694e23a55d5ca526fc29534a80a200e2c58698bBen Murdoch
23862694e23a55d5ca526fc29534a80a200e2c58698bBen Murdoch                case UPDATE_BOOKMARK_THUMBNAIL:
23872694e23a55d5ca526fc29534a80a200e2c58698bBen Murdoch                    WebView view = (WebView) msg.obj;
23882694e23a55d5ca526fc29534a80a200e2c58698bBen Murdoch                    if (view != null) {
23892694e23a55d5ca526fc29534a80a200e2c58698bBen Murdoch                        updateScreenshot(view);
23902694e23a55d5ca526fc29534a80a200e2c58698bBen Murdoch                    }
23912694e23a55d5ca526fc29534a80a200e2c58698bBen Murdoch                    break;
2392eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch
2393eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch                case TOUCH_ICON_DOWNLOADED:
2394eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch                    Bundle b = msg.getData();
2395eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch                    showSaveToHomescreenDialog(b.getString("url"),
2396eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch                        b.getString("title"),
2397eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch                        (Bitmap) b.getParcelable("touchIcon"),
2398eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch                        (Bitmap) b.getParcelable("favicon"));
2399eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch                    break;
24000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
24010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
24020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    };
24030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
240496afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins    /**
240596afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins     * Share a page, providing the title, url, favicon, and a screenshot.  Uses
240696afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins     * an {@link Intent} to launch the Activity chooser.
240796afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins     * @param c Context used to launch a new Activity.
240896afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins     * @param title Title of the page.  Stored in the Intent with
240903e6d39560d7de359782485d4c863d600b34fb51Paul Westbrook     *          {@link Intent#EXTRA_SUBJECT}
241096afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins     * @param url URL of the page.  Stored in the Intent with
241196afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins     *          {@link Intent#EXTRA_TEXT}
241296afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins     * @param favicon Bitmap of the favicon for the page.  Stored in the Intent
241396afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins     *          with {@link Browser#EXTRA_SHARE_FAVICON}
241496afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins     * @param screenshot Bitmap of a screenshot of the page.  Stored in the
241596afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins     *          Intent with {@link Browser#EXTRA_SHARE_SCREENSHOT}
241696afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins     */
241796afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins    public static final void sharePage(Context c, String title, String url,
241896afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins            Bitmap favicon, Bitmap screenshot) {
241996afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins        Intent send = new Intent(Intent.ACTION_SEND);
242096afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins        send.setType("text/plain");
242196afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins        send.putExtra(Intent.EXTRA_TEXT, url);
242203e6d39560d7de359782485d4c863d600b34fb51Paul Westbrook        send.putExtra(Intent.EXTRA_SUBJECT, title);
242396afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins        send.putExtra(Browser.EXTRA_SHARE_FAVICON, favicon);
242496afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins        send.putExtra(Browser.EXTRA_SHARE_SCREENSHOT, screenshot);
242596afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins        try {
242696afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins            c.startActivity(Intent.createChooser(send, c.getString(
242796afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                    R.string.choosertitle_sharevia)));
242896afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins        } catch(android.content.ActivityNotFoundException ex) {
242996afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins            // if no app handles it, do nothing
243096afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins        }
243196afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins    }
243296afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins
243389c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins    private void updateScreenshot(WebView view) {
243489c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins        // If this is a bookmarked site, add a screenshot to the database.
243589c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins        // FIXME: When should we update?  Every time?
243689c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins        // FIXME: Would like to make sure there is actually something to
243789c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins        // draw, but the API for that (WebViewCore.pictureReady()) is not
243889c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins        // currently accessible here.
2439aac7aa6fcfcb519755987ec126be066323f589c8Ben Murdoch
244087cc65d95c80c5e3a1c343ad5177a7dc2de874f6Ben Murdoch        final Bitmap bm = createScreenshot(view, getDesiredThumbnailWidth(this),
244187cc65d95c80c5e3a1c343ad5177a7dc2de874f6Ben Murdoch                getDesiredThumbnailHeight(this));
2442cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott        if (bm == null) {
2443cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott            return;
2444cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott        }
2445cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott
2446cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott        final ContentResolver cr = getContentResolver();
2447cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott        final String url = view.getUrl();
2448cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott        final String originalUrl = view.getOriginalUrl();
2449cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott
2450cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott        new AsyncTask<Void, Void, Void>() {
2451cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott            @Override
2452cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott            protected Void doInBackground(Void... unused) {
2453cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott                Cursor c = null;
2454cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott                try {
24558402962ef58546d3cfd48fbb211b5e36df0f118eJeff Hamilton                    c = Bookmarks.queryBookmarksForUrl(
24568ce956c6076a89aae85856f35b94bad7fc8fa1f1Jeff Hamilton                            cr, originalUrl, url);
2457cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott                    if (c != null) {
2458cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott                        if (c.moveToFirst()) {
2459cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott                            ContentValues values = new ContentValues();
2460cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott                            final ByteArrayOutputStream os
2461cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott                                    = new ByteArrayOutputStream();
2462cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott                            bm.compress(Bitmap.CompressFormat.PNG, 100, os);
24638ce956c6076a89aae85856f35b94bad7fc8fa1f1Jeff Hamilton                            values.put(BrowserContract.Bookmarks.THUMBNAIL,
2464cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott                                    os.toByteArray());
2465cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott                            do {
2466cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott                                cr.update(ContentUris.withAppendedId(
24678ce956c6076a89aae85856f35b94bad7fc8fa1f1Jeff Hamilton                                        BrowserContract.Bookmarks.CONTENT_URI, c.getLong(0)),
2468cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott                                        values, null, null);
2469cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott                            } while (c.moveToNext());
2470cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott                        }
24714580057e772b60433272af5cd691825748892693Leon Scroggins                    }
2472cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott                } catch (IllegalStateException e) {
2473cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott                    // Ignore
2474cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott                } finally {
2475cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott                    if (c != null) c.close();
247689c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins                }
2477cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott                return null;
247889c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins            }
2479cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott        }.execute();
248089c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins    }
248189c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins
248206ec5f2d8735d1ba17b779deb0f8da032e0a62eaLeon Scroggins    /**
2483f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins     * Return the desired width for thumbnail screenshots, which are stored in
2484f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins     * the database, and used on the bookmarks screen.
2485f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins     * @param context Context for finding out the density of the screen.
2486f3026374dccf7b491152946c5d0e42daec08d899Jeff Hamilton     * @return desired width for thumbnail screenshot.
2487f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins     */
2488f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins    /* package */ static int getDesiredThumbnailWidth(Context context) {
2489f3026374dccf7b491152946c5d0e42daec08d899Jeff Hamilton        return context.getResources().getDimensionPixelOffset(R.dimen.bookmarkThumbnailWidth);
2490f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins    }
2491f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins
2492f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins    /**
2493f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins     * Return the desired height for thumbnail screenshots, which are stored in
2494f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins     * the database, and used on the bookmarks screen.
2495f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins     * @param context Context for finding out the density of the screen.
2496f3026374dccf7b491152946c5d0e42daec08d899Jeff Hamilton     * @return desired height for thumbnail screenshot.
2497f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins     */
2498f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins    /* package */ static int getDesiredThumbnailHeight(Context context) {
2499f3026374dccf7b491152946c5d0e42daec08d899Jeff Hamilton        return context.getResources().getDimensionPixelOffset(R.dimen.bookmarkThumbnailHeight);
2500f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins    }
250106ec5f2d8735d1ba17b779deb0f8da032e0a62eaLeon Scroggins
250287cc65d95c80c5e3a1c343ad5177a7dc2de874f6Ben Murdoch    private Bitmap createScreenshot(WebView view, int width, int height) {
2503dcc2b6f08dd5677bc6ba761a9ba6f1c655113051Ben Murdoch        Picture thumbnail = view.capturePicture();
25044580057e772b60433272af5cd691825748892693Leon Scroggins        if (thumbnail == null) {
25054580057e772b60433272af5cd691825748892693Leon Scroggins            return null;
25064580057e772b60433272af5cd691825748892693Leon Scroggins        }
250787cc65d95c80c5e3a1c343ad5177a7dc2de874f6Ben Murdoch        Bitmap bm = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);
2508dcc2b6f08dd5677bc6ba761a9ba6f1c655113051Ben Murdoch        Canvas canvas = new Canvas(bm);
2509dcc2b6f08dd5677bc6ba761a9ba6f1c655113051Ben Murdoch        // May need to tweak these values to determine what is the
2510dcc2b6f08dd5677bc6ba761a9ba6f1c655113051Ben Murdoch        // best scale factor
25112694e23a55d5ca526fc29534a80a200e2c58698bBen Murdoch        int thumbnailWidth = thumbnail.getWidth();
2512ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch        int thumbnailHeight = thumbnail.getHeight();
2513ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch        float scaleFactorX = 1.0f;
2514ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch        float scaleFactorY = 1.0f;
25152694e23a55d5ca526fc29534a80a200e2c58698bBen Murdoch        if (thumbnailWidth > 0) {
251687cc65d95c80c5e3a1c343ad5177a7dc2de874f6Ben Murdoch            scaleFactorX = (float) width / (float)thumbnailWidth;
2517ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch        } else {
2518ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch            return null;
251906ec5f2d8735d1ba17b779deb0f8da032e0a62eaLeon Scroggins        }
2520ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch
2521ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch        if (view.getWidth() > view.getHeight() &&
2522ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch                thumbnailHeight < view.getHeight() && thumbnailHeight > 0) {
2523ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch            // If the device is in landscape and the page is shorter
2524ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch            // than the height of the view, stretch the thumbnail to fill the
2525ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch            // space.
252687cc65d95c80c5e3a1c343ad5177a7dc2de874f6Ben Murdoch            scaleFactorY = (float) height / (float)thumbnailHeight;
2527ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch        } else {
2528ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch            // In the portrait case, this looks nice.
2529ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch            scaleFactorY = scaleFactorX;
2530ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch        }
2531ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch
2532ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch        canvas.scale(scaleFactorX, scaleFactorY);
2533ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch
2534dcc2b6f08dd5677bc6ba761a9ba6f1c655113051Ben Murdoch        thumbnail.draw(canvas);
2535dcc2b6f08dd5677bc6ba761a9ba6f1c655113051Ben Murdoch        return bm;
2536dcc2b6f08dd5677bc6ba761a9ba6f1c655113051Ben Murdoch    }
2537dcc2b6f08dd5677bc6ba761a9ba6f1c655113051Ben Murdoch
25380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // -------------------------------------------------------------------------
253922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // Helper function for WebViewClient.
25400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    //-------------------------------------------------------------------------
25410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
25420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Use in overrideUrlLoading
25430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /* package */ final static String SCHEME_WTAI = "wtai://wp/";
25440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /* package */ final static String SCHEME_WTAI_MC = "wtai://wp/mc;";
25450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /* package */ final static String SCHEME_WTAI_SD = "wtai://wp/sd;";
25460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /* package */ final static String SCHEME_WTAI_AP = "wtai://wp/ap;";
25470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
254892472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins    // Keep this initial progress in sync with initialProgressValue (* 100)
254992472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins    // in ProgressTracker.cpp
255092472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins    private final static int INITIAL_PROGRESS = 10;
255192472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins
255222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void onPageStarted(WebView view, String url, Bitmap favicon) {
255322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // when BrowserActivity just starts, onPageStarted may be called before
255422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // onResume as it is triggered from onCreate. Call resumeWebViewTimers
255522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // to start the timer. As we won't switch tabs while an activity is in
255622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // pause state, we can ensure calling resume and pause in pair.
255722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mActivityInPause) resumeWebViewTimers();
255822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
255922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        resetLockIcon(url);
256022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        setUrlTitle(url, null);
256122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        setFavicon(favicon);
25628cf8f682e90f004d4b8028d2f5b74f72c0cf4e19Leon Scroggins        // Show some progress so that the user knows the page is beginning to
25638cf8f682e90f004d4b8028d2f5b74f72c0cf4e19Leon Scroggins        // load
256492472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins        onProgressChanged(view, INITIAL_PROGRESS);
256522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mDidStopLoad = false;
256622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (!mIsNetworkUp) createAndShowNetworkDialog();
25678e4fbf1b26c2cc05a56ba2d4e7d1eda7d1574e91Leon Scroggins III        endActionMode();
256822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mSettings.isTracing()) {
256922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            String host;
257022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            try {
257122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                WebAddress uri = new WebAddress(url);
257222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                host = uri.mHost;
257322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            } catch (android.net.ParseException ex) {
257422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                host = "browser";
257522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
257622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            host = host.replace('.', '_');
257722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            host += ".trace";
257822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mInTrace = true;
257922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            Debug.startMethodTracing(host, 20 * 1024 * 1024);
258015525d48024d325c8a52766d8ca727191251a8d4Patrick Scott        }
258115525d48024d325c8a52766d8ca727191251a8d4Patrick Scott
258222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Performance probe
258322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (false) {
258422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mStart = SystemClock.uptimeMillis();
258522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mProcessStart = Process.getElapsedCpuTime();
258622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            long[] sysCpu = new long[7];
258722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (Process.readProcFile("/proc/stat", SYSTEM_CPU_FORMAT, null,
258822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    sysCpu, null)) {
258922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                mUserStart = sysCpu[0] + sysCpu[1];
259022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                mSystemStart = sysCpu[2];
259122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                mIdleStart = sysCpu[3];
259222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                mIrqStart = sysCpu[4] + sysCpu[5] + sysCpu[6];
259322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
259422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mUiStart = SystemClock.currentThreadTimeMillis();
25950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
25960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
25970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
259822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void onPageFinished(WebView view, String url) {
259922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Reset the title and icon in case we stopped a provisional load.
260022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        resetTitleAndIcon(view);
260122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Update the lock icon image only once we are done loading
260222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        updateLockIconToLatest();
260322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // pause the WebView timer and release the wake lock if it is finished
260422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // while BrowserActivity is in pause state.
260522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mActivityInPause && pauseWebViewTimers()) {
260622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (mWakeLock.isHeld()) {
260722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                mHandler.removeMessages(RELEASE_WAKELOCK);
260822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                mWakeLock.release();
260922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
261022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
261122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
261222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Performance probe
261322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (false) {
261422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            long[] sysCpu = new long[7];
261522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (Process.readProcFile("/proc/stat", SYSTEM_CPU_FORMAT, null,
261622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    sysCpu, null)) {
261722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                String uiInfo = "UI thread used "
261822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        + (SystemClock.currentThreadTimeMillis() - mUiStart)
261922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        + " ms";
262022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                if (LOGD_ENABLED) {
262122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    Log.d(LOGTAG, uiInfo);
262222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                }
262322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                //The string that gets written to the log
262422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                String performanceString = "It took total "
262522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        + (SystemClock.uptimeMillis() - mStart)
262622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        + " ms clock time to load the page."
262722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        + "\nbrowser process used "
262822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        + (Process.getElapsedCpuTime() - mProcessStart)
262922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        + " ms, user processes used "
263022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        + (sysCpu[0] + sysCpu[1] - mUserStart) * 10
263122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        + " ms, kernel used "
263222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        + (sysCpu[2] - mSystemStart) * 10
263322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        + " ms, idle took " + (sysCpu[3] - mIdleStart) * 10
263422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        + " ms and irq took "
263522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        + (sysCpu[4] + sysCpu[5] + sysCpu[6] - mIrqStart)
263622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        * 10 + " ms, " + uiInfo;
263722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                if (LOGD_ENABLED) {
263822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    Log.d(LOGTAG, performanceString + "\nWebpage: " + url);
26390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
264022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                if (url != null) {
264122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    // strip the url to maintain consistency
264222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    String newUrl = new String(url);
264322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    if (newUrl.startsWith("http://www.")) {
264422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        newUrl = newUrl.substring(11);
264522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    } else if (newUrl.startsWith("http://")) {
264622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        newUrl = newUrl.substring(7);
264722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    } else if (newUrl.startsWith("https://www.")) {
264822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        newUrl = newUrl.substring(12);
264922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    } else if (newUrl.startsWith("https://")) {
265022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        newUrl = newUrl.substring(8);
26510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
265231a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort                    if (LOGD_ENABLED) {
265322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        Log.d(LOGTAG, newUrl + " loaded");
26540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
26550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
26560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
265722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         }
26580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
265922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mInTrace) {
266022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mInTrace = false;
266122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            Debug.stopMethodTracing();
26620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
266322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
26640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
2665e7fe26bb1af55ec9e1535dcff8c9611692a7132dGrace Kloba    private void closeEmptyChildTab() {
2666e7fe26bb1af55ec9e1535dcff8c9611692a7132dGrace Kloba        Tab current = mTabControl.getCurrentTab();
2667e7fe26bb1af55ec9e1535dcff8c9611692a7132dGrace Kloba        if (current != null
2668e7fe26bb1af55ec9e1535dcff8c9611692a7132dGrace Kloba                && current.getWebView().copyBackForwardList().getSize() == 0) {
2669e7fe26bb1af55ec9e1535dcff8c9611692a7132dGrace Kloba            Tab parent = current.getParentTab();
2670e7fe26bb1af55ec9e1535dcff8c9611692a7132dGrace Kloba            if (parent != null) {
2671e7fe26bb1af55ec9e1535dcff8c9611692a7132dGrace Kloba                switchToTab(mTabControl.getTabIndex(parent));
2672e7fe26bb1af55ec9e1535dcff8c9611692a7132dGrace Kloba                closeTab(current);
2673e7fe26bb1af55ec9e1535dcff8c9611692a7132dGrace Kloba            }
2674e7fe26bb1af55ec9e1535dcff8c9611692a7132dGrace Kloba        }
2675e7fe26bb1af55ec9e1535dcff8c9611692a7132dGrace Kloba    }
2676e7fe26bb1af55ec9e1535dcff8c9611692a7132dGrace Kloba
267722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    boolean shouldOverrideUrlLoading(WebView view, String url) {
267822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (url.startsWith(SCHEME_WTAI)) {
267922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // wtai://wp/mc;number
268022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // number=string(phone-number)
268122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (url.startsWith(SCHEME_WTAI_MC)) {
268222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                Intent intent = new Intent(Intent.ACTION_VIEW,
268322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        Uri.parse(WebView.SCHEME_TEL +
268422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        url.substring(SCHEME_WTAI_MC.length())));
268522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                startActivity(intent);
2686e7fe26bb1af55ec9e1535dcff8c9611692a7132dGrace Kloba                // before leaving BrowserActivity, close the empty child tab.
2687e7fe26bb1af55ec9e1535dcff8c9611692a7132dGrace Kloba                // If a new tab is created through JavaScript open to load this
2688e7fe26bb1af55ec9e1535dcff8c9611692a7132dGrace Kloba                // url, we would like to close it as we will load this url in a
2689e7fe26bb1af55ec9e1535dcff8c9611692a7132dGrace Kloba                // different Activity.
2690e7fe26bb1af55ec9e1535dcff8c9611692a7132dGrace Kloba                closeEmptyChildTab();
269122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                return true;
26920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
269322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // wtai://wp/sd;dtmf
269422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // dtmf=string(dialstring)
269522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (url.startsWith(SCHEME_WTAI_SD)) {
269622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                // TODO: only send when there is active voice connection
26979918943559193e3e047a1c18442e2cdb0fe22b15Dianne Hackborn                return false;
26989918943559193e3e047a1c18442e2cdb0fe22b15Dianne Hackborn            }
269922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // wtai://wp/ap;number;name
270022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // number=string(phone-number)
270122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // name=string
270222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (url.startsWith(SCHEME_WTAI_AP)) {
270322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                // TODO
27040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                return false;
27050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
27060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
27070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
270822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // The "about:" schemes are internal to the browser; don't want these to
270922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // be dispatched to other apps.
271022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (url.startsWith("about:")) {
271122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            return false;
27120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
27130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
271443610292590fe3e2f8d0ddba1adf9e5557c0f401Jeff Davidson        // If this is a Google search, attempt to add an RLZ string (if one isn't already present).
271543610292590fe3e2f8d0ddba1adf9e5557c0f401Jeff Davidson        if (rlzProviderPresent()) {
271643610292590fe3e2f8d0ddba1adf9e5557c0f401Jeff Davidson            Uri siteUri = Uri.parse(url);
271743610292590fe3e2f8d0ddba1adf9e5557c0f401Jeff Davidson            if (needsRlzString(siteUri)) {
271843610292590fe3e2f8d0ddba1adf9e5557c0f401Jeff Davidson                String rlz = null;
271943610292590fe3e2f8d0ddba1adf9e5557c0f401Jeff Davidson                Cursor cur = null;
272043610292590fe3e2f8d0ddba1adf9e5557c0f401Jeff Davidson                try {
272143610292590fe3e2f8d0ddba1adf9e5557c0f401Jeff Davidson                    cur = getContentResolver().query(getRlzUri(), null, null, null, null);
272243610292590fe3e2f8d0ddba1adf9e5557c0f401Jeff Davidson                    if (cur != null && cur.moveToFirst() && !cur.isNull(0)) {
272343610292590fe3e2f8d0ddba1adf9e5557c0f401Jeff Davidson                        url = siteUri.buildUpon()
272443610292590fe3e2f8d0ddba1adf9e5557c0f401Jeff Davidson                                     .appendQueryParameter("rlz", cur.getString(0))
272543610292590fe3e2f8d0ddba1adf9e5557c0f401Jeff Davidson                                     .build().toString();
272643610292590fe3e2f8d0ddba1adf9e5557c0f401Jeff Davidson                    }
272743610292590fe3e2f8d0ddba1adf9e5557c0f401Jeff Davidson                } finally {
272843610292590fe3e2f8d0ddba1adf9e5557c0f401Jeff Davidson                    if (cur != null) {
272943610292590fe3e2f8d0ddba1adf9e5557c0f401Jeff Davidson                        cur.close();
273043610292590fe3e2f8d0ddba1adf9e5557c0f401Jeff Davidson                    }
273143610292590fe3e2f8d0ddba1adf9e5557c0f401Jeff Davidson                }
273243610292590fe3e2f8d0ddba1adf9e5557c0f401Jeff Davidson                loadUrl(view, url);
273343610292590fe3e2f8d0ddba1adf9e5557c0f401Jeff Davidson                return true;
273443610292590fe3e2f8d0ddba1adf9e5557c0f401Jeff Davidson            }
273543610292590fe3e2f8d0ddba1adf9e5557c0f401Jeff Davidson        }
273643610292590fe3e2f8d0ddba1adf9e5557c0f401Jeff Davidson
273722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        Intent intent;
273822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // perform generic parsing of the URI to turn it into an Intent.
273922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        try {
274022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            intent = Intent.parseUri(url, Intent.URI_INTENT_SCHEME);
274122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        } catch (URISyntaxException ex) {
274222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            Log.w("Browser", "Bad URI " + url + ": " + ex.getMessage());
274322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            return false;
27440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
27450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
274622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // check whether the intent can be resolved. If not, we will see
274722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // whether we can download it from the Market.
274822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (getPackageManager().resolveActivity(intent, 0) == null) {
274922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            String packagename = intent.getPackage();
275022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (packagename != null) {
275122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                intent = new Intent(Intent.ACTION_VIEW, Uri
275222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        .parse("market://search?q=pname:" + packagename));
275322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                intent.addCategory(Intent.CATEGORY_BROWSABLE);
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            } else {
27620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                return false;
27630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
27640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
27650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
276622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // sanitize the Intent, ensuring web pages can not bypass browser
276722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // security (only access to BROWSABLE activities).
276822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        intent.addCategory(Intent.CATEGORY_BROWSABLE);
276922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        intent.setComponent(null);
277022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        try {
277122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (startActivityIfNeeded(intent, -1)) {
2772e7fe26bb1af55ec9e1535dcff8c9611692a7132dGrace Kloba                // before leaving BrowserActivity, close the empty child tab.
2773e7fe26bb1af55ec9e1535dcff8c9611692a7132dGrace Kloba                // If a new tab is created through JavaScript open to load this
2774e7fe26bb1af55ec9e1535dcff8c9611692a7132dGrace Kloba                // url, we would like to close it as we will load this url in a
2775e7fe26bb1af55ec9e1535dcff8c9611692a7132dGrace Kloba                // different Activity.
2776e7fe26bb1af55ec9e1535dcff8c9611692a7132dGrace Kloba                closeEmptyChildTab();
27770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                return true;
27780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
277922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        } catch (ActivityNotFoundException ex) {
278022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // ignore the error. If no application can handle the URL,
278122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // eg about:blank, assume the browser can handle it.
278222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
27830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
278422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mMenuIsDown) {
278568792c84eded7f83e2f086d3efe81f9cfc07f9c3Michael Kolb            openTab(url, false);
278622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            closeOptionsMenu();
27870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return true;
27880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
278922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return false;
279022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
27910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
279243610292590fe3e2f8d0ddba1adf9e5557c0f401Jeff Davidson    // Determine whether the RLZ provider is present on the system.
279343610292590fe3e2f8d0ddba1adf9e5557c0f401Jeff Davidson    private boolean rlzProviderPresent() {
279443610292590fe3e2f8d0ddba1adf9e5557c0f401Jeff Davidson        if (mIsProviderPresent == null) {
279543610292590fe3e2f8d0ddba1adf9e5557c0f401Jeff Davidson            PackageManager pm = getPackageManager();
279643610292590fe3e2f8d0ddba1adf9e5557c0f401Jeff Davidson            mIsProviderPresent = pm.resolveContentProvider(BrowserSettings.RLZ_PROVIDER, 0) != null;
279743610292590fe3e2f8d0ddba1adf9e5557c0f401Jeff Davidson        }
279843610292590fe3e2f8d0ddba1adf9e5557c0f401Jeff Davidson        return mIsProviderPresent;
279943610292590fe3e2f8d0ddba1adf9e5557c0f401Jeff Davidson    }
280043610292590fe3e2f8d0ddba1adf9e5557c0f401Jeff Davidson
280143610292590fe3e2f8d0ddba1adf9e5557c0f401Jeff Davidson    // Retrieve the RLZ access point string and cache the URI used to retrieve RLZ values.
280243610292590fe3e2f8d0ddba1adf9e5557c0f401Jeff Davidson    private Uri getRlzUri() {
280343610292590fe3e2f8d0ddba1adf9e5557c0f401Jeff Davidson        if (mRlzUri == null) {
280443610292590fe3e2f8d0ddba1adf9e5557c0f401Jeff Davidson            String ap = getResources().getString(R.string.rlz_access_point);
280543610292590fe3e2f8d0ddba1adf9e5557c0f401Jeff Davidson            mRlzUri = Uri.withAppendedPath(BrowserSettings.RLZ_PROVIDER_URI, ap);
280643610292590fe3e2f8d0ddba1adf9e5557c0f401Jeff Davidson        }
280743610292590fe3e2f8d0ddba1adf9e5557c0f401Jeff Davidson        return mRlzUri;
280843610292590fe3e2f8d0ddba1adf9e5557c0f401Jeff Davidson    }
280943610292590fe3e2f8d0ddba1adf9e5557c0f401Jeff Davidson
281043610292590fe3e2f8d0ddba1adf9e5557c0f401Jeff Davidson    // Determine if this URI appears to be for a Google search and does not have an RLZ parameter.
281143610292590fe3e2f8d0ddba1adf9e5557c0f401Jeff Davidson    // Taken largely from Chrome source, src/chrome/browser/google_url_tracker.cc
281243610292590fe3e2f8d0ddba1adf9e5557c0f401Jeff Davidson    private static boolean needsRlzString(Uri uri) {
2813c50e71a184ed1963d2358e92b4e196653d0a29faBill Napier        String scheme = uri.getScheme();
2814c50e71a184ed1963d2358e92b4e196653d0a29faBill Napier        if (("http".equals(scheme) || "https".equals(scheme)) &&
2815c50e71a184ed1963d2358e92b4e196653d0a29faBill Napier            (uri.getQueryParameter("q") != null) && (uri.getQueryParameter("rlz") == null)) {
281643610292590fe3e2f8d0ddba1adf9e5557c0f401Jeff Davidson            String host = uri.getHost();
281743610292590fe3e2f8d0ddba1adf9e5557c0f401Jeff Davidson            if (host == null) {
281843610292590fe3e2f8d0ddba1adf9e5557c0f401Jeff Davidson                return false;
281943610292590fe3e2f8d0ddba1adf9e5557c0f401Jeff Davidson            }
282043610292590fe3e2f8d0ddba1adf9e5557c0f401Jeff Davidson            String[] hostComponents = host.split("\\.");
282143610292590fe3e2f8d0ddba1adf9e5557c0f401Jeff Davidson
282243610292590fe3e2f8d0ddba1adf9e5557c0f401Jeff Davidson            if (hostComponents.length < 2) {
282343610292590fe3e2f8d0ddba1adf9e5557c0f401Jeff Davidson                return false;
282443610292590fe3e2f8d0ddba1adf9e5557c0f401Jeff Davidson            }
282543610292590fe3e2f8d0ddba1adf9e5557c0f401Jeff Davidson            int googleComponent = hostComponents.length - 2;
282643610292590fe3e2f8d0ddba1adf9e5557c0f401Jeff Davidson            String component = hostComponents[googleComponent];
282743610292590fe3e2f8d0ddba1adf9e5557c0f401Jeff Davidson            if (!"google".equals(component)) {
282843610292590fe3e2f8d0ddba1adf9e5557c0f401Jeff Davidson                if (hostComponents.length < 3 ||
282943610292590fe3e2f8d0ddba1adf9e5557c0f401Jeff Davidson                        (!"co".equals(component) && !"com".equals(component))) {
283043610292590fe3e2f8d0ddba1adf9e5557c0f401Jeff Davidson                    return false;
283143610292590fe3e2f8d0ddba1adf9e5557c0f401Jeff Davidson                }
283243610292590fe3e2f8d0ddba1adf9e5557c0f401Jeff Davidson                googleComponent = hostComponents.length - 3;
283343610292590fe3e2f8d0ddba1adf9e5557c0f401Jeff Davidson                if (!"google".equals(hostComponents[googleComponent])) {
283443610292590fe3e2f8d0ddba1adf9e5557c0f401Jeff Davidson                    return false;
283543610292590fe3e2f8d0ddba1adf9e5557c0f401Jeff Davidson                }
283643610292590fe3e2f8d0ddba1adf9e5557c0f401Jeff Davidson            }
283743610292590fe3e2f8d0ddba1adf9e5557c0f401Jeff Davidson
283843610292590fe3e2f8d0ddba1adf9e5557c0f401Jeff Davidson            // Google corp network handling.
283943610292590fe3e2f8d0ddba1adf9e5557c0f401Jeff Davidson            if (googleComponent > 0 && "corp".equals(hostComponents[googleComponent - 1])) {
284043610292590fe3e2f8d0ddba1adf9e5557c0f401Jeff Davidson                return false;
284143610292590fe3e2f8d0ddba1adf9e5557c0f401Jeff Davidson            }
284243610292590fe3e2f8d0ddba1adf9e5557c0f401Jeff Davidson
284343610292590fe3e2f8d0ddba1adf9e5557c0f401Jeff Davidson            return true;
284443610292590fe3e2f8d0ddba1adf9e5557c0f401Jeff Davidson        }
284543610292590fe3e2f8d0ddba1adf9e5557c0f401Jeff Davidson        return false;
284643610292590fe3e2f8d0ddba1adf9e5557c0f401Jeff Davidson    }
284743610292590fe3e2f8d0ddba1adf9e5557c0f401Jeff Davidson
284822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // -------------------------------------------------------------------------
284922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // Helper function for WebChromeClient
285022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // -------------------------------------------------------------------------
28510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
285222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void onProgressChanged(WebView view, int newProgress) {
2853a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb
2854a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb        // On the phone, the fake title bar will always cover up the
2855a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb        // regular title bar (or the regular one is offscreen), so only the
2856a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb        // fake title bar needs to change its progress
2857a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb        mFakeTitleBar.setProgress(newProgress);
285822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
285922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (newProgress == 100) {
286022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // onProgressChanged() may continue to be called after the main
286122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // frame has finished loading, as any remaining sub frames continue
286222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // to load. We'll only get called once though with newProgress as
286322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // 100 when everything is loaded. (onPageFinished is called once
286422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // when the main frame completes loading regardless of the state of
286522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // any sub frames so calls to onProgressChanges may continue after
286622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // onPageFinished has executed)
286722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (mInLoad) {
286822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                mInLoad = false;
2869a27ff19e24cb1c9fef5624dbc4554548349b5b31Leon Scroggins                updateInLoadMenuItems();
287022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                // If the options menu is open, leave the title bar
287122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                if (!mOptionsMenuOpen || !mIconView) {
287222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    hideFakeTitleBar();
28730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
28740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
2875aa37e7fdb52d0180b8eea25d53950c5c0791f968Leon Scroggins        } else {
2876aa37e7fdb52d0180b8eea25d53950c5c0791f968Leon Scroggins            if (!mInLoad) {
2877aa37e7fdb52d0180b8eea25d53950c5c0791f968Leon Scroggins                // onPageFinished may have already been called but a subframe is
2878aa37e7fdb52d0180b8eea25d53950c5c0791f968Leon Scroggins                // still loading and updating the progress. Reset mInLoad and
2879aa37e7fdb52d0180b8eea25d53950c5c0791f968Leon Scroggins                // update the menu items.
2880aa37e7fdb52d0180b8eea25d53950c5c0791f968Leon Scroggins                mInLoad = true;
2881aa37e7fdb52d0180b8eea25d53950c5c0791f968Leon Scroggins                updateInLoadMenuItems();
2882aa37e7fdb52d0180b8eea25d53950c5c0791f968Leon Scroggins            }
2883aa37e7fdb52d0180b8eea25d53950c5c0791f968Leon Scroggins            // When the page first begins to load, the Activity may still be
2884aa37e7fdb52d0180b8eea25d53950c5c0791f968Leon Scroggins            // paused, in which case showFakeTitleBar will do nothing.  Call
2885aa37e7fdb52d0180b8eea25d53950c5c0791f968Leon Scroggins            // again as the page continues to load so that it will be shown.
2886aa37e7fdb52d0180b8eea25d53950c5c0791f968Leon Scroggins            // (Calling it will the fake title bar is already showing will also
2887aa37e7fdb52d0180b8eea25d53950c5c0791f968Leon Scroggins            // do nothing.
288822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (!mOptionsMenuOpen || mIconView) {
288922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                // This page has begun to load, so show the title bar
289022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                showFakeTitleBar();
28913918d4443ff38ef1870e02aa51a8b29f8352bb1aPatrick Scott            }
28920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
289322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
2894092dd5d22d7f2ee0efcc68bd6e5a3afd1ea98953Ben Murdoch
289522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void onShowCustomView(View view, WebChromeClient.CustomViewCallback callback) {
28968ff57db0a8dc8eb659fbcdcd4a856208609e6070Derek Sollenberger        // if a view already exists then immediately terminate the new one
28978ff57db0a8dc8eb659fbcdcd4a856208609e6070Derek Sollenberger        if (mCustomView != null) {
28988ff57db0a8dc8eb659fbcdcd4a856208609e6070Derek Sollenberger            callback.onCustomViewHidden();
289922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            return;
29008ff57db0a8dc8eb659fbcdcd4a856208609e6070Derek Sollenberger        }
29012bc69918d97a767a02132090e58718077381ba1aSteve Block
290222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Add the custom view to its container.
290322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mCustomViewContainer.addView(view, COVER_SCREEN_GRAVITY_CENTER);
290422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mCustomView = view;
290522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mCustomViewCallback = callback;
290622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Save the menu state and set it to empty while the custom
290722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // view is showing.
290822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mOldMenuState = mMenuState;
290922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mMenuState = EMPTY_MENU;
291022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Hide the content view.
291122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mContentView.setVisibility(View.GONE);
291222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Finally show the custom view container.
2913163ab74e2f85b53a1a374c49677073fb64d35f28Andrei Popescu        setStatusBarVisibility(false);
291422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mCustomViewContainer.setVisibility(View.VISIBLE);
291522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mCustomViewContainer.bringToFront();
291622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
291722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
291822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void onHideCustomView() {
291922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mCustomView == null)
292022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            return;
29212bc69918d97a767a02132090e58718077381ba1aSteve Block
292222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Hide the custom view.
292322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mCustomView.setVisibility(View.GONE);
292422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Remove the custom view from its container.
292522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mCustomViewContainer.removeView(mCustomView);
292622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mCustomView = null;
292722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Reset the old menu state.
292822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mMenuState = mOldMenuState;
292922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mOldMenuState = EMPTY_MENU;
293022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mCustomViewContainer.setVisibility(View.GONE);
293122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mCustomViewCallback.onCustomViewHidden();
293222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Show the content view.
2933163ab74e2f85b53a1a374c49677073fb64d35f28Andrei Popescu        setStatusBarVisibility(true);
293422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mContentView.setVisibility(View.VISIBLE);
293522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
2936540035dfd1347c78eeec10ec0847e18fcc50ef36Andrei Popescu
293722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    Bitmap getDefaultVideoPoster() {
293822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mDefaultVideoPoster == null) {
293922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mDefaultVideoPoster = BitmapFactory.decodeResource(
294022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    getResources(), R.drawable.default_video_poster);
2941540035dfd1347c78eeec10ec0847e18fcc50ef36Andrei Popescu        }
294222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return mDefaultVideoPoster;
294322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
2944540035dfd1347c78eeec10ec0847e18fcc50ef36Andrei Popescu
294522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    View getVideoLoadingProgressView() {
294622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mVideoProgressView == null) {
294722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            LayoutInflater inflater = LayoutInflater.from(BrowserActivity.this);
294822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mVideoProgressView = inflater.inflate(
294922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    R.layout.video_loading_progress, null);
2950540035dfd1347c78eeec10ec0847e18fcc50ef36Andrei Popescu        }
295122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return mVideoProgressView;
295222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
29530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
29548d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins    /*
29558d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins     * The Object used to inform the WebView of the file to upload.
29568d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins     */
29578d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins    private ValueCallback<Uri> mUploadMessage;
295862b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch    private String mCameraFilePath;
295962b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch
296062b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch    void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType) {
296162b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch
296262b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch        final String imageMimeType = "image/*";
29636af492aeddda96c749142885e3b49455aa336309Ben Murdoch        final String videoMimeType = "video/*";
2964039bd47edd231965abb2c8e9b2dd32308cddb74bBen Murdoch        final String audioMimeType = "audio/*";
2965b50d7403816f316fdcaf5b5a318383e64f1a8775Ben Murdoch        final String mediaSourceKey = "capture";
29666af492aeddda96c749142885e3b49455aa336309Ben Murdoch        final String mediaSourceValueCamera = "camera";
2967b50d7403816f316fdcaf5b5a318383e64f1a8775Ben Murdoch        final String mediaSourceValueFileSystem = "filesystem";
29686af492aeddda96c749142885e3b49455aa336309Ben Murdoch        final String mediaSourceValueCamcorder = "camcorder";
2969039bd47edd231965abb2c8e9b2dd32308cddb74bBen Murdoch        final String mediaSourceValueMicrophone = "microphone";
297062b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch
2971039bd47edd231965abb2c8e9b2dd32308cddb74bBen Murdoch        // media source can be 'filesystem' or 'camera' or 'camcorder' or 'microphone'.
29726af492aeddda96c749142885e3b49455aa336309Ben Murdoch        String mediaSource = "";
297362b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch
29746af492aeddda96c749142885e3b49455aa336309Ben Murdoch        // We add the camera intent if there was no accept type (or '*/*' or 'image/*').
297562b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch        boolean addCameraIntent = true;
29766af492aeddda96c749142885e3b49455aa336309Ben Murdoch        // We add the camcorder intent if there was no accept type (or '*/*' or 'video/*').
29776af492aeddda96c749142885e3b49455aa336309Ben Murdoch        boolean addCamcorderIntent = true;
29786af492aeddda96c749142885e3b49455aa336309Ben Murdoch
29796af492aeddda96c749142885e3b49455aa336309Ben Murdoch        if (mUploadMessage != null) {
29806af492aeddda96c749142885e3b49455aa336309Ben Murdoch            // Already a file picker operation in progress.
29816af492aeddda96c749142885e3b49455aa336309Ben Murdoch            return;
29826af492aeddda96c749142885e3b49455aa336309Ben Murdoch        }
29838d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins
298422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mUploadMessage = uploadMsg;
298562b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch
298662b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch        // Parse the accept type.
298762b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch        String params[] = acceptType.split(";");
298862b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch        String mimeType = params[0];
298962b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch
299062b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch        for (String p : params) {
299162b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch            String[] keyValue = p.split("=");
299262b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch            if (keyValue.length == 2) {
299362b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch                // Process key=value parameters.
29946af492aeddda96c749142885e3b49455aa336309Ben Murdoch                if (mediaSourceKey.equals(keyValue[0])) {
29956af492aeddda96c749142885e3b49455aa336309Ben Murdoch                    mediaSource = keyValue[1];
299662b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch                }
299762b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch            }
299862b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch        }
299962b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch
300062b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch        // This intent will display the standard OPENABLE file picker.
300122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        Intent i = new Intent(Intent.ACTION_GET_CONTENT);
300222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        i.addCategory(Intent.CATEGORY_OPENABLE);
300362b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch
300462b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch        // Create an intent to add to the standard file picker that will
300562b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch        // capture an image from the camera. We'll combine this intent with
300662b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch        // the standard OPENABLE picker unless the web developer specifically
300762b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch        // requested the camera or gallery be opened by passing a parameter
300862b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch        // in the accept type.
300962b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch        Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
301062b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch        File externalDataDir = Environment.getExternalStoragePublicDirectory(
301162b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch                Environment.DIRECTORY_DCIM);
301262b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch        File cameraDataDir = new File(externalDataDir.getAbsolutePath() +
301362b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch                File.separator + "browser-photos");
301462b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch        cameraDataDir.mkdirs();
301562b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch        mCameraFilePath = cameraDataDir.getAbsolutePath() + File.separator +
301662b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch                System.currentTimeMillis() + ".jpg";
301762b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch        cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(new File(mCameraFilePath)));
301862b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch
30196af492aeddda96c749142885e3b49455aa336309Ben Murdoch        Intent camcorderIntent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
30206af492aeddda96c749142885e3b49455aa336309Ben Murdoch
3021039bd47edd231965abb2c8e9b2dd32308cddb74bBen Murdoch        Intent soundRecIntent = new Intent(MediaStore.Audio.Media.RECORD_SOUND_ACTION);
3022039bd47edd231965abb2c8e9b2dd32308cddb74bBen Murdoch
302362b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch        if (mimeType.equals(imageMimeType)) {
302462b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch            i.setType(imageMimeType);
30256af492aeddda96c749142885e3b49455aa336309Ben Murdoch            addCamcorderIntent = false;
30266af492aeddda96c749142885e3b49455aa336309Ben Murdoch            if (mediaSource.equals(mediaSourceValueCamera)) {
302762b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch                // Specified 'image/*' and requested the camera, so go ahead and launch the camera
302862b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch                // directly.
302962b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch                BrowserActivity.this.startActivityForResult(cameraIntent, FILE_SELECTED);
303062b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch                return;
3031b50d7403816f316fdcaf5b5a318383e64f1a8775Ben Murdoch            } else if (mediaSource.equals(mediaSourceValueFileSystem)) {
3032b50d7403816f316fdcaf5b5a318383e64f1a8775Ben Murdoch                // Specified filesytem as the source, so don't want to consider the camera.
303362b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch                addCameraIntent = false;
303462b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch            }
30356af492aeddda96c749142885e3b49455aa336309Ben Murdoch        } else if (mimeType.equals(videoMimeType)) {
30366af492aeddda96c749142885e3b49455aa336309Ben Murdoch            i.setType(videoMimeType);
30376af492aeddda96c749142885e3b49455aa336309Ben Murdoch            addCameraIntent = false;
30386af492aeddda96c749142885e3b49455aa336309Ben Murdoch            // The camcorder saves it's own file and returns it to us in the intent, so
30396af492aeddda96c749142885e3b49455aa336309Ben Murdoch            // we don't need to generate one here.
30406af492aeddda96c749142885e3b49455aa336309Ben Murdoch            mCameraFilePath = null;
30416af492aeddda96c749142885e3b49455aa336309Ben Murdoch
30426af492aeddda96c749142885e3b49455aa336309Ben Murdoch            if (mediaSource.equals(mediaSourceValueCamcorder)) {
3043039bd47edd231965abb2c8e9b2dd32308cddb74bBen Murdoch                // Specified 'video/*' and requested the camcorder, so go ahead and launch the
3044039bd47edd231965abb2c8e9b2dd32308cddb74bBen Murdoch                // camcorder directly.
30456af492aeddda96c749142885e3b49455aa336309Ben Murdoch                BrowserActivity.this.startActivityForResult(camcorderIntent, FILE_SELECTED);
30466af492aeddda96c749142885e3b49455aa336309Ben Murdoch                return;
3047b50d7403816f316fdcaf5b5a318383e64f1a8775Ben Murdoch            } else if (mediaSource.equals(mediaSourceValueFileSystem)) {
3048b50d7403816f316fdcaf5b5a318383e64f1a8775Ben Murdoch                // Specified filesystem as the source, so don't want to consider the camcorder.
30496af492aeddda96c749142885e3b49455aa336309Ben Murdoch                addCamcorderIntent = false;
30506af492aeddda96c749142885e3b49455aa336309Ben Murdoch            }
3051039bd47edd231965abb2c8e9b2dd32308cddb74bBen Murdoch        } else if (mimeType.equals(audioMimeType)) {
3052039bd47edd231965abb2c8e9b2dd32308cddb74bBen Murdoch            i.setType(audioMimeType);
3053039bd47edd231965abb2c8e9b2dd32308cddb74bBen Murdoch            addCameraIntent = false;
3054039bd47edd231965abb2c8e9b2dd32308cddb74bBen Murdoch            addCamcorderIntent = false;
3055039bd47edd231965abb2c8e9b2dd32308cddb74bBen Murdoch            if (mediaSource.equals(mediaSourceValueMicrophone)) {
3056039bd47edd231965abb2c8e9b2dd32308cddb74bBen Murdoch                // Specified 'audio/*' and requested microphone, so go ahead and launch the sound
3057039bd47edd231965abb2c8e9b2dd32308cddb74bBen Murdoch                // recorder.
3058039bd47edd231965abb2c8e9b2dd32308cddb74bBen Murdoch                BrowserActivity.this.startActivityForResult(soundRecIntent, FILE_SELECTED);
3059039bd47edd231965abb2c8e9b2dd32308cddb74bBen Murdoch                return;
3060039bd47edd231965abb2c8e9b2dd32308cddb74bBen Murdoch            }
3061039bd47edd231965abb2c8e9b2dd32308cddb74bBen Murdoch            // On a default system, there is no single option to open an audio "gallery". Both the
3062039bd47edd231965abb2c8e9b2dd32308cddb74bBen Murdoch            // sound recorder and music browser respond to the OPENABLE/audio/* intent unlike the
3063039bd47edd231965abb2c8e9b2dd32308cddb74bBen Murdoch            // image/* and video/* OPENABLE intents where the image / video gallery are the only
3064039bd47edd231965abb2c8e9b2dd32308cddb74bBen Murdoch            // respondants (and so the user is not prompted by default).
306562b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch        } else {
306662b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch            i.setType("*/*");
306762b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch        }
306862b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch
30696af492aeddda96c749142885e3b49455aa336309Ben Murdoch        // Combine the chooser and the extra choices (like camera or camcorder)
307062b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch        Intent chooser = new Intent(Intent.ACTION_CHOOSER);
307162b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch        chooser.putExtra(Intent.EXTRA_INTENT, i);
307262b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch
30736af492aeddda96c749142885e3b49455aa336309Ben Murdoch        Vector<Intent> extraInitialIntents = new Vector<Intent>(0);
30746af492aeddda96c749142885e3b49455aa336309Ben Murdoch
307562b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch        if (addCameraIntent) {
30766af492aeddda96c749142885e3b49455aa336309Ben Murdoch            extraInitialIntents.add(cameraIntent);
30776af492aeddda96c749142885e3b49455aa336309Ben Murdoch        }
30786af492aeddda96c749142885e3b49455aa336309Ben Murdoch
30796af492aeddda96c749142885e3b49455aa336309Ben Murdoch        if (addCamcorderIntent) {
30806af492aeddda96c749142885e3b49455aa336309Ben Murdoch            extraInitialIntents.add(camcorderIntent);
30816af492aeddda96c749142885e3b49455aa336309Ben Murdoch        }
30826af492aeddda96c749142885e3b49455aa336309Ben Murdoch
30836af492aeddda96c749142885e3b49455aa336309Ben Murdoch        if (extraInitialIntents.size() > 0) {
30846af492aeddda96c749142885e3b49455aa336309Ben Murdoch            Intent[] extraIntents = new Intent[extraInitialIntents.size()];
30856af492aeddda96c749142885e3b49455aa336309Ben Murdoch            chooser.putExtra(Intent.EXTRA_INITIAL_INTENTS, extraInitialIntents.toArray(extraIntents));
308662b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch        }
308762b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch
308862b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch        chooser.putExtra(Intent.EXTRA_TITLE, getString(R.string.choose_upload));
308962b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch        BrowserActivity.this.startActivityForResult(chooser, FILE_SELECTED);
309022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
309122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
309222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // -------------------------------------------------------------------------
309322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // Implement functions for DownloadListener
309422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // -------------------------------------------------------------------------
309522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
30960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
30970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Notify the host application a download should be done, or that
30980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * the data should be streamed if a streaming viewer is available.
30990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param url The full url to the content that should be downloaded
31000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param contentDisposition Content-disposition http header, if
31010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *                           present.
31020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param mimetype The mimetype of the content reported by the server
31030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param contentLength The file size reported by the server
31040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
31050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public void onDownloadStart(String url, String userAgent,
31060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            String contentDisposition, String mimetype, long contentLength) {
31070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // if we're dealing wih A/V content that's not explicitly marked
31080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        //     for download, check if it's streamable.
31090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (contentDisposition == null
3110e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                || !contentDisposition.regionMatches(
3111e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                        true, 0, "attachment", 0, 10)) {
31120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // query the package manager to see if there's a registered handler
31130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            //     that matches.
31140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Intent intent = new Intent(Intent.ACTION_VIEW);
31150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            intent.setDataAndType(Uri.parse(url), mimetype);
3116e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott            ResolveInfo info = getPackageManager().resolveActivity(intent,
3117e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                    PackageManager.MATCH_DEFAULT_ONLY);
3118e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott            if (info != null) {
3119e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                ComponentName myName = getComponentName();
3120e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                // If we resolved to ourselves, we don't want to attempt to
3121e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                // load the url only to try and download it again.
3122e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                if (!myName.getPackageName().equals(
3123e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                        info.activityInfo.packageName)
3124e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                        || !myName.getClassName().equals(
3125e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                                info.activityInfo.name)) {
3126e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                    // someone (other than us) knows how to handle this mime
3127e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                    // type with this scheme, don't download.
3128e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                    try {
3129e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                        startActivity(intent);
3130e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                        return;
3131e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                    } catch (ActivityNotFoundException ex) {
3132e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                        if (LOGD_ENABLED) {
3133e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                            Log.d(LOGTAG, "activity not found for " + mimetype
3134e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                                    + " over " + Uri.parse(url).getScheme(),
3135e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                                    ex);
3136e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                        }
3137e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                        // Best behavior is to fall back to a download in this
3138e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                        // case
31390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
31400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
31410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
31420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
31430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        onDownloadStartNoStream(url, userAgent, contentDisposition, mimetype, contentLength);
31440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
31450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
3146fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen    // This is to work around the fact that java.net.URI throws Exceptions
3147fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen    // instead of just encoding URL's properly
3148fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen    // Helper method for onDownloadStartNoStream
3149fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen    private static String encodePath(String path) {
3150fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen        char[] chars = path.toCharArray();
3151fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen
3152fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen        boolean needed = false;
3153fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen        for (char c : chars) {
3154fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen            if (c == '[' || c == ']') {
3155fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen                needed = true;
3156fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen                break;
3157fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen            }
3158fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen        }
3159fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen        if (needed == false) {
3160fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen            return path;
3161fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen        }
3162fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen
3163fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen        StringBuilder sb = new StringBuilder("");
3164fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen        for (char c : chars) {
3165fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen            if (c == '[' || c == ']') {
3166fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen                sb.append('%');
3167fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen                sb.append(Integer.toHexString(c));
3168fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen            } else {
3169fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen                sb.append(c);
3170fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen            }
3171fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen        }
3172fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen
3173fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen        return sb.toString();
3174fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen    }
3175fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen
31760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
31770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Notify the host application a download should be done, even if there
31780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * is a streaming viewer available for thise type.
31790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param url The full url to the content that should be downloaded
31800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param contentDisposition Content-disposition http header, if
31810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *                           present.
31820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param mimetype The mimetype of the content reported by the server
31830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param contentLength The file size reported by the server
31840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
31850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /*package */ void onDownloadStartNoStream(String url, String userAgent,
31860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            String contentDisposition, String mimetype, long contentLength) {
31870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
31880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String filename = URLUtil.guessFileName(url,
31890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                contentDisposition, mimetype);
31900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
31910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Check to see if we have an SDCard
31920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String status = Environment.getExternalStorageState();
31930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (!status.equals(Environment.MEDIA_MOUNTED)) {
31940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            int title;
31950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            String msg;
31960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
31970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Check to see if the SDCard is busy, same as the music app
31980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (status.equals(Environment.MEDIA_SHARED)) {
31990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                msg = getString(R.string.download_sdcard_busy_dlg_msg);
32000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                title = R.string.download_sdcard_busy_dlg_title;
32010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } else {
32020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                msg = getString(R.string.download_no_sdcard_dlg_msg, filename);
32030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                title = R.string.download_no_sdcard_dlg_title;
32040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
32050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
32060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            new AlertDialog.Builder(this)
32070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setTitle(title)
32080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setIcon(android.R.drawable.ic_dialog_alert)
32090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setMessage(msg)
32100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setPositiveButton(R.string.ok, null)
32110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .show();
32120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
32130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
32140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
3215fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen        // java.net.URI is a lot stricter than KURL so we have to encode some
3216fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen        // extra characters. Fix for b 2538060 and b 1634719
3217fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen        WebAddress webAddress;
32180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        try {
3219fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen            webAddress = new WebAddress(url);
3220fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen            webAddress.mPath = encodePath(webAddress.mPath);
32210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } catch (Exception e) {
3222fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen            // This only happens for very bad urls, we want to chatch the
3223fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen            // exception here
3224fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen            Log.e(LOGTAG, "Exception trying to parse url:" + url);
32250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
32260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
32270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
32280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // XXX: Have to use the old url since the cookies were stored using the
32290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // old percent-encoded url.
32300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String cookies = CookieManager.getInstance().getCookie(url);
32310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
32320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        ContentValues values = new ContentValues();
3233fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen        values.put(Downloads.Impl.COLUMN_URI, webAddress.toString());
32341e5bad97ca8fb9b12501f4f747941d02f03e1362Jean-Baptiste Queru        values.put(Downloads.Impl.COLUMN_COOKIE_DATA, cookies);
32351e5bad97ca8fb9b12501f4f747941d02f03e1362Jean-Baptiste Queru        values.put(Downloads.Impl.COLUMN_USER_AGENT, userAgent);
32361e5bad97ca8fb9b12501f4f747941d02f03e1362Jean-Baptiste Queru        values.put(Downloads.Impl.COLUMN_NOTIFICATION_PACKAGE,
32370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                getPackageName());
32381e5bad97ca8fb9b12501f4f747941d02f03e1362Jean-Baptiste Queru        values.put(Downloads.Impl.COLUMN_NOTIFICATION_CLASS,
3239a563d09392905140893d7a017dd63721577e1953Leon Scroggins                OpenDownloadReceiver.class.getCanonicalName());
32401e5bad97ca8fb9b12501f4f747941d02f03e1362Jean-Baptiste Queru        values.put(Downloads.Impl.COLUMN_VISIBILITY,
32411e5bad97ca8fb9b12501f4f747941d02f03e1362Jean-Baptiste Queru                Downloads.Impl.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
32421e5bad97ca8fb9b12501f4f747941d02f03e1362Jean-Baptiste Queru        values.put(Downloads.Impl.COLUMN_MIME_TYPE, mimetype);
32431e5bad97ca8fb9b12501f4f747941d02f03e1362Jean-Baptiste Queru        values.put(Downloads.Impl.COLUMN_FILE_NAME_HINT, filename);
3244fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen        values.put(Downloads.Impl.COLUMN_DESCRIPTION, webAddress.mHost);
32450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (contentLength > 0) {
32461e5bad97ca8fb9b12501f4f747941d02f03e1362Jean-Baptiste Queru            values.put(Downloads.Impl.COLUMN_TOTAL_BYTES, contentLength);
32470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
32480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mimetype == null) {
32490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // We must have long pressed on a link or image to download it. We
32500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // are not sure of the mimetype in this case, so do a head request
32510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            new FetchUrlMimeType(this).execute(values);
32520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
32530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            final Uri contentUri =
32541e5bad97ca8fb9b12501f4f747941d02f03e1362Jean-Baptiste Queru                    getContentResolver().insert(Downloads.Impl.CONTENT_URI, values);
32550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
32569191a7f745c965cf57df94d0628890b413c710c9Leon Scroggins        Toast.makeText(this, R.string.download_pending, Toast.LENGTH_SHORT)
32579191a7f745c965cf57df94d0628890b413c710c9Leon Scroggins                .show();
32580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
32590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
326022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // -------------------------------------------------------------------------
326122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
32620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
32630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Resets the lock icon. This method is called when we start a new load and
32640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * know the url to be loaded.
32650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
32660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void resetLockIcon(String url) {
32670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Save the lock-icon state (we revert to it if the load gets cancelled)
326822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mTabControl.getCurrentTab().resetLockIcon(url);
32690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        updateLockIconImage(LOCK_ICON_UNSECURE);
32700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
32710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
32720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
32733bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     * Update the lock icon to correspond to our latest state.
32743bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     */
327522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private void updateLockIconToLatest() {
327691f65fccfd6feae560a42abdd3385ca3318f0430Leon Scroggins        Tab t = mTabControl.getCurrentTab();
327791f65fccfd6feae560a42abdd3385ca3318f0430Leon Scroggins        if (t != null) {
327891f65fccfd6feae560a42abdd3385ca3318f0430Leon Scroggins            updateLockIconImage(t.getLockIconType());
327991f65fccfd6feae560a42abdd3385ca3318f0430Leon Scroggins        }
32803bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    }
32813bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins
32823bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    /**
32830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Updates the lock-icon image in the title-bar.
32840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
32850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void updateLockIconImage(int lockIconType) {
32860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        Drawable d = null;
32870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (lockIconType == LOCK_ICON_SECURE) {
32880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            d = mSecLockIcon;
32890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else if (lockIconType == LOCK_ICON_MIXED) {
32900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            d = mMixLockIcon;
32910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
329268579393973f745fc65a2781061af9bb8f2d7020Leon Scroggins        mTitleBar.setLock(d);
3293a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb        mFakeTitleBar.setLock(d);
32940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
32950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
32960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
32970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Displays a page-info dialog.
32980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param tab The tab to show info about
32990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param fromShowSSLCertificateOnError The flag that indicates whether
33000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * this dialog was opened from the SSL-certificate-on-error dialog or
33010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * not. This is important, since we need to know whether to return to
33020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * the parent dialog or simply dismiss.
33030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
330422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private void showPageInfo(final Tab tab,
33050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                              final boolean fromShowSSLCertificateOnError) {
33060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final LayoutInflater factory = LayoutInflater
33070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .from(this);
33080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
33090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final View pageInfoView = factory.inflate(R.layout.page_info, null);
33100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
33110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final WebView view = tab.getWebView();
33120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
33130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String url = null;
33140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String title = null;
33150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
33160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (view == null) {
33170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            url = tab.getUrl();
33180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            title = tab.getTitle();
33190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else if (view == mTabControl.getCurrentWebView()) {
33200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project             // Use the cached title and url if this is the current WebView
33210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            url = mUrl;
33220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            title = mTitle;
33230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
33240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            url = view.getUrl();
33250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            title = view.getTitle();
33260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
33270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
33280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (url == null) {
33290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            url = "";
33300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
33310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (title == null) {
33320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            title = "";
33330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
33340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
33350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        ((TextView) pageInfoView.findViewById(R.id.address)).setText(url);
33360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        ((TextView) pageInfoView.findViewById(R.id.title)).setText(title);
33370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
33380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mPageInfoView = tab;
3339c7b92f811dfa3572578ddc6714c98a03936d9ce5Leon Scroggins        mPageInfoFromShowSSLCertificateOnError = fromShowSSLCertificateOnError;
33400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
33410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        AlertDialog.Builder alertDialogBuilder =
33420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            new AlertDialog.Builder(this)
33430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            .setTitle(R.string.page_info).setIcon(android.R.drawable.ic_dialog_info)
33440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            .setView(pageInfoView)
33450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            .setPositiveButton(
33460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                R.string.ok,
33470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                new DialogInterface.OnClickListener() {
33480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    public void onClick(DialogInterface dialog,
33490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        int whichButton) {
33500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        mPageInfoDialog = null;
33510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        mPageInfoView = null;
33520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
33530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        // if we came here from the SSL error dialog
33540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        if (fromShowSSLCertificateOnError) {
33550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            // go back to the SSL error dialog
33560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            showSSLCertificateOnError(
33570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorView,
33580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorHandler,
33590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorError);
33600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }
33610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
33620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                })
33630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            .setOnCancelListener(
33640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                new DialogInterface.OnCancelListener() {
33650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    public void onCancel(DialogInterface dialog) {
33660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        mPageInfoDialog = null;
33670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        mPageInfoView = null;
33680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
33690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        // if we came here from the SSL error dialog
33700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        if (fromShowSSLCertificateOnError) {
33710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            // go back to the SSL error dialog
33720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            showSSLCertificateOnError(
33730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorView,
33740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorHandler,
33750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorError);
33760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }
33770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
33780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                });
33790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
33800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // if we have a main top-level page SSL certificate set or a certificate
33810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // error
33820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (fromShowSSLCertificateOnError ||
33830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                (view != null && view.getCertificate() != null)) {
33840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // add a 'View Certificate' button
33850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            alertDialogBuilder.setNeutralButton(
33860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                R.string.view_certificate,
33870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                new DialogInterface.OnClickListener() {
33880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    public void onClick(DialogInterface dialog,
33890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        int whichButton) {
33900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        mPageInfoDialog = null;
33910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        mPageInfoView = null;
33920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
33930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        // if we came here from the SSL error dialog
33940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        if (fromShowSSLCertificateOnError) {
33950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            // go back to the SSL error dialog
33960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            showSSLCertificateOnError(
33970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorView,
33980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorHandler,
33990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorError);
34000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        } else {
34010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            // otherwise, display the top-most certificate from
34020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            // the chain
34030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            if (view.getCertificate() != null) {
34040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                showSSLCertificate(tab);
34050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            }
34060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }
34070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
34080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                });
34090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
34100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
34110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mPageInfoDialog = alertDialogBuilder.show();
34120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
34130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
34140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project       /**
34150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Displays the main top-level page SSL certificate dialog
34160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * (accessible from the Page-Info dialog).
34170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param tab The tab to show certificate for.
34180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
341922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private void showSSLCertificate(final Tab tab) {
34200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final View certificateView =
34210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                inflateCertificateView(tab.getWebView().getCertificate());
34220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (certificateView == null) {
34230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
34240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
34250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
34260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        LayoutInflater factory = LayoutInflater.from(this);
34270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
34280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final LinearLayout placeholder =
34290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                (LinearLayout)certificateView.findViewById(R.id.placeholder);
34300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
34310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        LinearLayout ll = (LinearLayout) factory.inflate(
34320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            R.layout.ssl_success, placeholder);
34330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        ((TextView)ll.findViewById(R.id.success))
34340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            .setText(R.string.ssl_certificate_is_valid);
34350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
34360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mSSLCertificateView = tab;
34370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mSSLCertificateDialog =
34380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            new AlertDialog.Builder(this)
34390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setTitle(R.string.ssl_certificate).setIcon(
34400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    R.drawable.ic_dialog_browser_certificate_secure)
34410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setView(certificateView)
34420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setPositiveButton(R.string.ok,
34430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new DialogInterface.OnClickListener() {
34440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            public void onClick(DialogInterface dialog,
34450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    int whichButton) {
34460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateDialog = null;
34470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateView = null;
34480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
34490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                showPageInfo(tab, false);
34500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            }
34510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        })
34520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setOnCancelListener(
34530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new DialogInterface.OnCancelListener() {
34540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            public void onCancel(DialogInterface dialog) {
34550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateDialog = null;
34560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateView = null;
34570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
34580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                showPageInfo(tab, false);
34590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            }
34600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        })
34610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .show();
34620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
34630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
34640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
34650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Displays the SSL error certificate dialog.
34660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param view The target web-view.
34670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param handler The SSL error handler responsible for cancelling the
34680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * connection that resulted in an SSL error or proceeding per user request.
34690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param error The SSL error object.
34700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
347122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void showSSLCertificateOnError(
34720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final WebView view, final SslErrorHandler handler, final SslError error) {
34730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
34740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final View certificateView =
34750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            inflateCertificateView(error.getCertificate());
34760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (certificateView == null) {
34770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
34780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
34790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
34800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        LayoutInflater factory = LayoutInflater.from(this);
34810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
34820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final LinearLayout placeholder =
34830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                (LinearLayout)certificateView.findViewById(R.id.placeholder);
34840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
34850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (error.hasError(SslError.SSL_UNTRUSTED)) {
34860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            LinearLayout ll = (LinearLayout)factory
34870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .inflate(R.layout.ssl_warning, placeholder);
34880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((TextView)ll.findViewById(R.id.warning))
34890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setText(R.string.ssl_untrusted);
34900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
34910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
34920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (error.hasError(SslError.SSL_IDMISMATCH)) {
34930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            LinearLayout ll = (LinearLayout)factory
34940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .inflate(R.layout.ssl_warning, placeholder);
34950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((TextView)ll.findViewById(R.id.warning))
34960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setText(R.string.ssl_mismatch);
34970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
34980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
34990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (error.hasError(SslError.SSL_EXPIRED)) {
35000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            LinearLayout ll = (LinearLayout)factory
35010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .inflate(R.layout.ssl_warning, placeholder);
35020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((TextView)ll.findViewById(R.id.warning))
35030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setText(R.string.ssl_expired);
35040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
35050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
35060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (error.hasError(SslError.SSL_NOTYETVALID)) {
35070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            LinearLayout ll = (LinearLayout)factory
35080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .inflate(R.layout.ssl_warning, placeholder);
35090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((TextView)ll.findViewById(R.id.warning))
35100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setText(R.string.ssl_not_yet_valid);
35110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
35120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
35130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mSSLCertificateOnErrorHandler = handler;
35140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mSSLCertificateOnErrorView = view;
35150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mSSLCertificateOnErrorError = error;
35160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mSSLCertificateOnErrorDialog =
35170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            new AlertDialog.Builder(this)
35180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setTitle(R.string.ssl_certificate).setIcon(
35190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    R.drawable.ic_dialog_browser_certificate_partially_secure)
35200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setView(certificateView)
35210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setPositiveButton(R.string.ok,
35220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new DialogInterface.OnClickListener() {
35230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            public void onClick(DialogInterface dialog,
35240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    int whichButton) {
35250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorDialog = null;
35260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorView = null;
35270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorHandler = null;
35280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorError = null;
35290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
353022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                view.getWebViewClient().onReceivedSslError(
353122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                                view, handler, error);
35320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            }
35330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        })
35340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                 .setNeutralButton(R.string.page_info_view,
35350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new DialogInterface.OnClickListener() {
35360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            public void onClick(DialogInterface dialog,
35370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    int whichButton) {
35380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorDialog = null;
35390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
35400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                // do not clear the dialog state: we will
35410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                // need to show the dialog again once the
35420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                // user is done exploring the page-info details
35430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
35440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                showPageInfo(mTabControl.getTabFromView(view),
35450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        true);
35460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            }
35470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        })
35480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setOnCancelListener(
35490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new DialogInterface.OnCancelListener() {
35500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            public void onCancel(DialogInterface dialog) {
35510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorDialog = null;
35520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorView = null;
35530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorHandler = null;
35540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorError = null;
35550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
355622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                view.getWebViewClient().onReceivedSslError(
355722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                                view, handler, error);
35580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            }
35590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        })
35600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .show();
35610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
35620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
35630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
35640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Inflates the SSL certificate view (helper method).
35650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param certificate The SSL certificate.
35660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @return The resultant certificate view with issued-to, issued-by,
35670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * issued-on, expires-on, and possibly other fields set.
35680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * If the input certificate is null, returns null.
35690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
35700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private View inflateCertificateView(SslCertificate certificate) {
35710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (certificate == null) {
35720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return null;
35730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
35740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
35750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        LayoutInflater factory = LayoutInflater.from(this);
35760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
35770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        View certificateView = factory.inflate(
35780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            R.layout.ssl_certificate, null);
35790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
35800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // issued to:
35810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        SslCertificate.DName issuedTo = certificate.getIssuedTo();
35820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (issuedTo != null) {
35830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((TextView) certificateView.findViewById(R.id.to_common))
35840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setText(issuedTo.getCName());
35850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((TextView) certificateView.findViewById(R.id.to_org))
35860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setText(issuedTo.getOName());
35870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((TextView) certificateView.findViewById(R.id.to_org_unit))
35880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setText(issuedTo.getUName());
35890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
35900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
35910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // issued by:
35920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        SslCertificate.DName issuedBy = certificate.getIssuedBy();
35930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (issuedBy != null) {
35940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((TextView) certificateView.findViewById(R.id.by_common))
35950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setText(issuedBy.getCName());
35960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((TextView) certificateView.findViewById(R.id.by_org))
35970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setText(issuedBy.getOName());
35980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((TextView) certificateView.findViewById(R.id.by_org_unit))
35990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setText(issuedBy.getUName());
36000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
36010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
36020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // issued on:
360395a2e4ab94514e4e41033b0d27a0e66855cff8ebBrian Carlstrom        String issuedOn = formatCertificateDate(
360495a2e4ab94514e4e41033b0d27a0e66855cff8ebBrian Carlstrom            certificate.getValidNotBeforeDate());
36050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        ((TextView) certificateView.findViewById(R.id.issued_on))
36060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            .setText(issuedOn);
36070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
36080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // expires on:
360995a2e4ab94514e4e41033b0d27a0e66855cff8ebBrian Carlstrom        String expiresOn = formatCertificateDate(
361095a2e4ab94514e4e41033b0d27a0e66855cff8ebBrian Carlstrom            certificate.getValidNotAfterDate());
36110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        ((TextView) certificateView.findViewById(R.id.expires_on))
36120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            .setText(expiresOn);
36130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
36140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return certificateView;
36150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
36160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
36170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
361895a2e4ab94514e4e41033b0d27a0e66855cff8ebBrian Carlstrom     * Formats the certificate date to a properly localized date string.
36190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @return Properly localized version of the certificate date string and
362095a2e4ab94514e4e41033b0d27a0e66855cff8ebBrian Carlstrom     * the "" if it fails to localize.
36210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
362295a2e4ab94514e4e41033b0d27a0e66855cff8ebBrian Carlstrom    private String formatCertificateDate(Date certificateDate) {
362395a2e4ab94514e4e41033b0d27a0e66855cff8ebBrian Carlstrom      if (certificateDate == null) {
362495a2e4ab94514e4e41033b0d27a0e66855cff8ebBrian Carlstrom          return "";
36250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project      }
362695a2e4ab94514e4e41033b0d27a0e66855cff8ebBrian Carlstrom      String formattedDate = DateFormat.getDateFormat(this).format(certificateDate);
362795a2e4ab94514e4e41033b0d27a0e66855cff8ebBrian Carlstrom      if (formattedDate == null) {
362895a2e4ab94514e4e41033b0d27a0e66855cff8ebBrian Carlstrom          return "";
362995a2e4ab94514e4e41033b0d27a0e66855cff8ebBrian Carlstrom      }
363095a2e4ab94514e4e41033b0d27a0e66855cff8ebBrian Carlstrom      return formattedDate;
36310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
36320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
36330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
36340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Displays an http-authentication dialog.
36350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
363622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void showHttpAuthentication(final HttpAuthHandler handler,
36370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            final String host, final String realm, final String title,
36380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            final String name, final String password, int focusId) {
36390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        LayoutInflater factory = LayoutInflater.from(this);
36400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final View v = factory
36410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .inflate(R.layout.http_authentication, null);
36420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (name != null) {
36430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((EditText) v.findViewById(R.id.username_edit)).setText(name);
36440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
36450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (password != null) {
36460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((EditText) v.findViewById(R.id.password_edit)).setText(password);
36470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
36480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
36490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String titleText = title;
36500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (titleText == null) {
36510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            titleText = getText(R.string.sign_in_to).toString().replace(
36520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    "%s1", host).replace("%s2", realm);
36530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
36540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
36550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mHttpAuthHandler = handler;
36560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        AlertDialog dialog = new AlertDialog.Builder(this)
36570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setTitle(titleText)
36580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setIcon(android.R.drawable.ic_dialog_alert)
36590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setView(v)
36600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setPositiveButton(R.string.action,
36610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new DialogInterface.OnClickListener() {
36620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                             public void onClick(DialogInterface dialog,
36630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                     int whichButton) {
36640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                String nm = ((EditText) v
36650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        .findViewById(R.id.username_edit))
36660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        .getText().toString();
36670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                String pw = ((EditText) v
36680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        .findViewById(R.id.password_edit))
36690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        .getText().toString();
36700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                BrowserActivity.this.setHttpAuthUsernamePassword
36710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        (host, realm, nm, pw);
36720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                handler.proceed(nm, pw);
36730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mHttpAuthenticationDialog = null;
36740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mHttpAuthHandler = null;
36750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            }})
36760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setNegativeButton(R.string.cancel,
36770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new DialogInterface.OnClickListener() {
36780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            public void onClick(DialogInterface dialog,
36790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    int whichButton) {
36800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                handler.cancel();
36810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                BrowserActivity.this.resetTitleAndRevertLockIcon();
36820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mHttpAuthenticationDialog = null;
36830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mHttpAuthHandler = null;
36840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            }})
36850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setOnCancelListener(new DialogInterface.OnCancelListener() {
36860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        public void onCancel(DialogInterface dialog) {
36870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            handler.cancel();
36880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            BrowserActivity.this.resetTitleAndRevertLockIcon();
36890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            mHttpAuthenticationDialog = null;
36900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            mHttpAuthHandler = null;
36910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }})
36920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .create();
36930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Make the IME appear when the dialog is displayed if applicable.
36940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        dialog.getWindow().setSoftInputMode(
36950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);
36960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        dialog.show();
36970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (focusId != 0) {
36980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            dialog.findViewById(focusId).requestFocus();
36990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
37000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            v.findViewById(R.id.username_edit).requestFocus();
37010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
37020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mHttpAuthenticationDialog = dialog;
37030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
37040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
37050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public int getProgress() {
37060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebView w = mTabControl.getCurrentWebView();
37070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (w != null) {
37080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return w.getProgress();
37090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
37100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return 100;
37110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
37120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
37130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
37140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
37150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Set HTTP authentication password.
37160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *
37170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param host The host for the password
37180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param realm The realm for the password
37190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param username The username for the password. If it is null, it means
37200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *            password can't be saved.
37210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param password The password
37220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
37230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public void setHttpAuthUsernamePassword(String host, String realm,
37240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                            String username,
37250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                            String password) {
372695a53b25504f12c3a5f8ecbbfcff7ac1dc047e4fSteve Block        WebView w = getTopWindow();
37270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (w != null) {
37280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            w.setHttpAuthUsernamePassword(host, realm, username, password);
37290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
37300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
37310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
37320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
37330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * connectivity manager says net has come or gone... inform the user
37340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param up true if net has come up, false if net has gone down
37350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
37360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public void onNetworkToggle(boolean up) {
37370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (up == mIsNetworkUp) {
37380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
37390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else if (up) {
37400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mIsNetworkUp = true;
37410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (mAlertDialog != null) {
37420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mAlertDialog.cancel();
37430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mAlertDialog = null;
37440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
37450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
37460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mIsNetworkUp = false;
3747eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott            if (mInLoad) {
3748eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott                createAndShowNetworkDialog();
3749eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott           }
37500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
37510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebView w = mTabControl.getCurrentWebView();
37520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (w != null) {
37530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            w.setNetworkAvailable(up);
37540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
37550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
37560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
375722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    boolean isNetworkUp() {
375822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return mIsNetworkUp;
375922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
376022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
3761eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott    // This method shows the network dialog alerting the user that the net is
3762eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott    // down. It will only show the dialog if mAlertDialog is null.
3763eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott    private void createAndShowNetworkDialog() {
3764eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott        if (mAlertDialog == null) {
3765eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott            mAlertDialog = new AlertDialog.Builder(this)
3766eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott                    .setTitle(R.string.loadSuspendedTitle)
3767eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott                    .setMessage(R.string.loadSuspended)
3768eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott                    .setPositiveButton(R.string.ok, null)
3769eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott                    .show();
3770eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott        }
3771eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott    }
3772eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott
37730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    @Override
37740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    protected void onActivityResult(int requestCode, int resultCode,
37750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    Intent intent) {
3776bb394f3e134b6e5898ef7ae861b75e95e618688fGrace Kloba        if (getTopWindow() == null) return;
3777bb394f3e134b6e5898ef7ae861b75e95e618688fGrace Kloba
37780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        switch (requestCode) {
37790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case COMBO_PAGE:
37800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (resultCode == RESULT_OK && intent != null) {
37810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    String data = intent.getAction();
37820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    Bundle extras = intent.getExtras();
3783300b7f0951f3688a8e41f190b57cbf8b3bc06170Michael Kolb                    if (extras != null &&
3784300b7f0951f3688a8e41f190b57cbf8b3bc06170Michael Kolb                            extras.getBoolean(
3785300b7f0951f3688a8e41f190b57cbf8b3bc06170Michael Kolb                                    CombinedBookmarkHistoryActivity.EXTRA_OPEN_NEW_WINDOW,
3786300b7f0951f3688a8e41f190b57cbf8b3bc06170Michael Kolb                                    false)) {
378768792c84eded7f83e2f086d3efe81f9cfc07f9c3Michael Kolb                        openTab(data, false);
378868792c84eded7f83e2f086d3efe81f9cfc07f9c3Michael Kolb                    } else if ((extras != null) &&
378968792c84eded7f83e2f086d3efe81f9cfc07f9c3Michael Kolb                            extras.getBoolean(CombinedBookmarkHistoryActivity.NEWTAB_MODE)) {
379068792c84eded7f83e2f086d3efe81f9cfc07f9c3Michael Kolb                        openTab(data, true);
37910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    } else {
379268792c84eded7f83e2f086d3efe81f9cfc07f9c3Michael Kolb                        final Tab currentTab = mTabControl.getCurrentTab();
37931f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                        dismissSubWindow(currentTab);
37941f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                        if (data != null && data.length() != 0) {
379592472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins                            loadUrl(getTopWindow(), data);
37960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }
37970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
37983f65c3831ff82a20f6f0edb08df2d7edae540044Michael Kolb                } else if (resultCode == RESULT_CANCELED) {
37993f65c3831ff82a20f6f0edb08df2d7edae540044Michael Kolb                    if (intent != null) {
38003f65c3831ff82a20f6f0edb08df2d7edae540044Michael Kolb                        float evtx = intent.getFloatExtra(CombinedBookmarkHistoryActivity.EVT_X, -1);
38013f65c3831ff82a20f6f0edb08df2d7edae540044Michael Kolb                        float evty = intent.getFloatExtra(CombinedBookmarkHistoryActivity.EVT_Y, -1);
38023f65c3831ff82a20f6f0edb08df2d7edae540044Michael Kolb                        long now = System.currentTimeMillis();
38033f65c3831ff82a20f6f0edb08df2d7edae540044Michael Kolb                        MotionEvent evt = MotionEvent.obtain(now, now,
38043f65c3831ff82a20f6f0edb08df2d7edae540044Michael Kolb                                MotionEvent.ACTION_DOWN, evtx, evty, 0);
38053f65c3831ff82a20f6f0edb08df2d7edae540044Michael Kolb                        dispatchTouchEvent(evt);
38063f65c3831ff82a20f6f0edb08df2d7edae540044Michael Kolb                        MotionEvent up = MotionEvent.obtain(evt);
38073f65c3831ff82a20f6f0edb08df2d7edae540044Michael Kolb                        up.setAction(MotionEvent.ACTION_UP);
38083f65c3831ff82a20f6f0edb08df2d7edae540044Michael Kolb                        dispatchTouchEvent(up);
38093f65c3831ff82a20f6f0edb08df2d7edae540044Michael Kolb                    }
38100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
3811fde9746ac3055848e110c35f19ec5893c621f766Leon Scroggins                // Deliberately fall through to PREFERENCES_PAGE, since the
3812fde9746ac3055848e110c35f19ec5893c621f766Leon Scroggins                // same extra may be attached to the COMBO_PAGE
3813fde9746ac3055848e110c35f19ec5893c621f766Leon Scroggins            case PREFERENCES_PAGE:
3814fde9746ac3055848e110c35f19ec5893c621f766Leon Scroggins                if (resultCode == RESULT_OK && intent != null) {
3815fde9746ac3055848e110c35f19ec5893c621f766Leon Scroggins                    String action = intent.getStringExtra(Intent.EXTRA_TEXT);
3816fde9746ac3055848e110c35f19ec5893c621f766Leon Scroggins                    if (BrowserSettings.PREF_CLEAR_HISTORY.equals(action)) {
3817fde9746ac3055848e110c35f19ec5893c621f766Leon Scroggins                        mTabControl.removeParentChildRelationShips();
3818fde9746ac3055848e110c35f19ec5893c621f766Leon Scroggins                    }
3819fde9746ac3055848e110c35f19ec5893c621f766Leon Scroggins                }
38200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
38218d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins            // Choose a file from the file picker.
38228d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins            case FILE_SELECTED:
38238d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins                if (null == mUploadMessage) break;
38248d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins                Uri result = intent == null || resultCode != RESULT_OK ? null
38258d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins                        : intent.getData();
382662b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch
382762b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch                // As we ask the camera to save the result of the user taking
382862b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch                // a picture, the camera application does not return anything other
382962b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch                // than RESULT_OK. So we need to check whether the file we expected
383062b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch                // was written to disk in the in the case that we
383162b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch                // did not get an intent returned but did get a RESULT_OK. If it was,
383262b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch                // we assume that this result has came back from the camera.
383362b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch                if (result == null && intent == null && resultCode == RESULT_OK) {
383462b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch                    File cameraFile = new File(mCameraFilePath);
383562b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch                    if (cameraFile.exists()) {
383662b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch                        result = Uri.fromFile(cameraFile);
383707d3473804cdfd646b39001ca80ebf530e8f8749Ben Murdoch                        // Broadcast to the media scanner that we have a new photo
383807d3473804cdfd646b39001ca80ebf530e8f8749Ben Murdoch                        // so it will be added into the gallery for the user.
383907d3473804cdfd646b39001ca80ebf530e8f8749Ben Murdoch                        sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, result));
384062b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch                    }
384162b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch                }
38428d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins                mUploadMessage.onReceiveValue(result);
38438d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins                mUploadMessage = null;
384462b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch                mCameraFilePath = null;
38458d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins                break;
38460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            default:
38470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
38480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
3849304442375719effd41dbd53ae62de7a8d0cec7d9Leon Scroggins        getTopWindow().requestFocus();
38500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
38510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
38520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /*
38530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * This method is called as a result of the user selecting the options
3854f08809b2cf7e502fef5965691a7fb6d7cf0322afLeon Scroggins     * menu to see the download window. It shows the download window on top of
3855f08809b2cf7e502fef5965691a7fb6d7cf0322afLeon Scroggins     * the current window.
38560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
3857f08809b2cf7e502fef5965691a7fb6d7cf0322afLeon Scroggins    private void viewDownloads(Uri downloadRecord) {
38580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        Intent intent = new Intent(this,
38590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                BrowserDownloadPage.class);
38600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        intent.setData(downloadRecord);
386122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        startActivityForResult(intent, BrowserActivity.DOWNLOAD_PAGE);
38620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
38630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
38640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
3865eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch    /* package*/ void promptAddOrInstallBookmark() {
3866eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch        final Tab current = mTabControl.getCurrentTab();
3867eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch        Resources resources = getResources();
3868eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch        CharSequence[] choices = {
3869eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch                resources.getString(R.string.save_to_bookmarks),
3870eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch                resources.getString(R.string.create_shortcut_bookmark)
3871eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch        };
3872eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch
3873eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch        AlertDialog.Builder builder = new AlertDialog.Builder(this);
3874eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch        builder.setTitle(R.string.add_new_bookmark);
3875eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch        builder.setItems(choices, new DialogInterface.OnClickListener() {
3876eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch                public void onClick(DialogInterface dialog, int item) {
3877eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch                    if (item == 0) {
3878eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch                        bookmarkCurrentPage();
3879eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch                    } else if (item == 1) {
3880eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch                        current.populatePickerData();
3881eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch                        String touchIconUrl = mTabControl.getCurrentWebView().getTouchIconUrl();
3882eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch                        if (touchIconUrl != null) {
3883eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch                            // Download the touch icon for this site then save it to the
3884eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch                            // homescreen.
3885eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch                            Bundle b = new Bundle();
3886eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch                            b.putString("url", current.getUrl());
3887eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch                            b.putString("title", current.getTitle());
3888eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch                            b.putParcelable("favicon", current.getFavicon());
3889eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch                            Message msg = mHandler.obtainMessage(TOUCH_ICON_DOWNLOADED);
3890eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch                            msg.setData(b);
3891ccb5de06714993c28d16f1e5abfcd9f0b1e656fcBen Murdoch                            new DownloadTouchIcon(BrowserActivity.this, msg,
3892eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch                                    mTabControl.getCurrentWebView().getSettings()
3893eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch                                    .getUserAgentString()).execute(touchIconUrl);
3894eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch                        } else {
3895eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch                            // add to homescreen, can do it immediately as there is no touch
3896eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch                            // icon.
3897eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch                            showSaveToHomescreenDialog(current.getUrl(), current.getTitle(),
3898eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch                                    null, current.getFavicon());
3899eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch                        }
3900eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch                     }
3901eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch                 }
3902eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch        });
3903eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch        builder.create().show();
3904eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch    }
3905eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch
3906160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins    /**
3907160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins     * Open the Go page.
3908160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins     * @param startWithHistory If true, open starting on the history tab.
3909160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins     *                         Otherwise, start with the bookmarks tab.
3910160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins     */
391168792c84eded7f83e2f086d3efe81f9cfc07f9c3Michael Kolb    /* package */ void bookmarksOrHistoryPicker(boolean startWithHistory, boolean newTabMode) {
39120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebView current = mTabControl.getCurrentWebView();
39130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (current == null) {
39140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
39150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
39160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        Intent intent = new Intent(this,
39170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                CombinedBookmarkHistoryActivity.class);
39180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String title = current.getTitle();
39190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String url = current.getUrl();
392087cc65d95c80c5e3a1c343ad5177a7dc2de874f6Ben Murdoch        Bitmap thumbnail = createScreenshot(current, getDesiredThumbnailWidth(this),
392187cc65d95c80c5e3a1c343ad5177a7dc2de874f6Ben Murdoch                getDesiredThumbnailHeight(this));
3922dcc2b6f08dd5677bc6ba761a9ba6f1c655113051Ben Murdoch
39230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Just in case the user opens bookmarks before a page finishes loading
39240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // so the current history item, and therefore the page, is null.
39250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (null == url) {
39260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            url = mLastEnteredUrl;
39270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // This can happen.
39280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (null == url) {
39290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                url = mSettings.getHomePage();
39300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
39310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
39320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // In case the web page has not yet received its associated title.
39330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (title == null) {
39340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            title = url;
39350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
39360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        intent.putExtra("title", title);
39370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        intent.putExtra("url", url);
3938dcc2b6f08dd5677bc6ba761a9ba6f1c655113051Ben Murdoch        intent.putExtra("thumbnail", thumbnail);
3939304442375719effd41dbd53ae62de7a8d0cec7d9Leon Scroggins        // Disable opening in a new window if we have maxed out the windows
394022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        intent.putExtra("disable_new_window", !mTabControl.canCreateNewTab());
39413918d4443ff38ef1870e02aa51a8b29f8352bb1aPatrick Scott        intent.putExtra("touch_icon_url", current.getTouchIconUrl());
39420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (startWithHistory) {
394364144e49208df145c8362dfa037335c7b9210167Jeff Hamilton            intent.putExtra(CombinedBookmarkHistoryActivity.STARTING_FRAGMENT,
394464144e49208df145c8362dfa037335c7b9210167Jeff Hamilton                    CombinedBookmarkHistoryActivity.FRAGMENT_ID_HISTORY);
39450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
3946300b7f0951f3688a8e41f190b57cbf8b3bc06170Michael Kolb        intent.putExtra(CombinedBookmarkHistoryActivity.NEWTAB_MODE, newTabMode);
39470998b0a02bcb8606881df8ed6ae204b5367ca4f9Michael Kolb        int top = -1;
39480998b0a02bcb8606881df8ed6ae204b5367ca4f9Michael Kolb        int height = -1;
39493f65c3831ff82a20f6f0edb08df2d7edae540044Michael Kolb        if (mXLargeScreenSize) {
39503f65c3831ff82a20f6f0edb08df2d7edae540044Michael Kolb            showFakeTitleBar();
39513f65c3831ff82a20f6f0edb08df2d7edae540044Michael Kolb            int titleBarHeight = ((TitleBarXLarge)mFakeTitleBar).getHeightWithoutProgress();
39520998b0a02bcb8606881df8ed6ae204b5367ca4f9Michael Kolb            top = mTabBar.getBottom() + titleBarHeight;
39530998b0a02bcb8606881df8ed6ae204b5367ca4f9Michael Kolb            height = getTopWindow().getHeight() - titleBarHeight;
395468792c84eded7f83e2f086d3efe81f9cfc07f9c3Michael Kolb        }
39550998b0a02bcb8606881df8ed6ae204b5367ca4f9Michael Kolb        intent.putExtra(CombinedBookmarkHistoryActivity.EXTRA_TOP, top);
39560998b0a02bcb8606881df8ed6ae204b5367ca4f9Michael Kolb        intent.putExtra(CombinedBookmarkHistoryActivity.EXTRA_HEIGHT, height);
39570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        startActivityForResult(intent, COMBO_PAGE);
39580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
39590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
3960eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch    private void showSaveToHomescreenDialog(String url, String title, Bitmap touchIcon,
3961eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch            Bitmap favicon) {
3962eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch        Intent intent = new Intent(this, SaveToHomescreenDialog.class);
3963eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch
3964eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch        // Just in case the user tries to save before a page finishes loading
3965eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch        // so the current history item, and therefore the page, is null.
3966eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch        if (null == url) {
3967eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch            url = mLastEnteredUrl;
3968eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch            // This can happen.
3969eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch            if (null == url) {
3970eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch                url = mSettings.getHomePage();
3971eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch            }
3972eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch        }
3973eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch
3974eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch        // In case the web page has not yet received its associated title.
3975eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch        if (title == null) {
3976eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch            title = url;
3977eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch        }
3978eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch
3979eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch        intent.putExtra("title", title);
3980eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch        intent.putExtra("url", url);
3981eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch        intent.putExtra("favicon", favicon);
3982eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch        intent.putExtra("touchIcon", touchIcon);
3983eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch        startActivity(intent);
3984eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch    }
3985eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch
3986eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch
39870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Called when loading from context menu or LOAD_URL message
398892472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins    private void loadUrlFromContext(WebView view, String url) {
39890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // In case the user enters nothing.
39900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (url != null && url.length() != 0 && view != null) {
39910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            url = smartUrlFilter(url);
399222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (!view.getWebViewClient().shouldOverrideUrlLoading(view, url)) {
399392472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins                loadUrl(view, url);
39940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
39950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
39960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
39970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
399892472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins    /**
399992472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins     * Load the URL into the given WebView and update the title bar
400092472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins     * to reflect the new load.  Call this instead of WebView.loadUrl
400192472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins     * directly.
400292472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins     * @param view The WebView used to load url.
400392472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins     * @param url The URL to load.
400492472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins     */
400592472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins    private void loadUrl(WebView view, String url) {
400692472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins        updateTitleBarForNewLoad(view, url);
400792472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins        view.loadUrl(url);
400892472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins    }
400992472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins
401092472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins    /**
401192472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins     * Load UrlData into a Tab and update the title bar to reflect the new
401292472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins     * load.  Call this instead of UrlData.loadIn directly.
401392472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins     * @param t The Tab used to load.
401492472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins     * @param data The UrlData being loaded.
401592472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins     */
401692472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins    private void loadUrlDataIn(Tab t, UrlData data) {
401792472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins        updateTitleBarForNewLoad(t.getWebView(), data.mUrl);
401892472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins        data.loadIn(t);
401992472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins    }
402092472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins
402192472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins    /**
402292472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins     * If the WebView is the top window, update the title bar to reflect
402392472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins     * loading the new URL.  i.e. set its text, clear the favicon (which
402492472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins     * will be set once the page begins loading), and set the progress to
402592472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins     * INITIAL_PROGRESS to show that the page has begun to load. Called
402692472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins     * by loadUrl and loadUrlDataIn.
402792472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins     * @param view The WebView that is starting a load.
402892472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins     * @param url The URL that is being loaded.
402992472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins     */
403092472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins    private void updateTitleBarForNewLoad(WebView view, String url) {
403192472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins        if (view == getTopWindow()) {
403292472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins            setUrlTitle(url, null);
403392472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins            setFavicon(null);
403492472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins            onProgressChanged(view, INITIAL_PROGRESS);
403592472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins        }
403692472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins    }
403792472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins
40380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private String smartUrlFilter(Uri inUri) {
40390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (inUri != null) {
40400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return smartUrlFilter(inUri.toString());
40410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
40420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return null;
40430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
40440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
4045b34f87a2e13af13d697130482af01b537ab7c5fdFeng Qian    protected static final Pattern ACCEPTED_URI_SCHEMA = Pattern.compile(
40460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            "(?i)" + // switch on case insensitive matching
40470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            "(" +    // begin group for schema
40480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            "(?:http|https|file):\\/\\/" +
404925ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima            "|(?:inline|data|about|content|javascript):" +
40500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ")" +
40510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            "(.*)" );
40520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
40530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
40540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Attempts to determine whether user input is a URL or search
40550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * terms.  Anything with a space is passed to search.
40560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *
40570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Converts to lowercase any mistakenly uppercased schema (i.e.,
40580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * "Http://" converts to "http://"
40590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *
40600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @return Original or modified URL
40610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *
40620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
40630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    String smartUrlFilter(String url) {
40640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
40650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String inUrl = url.trim();
40660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        boolean hasSpace = inUrl.indexOf(' ') != -1;
40670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
40680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        Matcher matcher = ACCEPTED_URI_SCHEMA.matcher(inUrl);
40690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (matcher.matches()) {
40700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // force scheme to lowercase
40710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            String scheme = matcher.group(1);
40720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            String lcScheme = scheme.toLowerCase();
40730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (!lcScheme.equals(scheme)) {
4074123ecfb21e7ca670e3d04efe58780b3bac54a9a1Mitsuru Oshima                inUrl = lcScheme + matcher.group(2);
4075123ecfb21e7ca670e3d04efe58780b3bac54a9a1Mitsuru Oshima            }
4076123ecfb21e7ca670e3d04efe58780b3bac54a9a1Mitsuru Oshima            if (hasSpace) {
4077123ecfb21e7ca670e3d04efe58780b3bac54a9a1Mitsuru Oshima                inUrl = inUrl.replace(" ", "%20");
40780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
40790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return inUrl;
40800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
40810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (hasSpace) {
4082565505b1a2c1d3099496af5910760087602e994aSatish Sampath            // FIXME: Is this the correct place to add to searches?
4083565505b1a2c1d3099496af5910760087602e994aSatish Sampath            // what if someone else calls this function?
4084565505b1a2c1d3099496af5910760087602e994aSatish Sampath            int shortcut = parseUrlShortcut(inUrl);
4085565505b1a2c1d3099496af5910760087602e994aSatish Sampath            if (shortcut != SHORTCUT_INVALID) {
4086565505b1a2c1d3099496af5910760087602e994aSatish Sampath                Browser.addSearchUrl(mResolver, inUrl);
4087565505b1a2c1d3099496af5910760087602e994aSatish Sampath                String query = inUrl.substring(2);
4088565505b1a2c1d3099496af5910760087602e994aSatish Sampath                switch (shortcut) {
4089565505b1a2c1d3099496af5910760087602e994aSatish Sampath                case SHORTCUT_GOOGLE_SEARCH:
409047fdfdb989ffb79590a39c40792be995de32e521Grace Kloba                    return URLUtil.composeSearchUrl(query, QuickSearch_G, QUERY_PLACE_HOLDER);
4091565505b1a2c1d3099496af5910760087602e994aSatish Sampath                case SHORTCUT_WIKIPEDIA_SEARCH:
4092565505b1a2c1d3099496af5910760087602e994aSatish Sampath                    return URLUtil.composeSearchUrl(query, QuickSearch_W, QUERY_PLACE_HOLDER);
4093565505b1a2c1d3099496af5910760087602e994aSatish Sampath                case SHORTCUT_DICTIONARY_SEARCH:
4094565505b1a2c1d3099496af5910760087602e994aSatish Sampath                    return URLUtil.composeSearchUrl(query, QuickSearch_D, QUERY_PLACE_HOLDER);
4095565505b1a2c1d3099496af5910760087602e994aSatish Sampath                case SHORTCUT_GOOGLE_MOBILE_LOCAL_SEARCH:
40960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // FIXME: we need location in this case
4097565505b1a2c1d3099496af5910760087602e994aSatish Sampath                    return URLUtil.composeSearchUrl(query, QuickSearch_L, QUERY_PLACE_HOLDER);
40980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
40990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
41000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
41015ee906c089567bca705e18561357510d7b55cb5aDan Egnor            if (Patterns.WEB_URL.matcher(inUrl).matches()) {
41020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                return URLUtil.guessUrl(inUrl);
41030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
41040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
41050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
41060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        Browser.addSearchUrl(mResolver, inUrl);
410747fdfdb989ffb79590a39c40792be995de32e521Grace Kloba        return URLUtil.composeSearchUrl(inUrl, QuickSearch_G, QUERY_PLACE_HOLDER);
41080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
41090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
4110bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch    /* package */ void setShouldShowErrorConsole(boolean flag) {
4111bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch        if (flag == mShouldShowErrorConsole) {
4112bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch            // Nothing to do.
4113bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch            return;
4114bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch        }
4115bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch
4116bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch        mShouldShowErrorConsole = flag;
4117bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch
411822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        ErrorConsoleView errorConsole = mTabControl.getCurrentTab()
411922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                .getErrorConsole(true);
4120bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch
4121bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch        if (flag) {
4122bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch            // Setting the show state of the console will cause it's the layout to be inflated.
4123bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch            if (errorConsole.numberOfErrors() > 0) {
4124bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch                errorConsole.showConsole(ErrorConsoleView.SHOW_MINIMIZED);
4125bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch            } else {
4126bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch                errorConsole.showConsole(ErrorConsoleView.SHOW_NONE);
4127bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch            }
4128bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch
4129bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch            // Now we can add it to the main view.
4130bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch            mErrorConsoleContainer.addView(errorConsole,
413115b8ec6b226f4d57307716e1f495e10a91f8cbf4Romain Guy                    new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
4132bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch                                                  ViewGroup.LayoutParams.WRAP_CONTENT));
4133bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch        } else {
4134bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch            mErrorConsoleContainer.removeView(errorConsole);
4135bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch        }
4136bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch
4137bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch    }
4138bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch
413922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    boolean shouldShowErrorConsole() {
414022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return mShouldShowErrorConsole;
414122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
414222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
4143163ab74e2f85b53a1a374c49677073fb64d35f28Andrei Popescu    private void setStatusBarVisibility(boolean visible) {
4144163ab74e2f85b53a1a374c49677073fb64d35f28Andrei Popescu        int flag = visible ? 0 : WindowManager.LayoutParams.FLAG_FULLSCREEN;
4145163ab74e2f85b53a1a374c49677073fb64d35f28Andrei Popescu        getWindow().setFlags(flag, WindowManager.LayoutParams.FLAG_FULLSCREEN);
4146163ab74e2f85b53a1a374c49677073fb64d35f28Andrei Popescu    }
4147163ab74e2f85b53a1a374c49677073fb64d35f28Andrei Popescu
414856199cc25e7ee0455ec2a8099098b66b8554f677Andrei Popescu
414956199cc25e7ee0455ec2a8099098b66b8554f677Andrei Popescu    private void sendNetworkType(String type, String subtype) {
415056199cc25e7ee0455ec2a8099098b66b8554f677Andrei Popescu        WebView w = mTabControl.getCurrentWebView();
415156199cc25e7ee0455ec2a8099098b66b8554f677Andrei Popescu        if (w != null) {
415256199cc25e7ee0455ec2a8099098b66b8554f677Andrei Popescu            w.setNetworkType(type, subtype);
415356199cc25e7ee0455ec2a8099098b66b8554f677Andrei Popescu        }
415456199cc25e7ee0455ec2a8099098b66b8554f677Andrei Popescu    }
415556199cc25e7ee0455ec2a8099098b66b8554f677Andrei Popescu
4156eb6eef4c45df2d65c3e70660493a147a2be405e3Grace Kloba    final static int LOCK_ICON_UNSECURE = 0;
4157eb6eef4c45df2d65c3e70660493a147a2be405e3Grace Kloba    final static int LOCK_ICON_SECURE   = 1;
4158eb6eef4c45df2d65c3e70660493a147a2be405e3Grace Kloba    final static int LOCK_ICON_MIXED    = 2;
41590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
41600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private BrowserSettings mSettings;
41610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private TabControl      mTabControl;
41620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private ContentResolver mResolver;
41630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private FrameLayout     mContentView;
4164adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu    private View            mCustomView;
4165adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu    private FrameLayout     mCustomViewContainer;
4166c9b5556351b59caec77b4eec1ad30652fec6a4d9Andrei Popescu    private WebChromeClient.CustomViewCallback mCustomViewCallback;
41670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
41680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // FIXME, temp address onPrepareMenu performance problem. When we move everything out of
41690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // view, we should rewrite this.
41700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private int mCurrentMenuState = 0;
41710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private int mMenuState = R.id.MAIN_MENU;
4172adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu    private int mOldMenuState = EMPTY_MENU;
41730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private static final int EMPTY_MENU = -1;
41740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private Menu mMenu;
41750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
41760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Used to prevent chording to result in firing two shortcuts immediately
41770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // one after another.  Fixes bug 1211714.
41780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    boolean mCanChord;
41790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
41800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private boolean mInLoad;
41810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private boolean mIsNetworkUp;
4182b7cc8b439dc595dc48e1c2183b35d23ad72dfbe5Ben Murdoch    private boolean mDidStopLoad;
41830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
41841f10cbfca5bf96e1466e0ed3ce1dbcd6fcfd0608Cary Clark    /* package */ boolean mActivityInPause = true;
41850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
41860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private boolean mMenuIsDown;
41870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
41880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private static boolean mInTrace;
41890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
41900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Performance probe
41910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private static final int[] SYSTEM_CPU_FORMAT = new int[] {
41920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Process.PROC_SPACE_TERM | Process.PROC_COMBINE,
41930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Process.PROC_SPACE_TERM | Process.PROC_OUT_LONG, // 1: user time
41940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Process.PROC_SPACE_TERM | Process.PROC_OUT_LONG, // 2: nice time
41950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Process.PROC_SPACE_TERM | Process.PROC_OUT_LONG, // 3: sys time
41960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Process.PROC_SPACE_TERM | Process.PROC_OUT_LONG, // 4: idle time
41970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Process.PROC_SPACE_TERM | Process.PROC_OUT_LONG, // 5: iowait time
41980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Process.PROC_SPACE_TERM | Process.PROC_OUT_LONG, // 6: irq time
41990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Process.PROC_SPACE_TERM | Process.PROC_OUT_LONG  // 7: softirq time
42000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    };
42010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
42020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private long mStart;
42030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private long mProcessStart;
42040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private long mUserStart;
42050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private long mSystemStart;
42060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private long mIdleStart;
42070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private long mIrqStart;
42080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
42090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private long mUiStart;
42100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
42110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private Drawable    mMixLockIcon;
42120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private Drawable    mSecLockIcon;
42130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
42140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /* hold a ref so we can auto-cancel if necessary */
42150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private AlertDialog mAlertDialog;
42160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
42170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // The up-to-date URL and title (these can be different from those stored
42180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // in WebView, since it takes some time for the information in WebView to
42190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // get updated)
42200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private String mUrl;
42210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private String mTitle;
42220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
42230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // As PageInfo has different style for landscape / portrait, we have
42240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // to re-open it when configuration changed
42250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private AlertDialog mPageInfoDialog;
422622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private Tab mPageInfoView;
42270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // If the Page-Info dialog is launched from the SSL-certificate-on-error
42280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // dialog, we should not just dismiss it, but should get back to the
42290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // SSL-certificate-on-error dialog. This flag is used to store this state
4230c7b92f811dfa3572578ddc6714c98a03936d9ce5Leon Scroggins    private boolean mPageInfoFromShowSSLCertificateOnError;
42310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
42320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // as SSLCertificateOnError has different style for landscape / portrait,
42330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // we have to re-open it when configuration changed
42340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private AlertDialog mSSLCertificateOnErrorDialog;
42350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private WebView mSSLCertificateOnErrorView;
42360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private SslErrorHandler mSSLCertificateOnErrorHandler;
42370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private SslError mSSLCertificateOnErrorError;
42380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
42390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // as SSLCertificate has different style for landscape / portrait, we
42400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // have to re-open it when configuration changed
42410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private AlertDialog mSSLCertificateDialog;
424222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private Tab mSSLCertificateView;
42430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
42440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // as HttpAuthentication has different style for landscape / portrait, we
42450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // have to re-open it when configuration changed
42460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private AlertDialog mHttpAuthenticationDialog;
42470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private HttpAuthHandler mHttpAuthHandler;
42480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
42490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /*package*/ static final FrameLayout.LayoutParams COVER_SCREEN_PARAMS =
42500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                            new FrameLayout.LayoutParams(
425115b8ec6b226f4d57307716e1f495e10a91f8cbf4Romain Guy                                            ViewGroup.LayoutParams.MATCH_PARENT,
425215b8ec6b226f4d57307716e1f495e10a91f8cbf4Romain Guy                                            ViewGroup.LayoutParams.MATCH_PARENT);
4253adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu    /*package*/ static final FrameLayout.LayoutParams COVER_SCREEN_GRAVITY_CENTER =
4254adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu                                            new FrameLayout.LayoutParams(
425515b8ec6b226f4d57307716e1f495e10a91f8cbf4Romain Guy                                            ViewGroup.LayoutParams.MATCH_PARENT,
425615b8ec6b226f4d57307716e1f495e10a91f8cbf4Romain Guy                                            ViewGroup.LayoutParams.MATCH_PARENT,
4257adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu                                            Gravity.CENTER);
425847fdfdb989ffb79590a39c40792be995de32e521Grace Kloba    // Google search
425947fdfdb989ffb79590a39c40792be995de32e521Grace Kloba    final static String QuickSearch_G = "http://www.google.com/m?q=%s";
42600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Wikipedia search
42610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    final static String QuickSearch_W = "http://en.wikipedia.org/w/index.php?search=%s&go=Go";
42620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Dictionary search
42630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    final static String QuickSearch_D = "http://dictionary.reference.com/search?q=%s";
42640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Google Mobile Local search
42650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    final static String QuickSearch_L = "http://www.google.com/m/search?site=local&q=%s&near=mountain+view";
42660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
42670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    final static String QUERY_PLACE_HOLDER = "%s";
42680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
42690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // "source" parameter for Google search through search key
42700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    final static String GOOGLE_SEARCH_SOURCE_SEARCHKEY = "browser-key";
42710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // "source" parameter for Google search through goto menu
42720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    final static String GOOGLE_SEARCH_SOURCE_GOTO = "browser-goto";
42730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // "source" parameter for Google search through simplily type
42740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    final static String GOOGLE_SEARCH_SOURCE_TYPE = "browser-type";
42750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // "source" parameter for Google search suggested by the browser
42760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    final static String GOOGLE_SEARCH_SOURCE_SUGGEST = "browser-suggest";
42770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // "source" parameter for Google search from unknown source
42780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    final static String GOOGLE_SEARCH_SOURCE_UNKNOWN = "unknown";
42790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
42800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private final static String LOGTAG = "browser";
42810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
42820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private String mLastEnteredUrl;
42830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
42840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private PowerManager.WakeLock mWakeLock;
42850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private final static int WAKELOCK_TIMEOUT = 5 * 60 * 1000; // 5 minutes
42860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
42870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private Toast mStopToast;
42880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
4289571b3762a5eb9e492283e0a1e437edd209fdc0deLeon Scroggins    private TitleBarBase mTitleBar;
4290a2b2ba8da913f26c820e49d3e43158e2fe6ebebaMichael Kolb    private TabBar mTabBar;
429181db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins
4292bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch    private LinearLayout mErrorConsoleContainer = null;
4293bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch    private boolean mShouldShowErrorConsole = false;
4294bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch
42950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // As the ids are dynamically created, we can't guarantee that they will
42960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // be in sequence, so this static array maps ids to a window number.
42970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    final static private int[] WINDOW_SHORTCUT_ID_ARRAY =
42980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    { R.id.window_one_menu_id, R.id.window_two_menu_id, R.id.window_three_menu_id,
42990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project      R.id.window_four_menu_id, R.id.window_five_menu_id, R.id.window_six_menu_id,
43000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project      R.id.window_seven_menu_id, R.id.window_eight_menu_id };
43010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
43020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // monitor platform changes
43030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private IntentFilter mNetworkStateChangedFilter;
43040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private BroadcastReceiver mNetworkStateIntentReceiver;
43050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
4306a7611811e0d744a7220b7bf80c8f795af5ea53edBjorn Bringert    private SystemAllowGeolocationOrigins mSystemAllowGeolocationOrigins;
4307a7611811e0d744a7220b7bf80c8f795af5ea53edBjorn Bringert
43080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // activity requestCode
430978a98e459323f938e97789a6131beddbebb459ceNicolas Roard    final static int COMBO_PAGE                 = 1;
431078a98e459323f938e97789a6131beddbebb459ceNicolas Roard    final static int DOWNLOAD_PAGE              = 2;
431178a98e459323f938e97789a6131beddbebb459ceNicolas Roard    final static int PREFERENCES_PAGE           = 3;
43128d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins    final static int FILE_SELECTED              = 4;
43130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
4314540035dfd1347c78eeec10ec0847e18fcc50ef36Andrei Popescu    // the default <video> poster
4315540035dfd1347c78eeec10ec0847e18fcc50ef36Andrei Popescu    private Bitmap mDefaultVideoPoster;
4316540035dfd1347c78eeec10ec0847e18fcc50ef36Andrei Popescu    // the video progress view
4317540035dfd1347c78eeec10ec0847e18fcc50ef36Andrei Popescu    private View mVideoProgressView;
4318540035dfd1347c78eeec10ec0847e18fcc50ef36Andrei Popescu
431925ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima    /**
432025ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima     * A UrlData class to abstract how the content will be set to WebView.
432125ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima     * This base class uses loadUrl to show the content.
432225ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima     */
43236eac63e78d43d04e31c4d16830c44c4d9df82639Leon Scroggins    /* package */ static class UrlData {
4324068e48b469f5abca53ee3da38f933cf2c25c93b8Grace Kloba        final String mUrl;
4325068e48b469f5abca53ee3da38f933cf2c25c93b8Grace Kloba        final Map<String, String> mHeaders;
432658d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        final Intent mVoiceIntent;
432760e095c190496d42327f8ec2ef990c044d15a76fGrace Kloba
432825ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima        UrlData(String url) {
432925ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima            this.mUrl = url;
4330068e48b469f5abca53ee3da38f933cf2c25c93b8Grace Kloba            this.mHeaders = null;
433158d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins            this.mVoiceIntent = null;
433225ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima        }
433360e095c190496d42327f8ec2ef990c044d15a76fGrace Kloba
433458d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        UrlData(String url, Map<String, String> headers, Intent intent) {
4335068e48b469f5abca53ee3da38f933cf2c25c93b8Grace Kloba            this.mUrl = url;
4336068e48b469f5abca53ee3da38f933cf2c25c93b8Grace Kloba            this.mHeaders = headers;
4337a1cc3fdce19a336c251297c61cd83ac6cf767cd1Leon Scroggins            if (RecognizerResultsIntent.ACTION_VOICE_SEARCH_RESULTS
4338a1cc3fdce19a336c251297c61cd83ac6cf767cd1Leon Scroggins                    .equals(intent.getAction())) {
433958d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins                this.mVoiceIntent = intent;
434058d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins            } else {
434158d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins                this.mVoiceIntent = null;
434258d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins            }
434360e095c190496d42327f8ec2ef990c044d15a76fGrace Kloba        }
434460e095c190496d42327f8ec2ef990c044d15a76fGrace Kloba
434525ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima        boolean isEmpty() {
434658d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins            return mVoiceIntent == null && (mUrl == null || mUrl.length() == 0);
434725ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima        }
434825ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima
434992472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins        /**
435092472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins         * Load this UrlData into the given Tab.  Use loadUrlDataIn to update
435192472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins         * the title bar as well.
435292472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins         */
435358d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        public void loadIn(Tab t) {
435458d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins            if (mVoiceIntent != null) {
435558d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins                t.activateVoiceSearchMode(mVoiceIntent);
435658d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins            } else {
435758d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins                t.getWebView().loadUrl(mUrl, mHeaders);
435858d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins            }
435925ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima        }
436025ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima    };
436125ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima
43621f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins    /* package */ static final UrlData EMPTY_URL_DATA = new UrlData(null);
43630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project}
4364