BrowserActivity.java revision ccb5de06714993c28d16f1e5abfcd9f0b1e656fc
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
190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.app.Activity;
200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.app.AlertDialog;
210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.app.ProgressDialog;
220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.app.SearchManager;
230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.content.ActivityNotFoundException;
240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.content.BroadcastReceiver;
250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.content.ComponentName;
2658d56c6b5052faa86083965132cd51b1a9594d0eLeon Scrogginsimport android.content.ContentProvider;
2758d56c6b5052faa86083965132cd51b1a9594d0eLeon Scrogginsimport android.content.ContentProviderClient;
280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.content.ContentResolver;
29b6b7f9ef3b4ed220063f555d8b7c205210a61a04Leon Scrogginsimport android.content.ContentUris;
300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.content.ContentValues;
310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.content.Context;
320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.content.DialogInterface;
330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.content.Intent;
340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.content.IntentFilter;
35b4da0ad0351996f639b50f9f29b123a9b5c24fd0Grace Klobaimport android.content.pm.PackageInfo;
360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.content.pm.PackageManager;
370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.content.pm.ResolveInfo;
380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.content.res.Configuration;
390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.content.res.Resources;
400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.database.Cursor;
410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.graphics.Bitmap;
42540035dfd1347c78eeec10ec0847e18fcc50ef36Andrei Popescuimport android.graphics.BitmapFactory;
430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.graphics.Canvas;
440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.graphics.Picture;
453bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scrogginsimport android.graphics.PixelFormat;
460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.graphics.drawable.Drawable;
470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.net.ConnectivityManager;
4856199cc25e7ee0455ec2a8099098b66b8554f677Andrei Popescuimport android.net.NetworkInfo;
490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.net.Uri;
500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.net.WebAddress;
510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.net.http.SslCertificate;
520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.net.http.SslError;
530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.os.AsyncTask;
540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.os.Bundle;
550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.os.Debug;
560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.os.Environment;
570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.os.Handler;
580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.os.Message;
590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.os.PowerManager;
600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.os.Process;
610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.os.ServiceManager;
620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.os.SystemClock;
630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.provider.Browser;
645e335a381a0cd66e94117b202c1f34f5cb29c9b8Cary Clarkimport android.provider.ContactsContract;
650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.provider.Downloads;
660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.provider.MediaStore;
67e0a3666b5c0dca7352895fa8b9b4fbb2237df721Michael Kolbimport android.provider.ContactsContract.Intents.Insert;
68a1cc3fdce19a336c251297c61cd83ac6cf767cd1Leon Scrogginsimport android.speech.RecognizerResultsIntent;
690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.text.IClipboard;
700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.text.TextUtils;
710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.text.format.DateFormat;
720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.util.Log;
73385effd3192a16b737a7d4fbe4fc71c6cf467627Dianne Hackbornimport android.util.Patterns;
740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.view.ContextMenu;
750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.view.Gravity;
760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.view.KeyEvent;
770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.view.LayoutInflater;
780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.view.Menu;
790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.view.MenuInflater;
800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.view.MenuItem;
810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.view.View;
820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.view.ViewGroup;
830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.view.Window;
840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.view.WindowManager;
850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.view.ContextMenu.ContextMenuInfo;
860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.view.MenuItem.OnMenuItemClickListener;
872b34599c39d2c04c242d2a0ed755705fc414541dSvetoslav Ganovimport android.view.accessibility.AccessibilityManager;
880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.webkit.CookieManager;
890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.webkit.CookieSyncManager;
900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.webkit.DownloadListener;
910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.webkit.HttpAuthHandler;
92b4da0ad0351996f639b50f9f29b123a9b5c24fd0Grace Klobaimport android.webkit.PluginManager;
930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.webkit.SslErrorHandler;
940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.webkit.URLUtil;
95cb6cc864e53f7d916622daf3b2cec133b36d6a55Leon Clarkeimport android.webkit.ValueCallback;
960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.webkit.WebChromeClient;
970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.webkit.WebHistoryItem;
980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.webkit.WebIconDatabase;
990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.webkit.WebView;
1000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.widget.EditText;
1010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.widget.FrameLayout;
1020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.widget.LinearLayout;
1030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.widget.TextView;
1040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.widget.Toast;
1050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
10610d1cca0c208d1f9db23893a8515685e04cfe224Bjorn Bringertimport com.android.common.Search;
1071fe13a5230e319df42b21939a14d127bd9bf3856Leon Scrogginsimport com.android.common.speech.LoggingEvents;
1085ee906c089567bca705e18561357510d7b55cb5aDan Egnor
109b6b7f9ef3b4ed220063f555d8b7c205210a61a04Leon Scrogginsimport java.io.ByteArrayOutputStream;
1100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport java.io.File;
1114f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdochimport java.io.IOException;
1124f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdochimport java.io.InputStream;
1130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport java.net.MalformedURLException;
1149918943559193e3e047a1c18442e2cdb0fe22b15Dianne Hackbornimport java.net.URISyntaxException;
1150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport java.net.URL;
1160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport java.net.URLEncoder;
1170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport java.util.Date;
1180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport java.util.HashMap;
11930995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescuimport java.util.HashSet;
12000f54c589fd38431efd42ea2a551a49e64d595d5Grace Klobaimport java.util.Iterator;
12130995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescuimport java.util.List;
122068e48b469f5abca53ee3da38f933cf2c25c93b8Grace Klobaimport java.util.Map;
12330995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescuimport java.util.Set;
1240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport java.util.regex.Matcher;
1250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport java.util.regex.Pattern;
1266af492aeddda96c749142885e3b49455aa336309Ben Murdochimport java.util.Vector;
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
16722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    @Override
16822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    public void onCreate(Bundle icicle) {
16931a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort        if (LOGV_ENABLED) {
1700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Log.v(LOGTAG, this + " onStart");
1710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
1720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        super.onCreate(icicle);
1730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // test the browser in OpenGL
1740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // requestWindowFeature(Window.FEATURE_OPENGL);
1750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
176d334bf564b72416e77e707d25f8c55cfe1d85709Mike Reed        // enable this to test the browser in 32bit
177d334bf564b72416e77e707d25f8c55cfe1d85709Mike Reed        if (false) {
178d334bf564b72416e77e707d25f8c55cfe1d85709Mike Reed            getWindow().setFormat(PixelFormat.RGBX_8888);
179d334bf564b72416e77e707d25f8c55cfe1d85709Mike Reed            BitmapFactory.setDefaultConfig(Bitmap.Config.ARGB_8888);
180d334bf564b72416e77e707d25f8c55cfe1d85709Mike Reed        }
181d334bf564b72416e77e707d25f8c55cfe1d85709Mike Reed
1822b34599c39d2c04c242d2a0ed755705fc414541dSvetoslav Ganov        if (AccessibilityManager.getInstance(this).isEnabled()) {
1832b34599c39d2c04c242d2a0ed755705fc414541dSvetoslav Ganov            setDefaultKeyMode(DEFAULT_KEYS_DISABLE);
1842b34599c39d2c04c242d2a0ed755705fc414541dSvetoslav Ganov        } else {
1852b34599c39d2c04c242d2a0ed755705fc414541dSvetoslav Ganov            setDefaultKeyMode(DEFAULT_KEYS_SEARCH_LOCAL);
1862b34599c39d2c04c242d2a0ed755705fc414541dSvetoslav Ganov        }
1870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
1880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mResolver = getContentResolver();
1890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
1900923d69a8ca45222cabd82a80eaa88da9f132e9aGrace Kloba        // If this was a web search request, pass it on to the default web
1910923d69a8ca45222cabd82a80eaa88da9f132e9aGrace Kloba        // search provider and finish this activity.
1920923d69a8ca45222cabd82a80eaa88da9f132e9aGrace Kloba        if (handleWebSearchIntent(getIntent())) {
1930923d69a8ca45222cabd82a80eaa88da9f132e9aGrace Kloba            finish();
1940923d69a8ca45222cabd82a80eaa88da9f132e9aGrace Kloba            return;
1950923d69a8ca45222cabd82a80eaa88da9f132e9aGrace Kloba        }
1960923d69a8ca45222cabd82a80eaa88da9f132e9aGrace Kloba
1970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mSecLockIcon = Resources.getSystem().getDrawable(
1980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                android.R.drawable.ic_secure);
1990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mMixLockIcon = Resources.getSystem().getDrawable(
2000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                android.R.drawable.ic_partial_secure);
2010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
20281db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins        FrameLayout frameLayout = (FrameLayout) getWindow().getDecorView()
20381db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins                .findViewById(com.android.internal.R.id.content);
2043bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins        mBrowserFrameLayout = (FrameLayout) LayoutInflater.from(this)
2053bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                .inflate(R.layout.custom_screen, null);
2063bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins        mContentView = (FrameLayout) mBrowserFrameLayout.findViewById(
2073bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                R.id.main_content);
2083bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins        mErrorConsoleContainer = (LinearLayout) mBrowserFrameLayout
2093bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                .findViewById(R.id.error_console);
2103bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins        mCustomViewContainer = (FrameLayout) mBrowserFrameLayout
2113bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                .findViewById(R.id.fullscreen_custom_content);
2123bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins        frameLayout.addView(mBrowserFrameLayout, COVER_SCREEN_PARAMS);
213d746a94137a87ffcc1fcefdac9a3764c3bc3f5cdLeon Scroggins        mXLargeScreenSize = (getResources().getConfiguration().screenLayout
214d746a94137a87ffcc1fcefdac9a3764c3bc3f5cdLeon Scroggins                & Configuration.SCREENLAYOUT_SIZE_MASK)
215d746a94137a87ffcc1fcefdac9a3764c3bc3f5cdLeon Scroggins                == Configuration.SCREENLAYOUT_SIZE_XLARGE;
216e0a3666b5c0dca7352895fa8b9b4fbb2237df721Michael Kolb
217d746a94137a87ffcc1fcefdac9a3764c3bc3f5cdLeon Scroggins        if (mXLargeScreenSize) {
218571b3762a5eb9e492283e0a1e437edd209fdc0deLeon Scroggins            mTitleBar = new TitleBarXLarge(this);
219d746a94137a87ffcc1fcefdac9a3764c3bc3f5cdLeon Scroggins            LinearLayout layout = (LinearLayout) mBrowserFrameLayout.
220d746a94137a87ffcc1fcefdac9a3764c3bc3f5cdLeon Scroggins                    findViewById(R.id.vertical_layout);
221d746a94137a87ffcc1fcefdac9a3764c3bc3f5cdLeon Scroggins            layout.addView(mTitleBar, 0, new LinearLayout.LayoutParams(
222d746a94137a87ffcc1fcefdac9a3764c3bc3f5cdLeon Scroggins                    ViewGroup.LayoutParams.MATCH_PARENT,
223d746a94137a87ffcc1fcefdac9a3764c3bc3f5cdLeon Scroggins                    ViewGroup.LayoutParams.WRAP_CONTENT));
224d746a94137a87ffcc1fcefdac9a3764c3bc3f5cdLeon Scroggins        } else {
225571b3762a5eb9e492283e0a1e437edd209fdc0deLeon Scroggins            mTitleBar = new TitleBar(this);
226d746a94137a87ffcc1fcefdac9a3764c3bc3f5cdLeon Scroggins            // mTitleBar will be always be shown in the fully loaded mode on
227d746a94137a87ffcc1fcefdac9a3764c3bc3f5cdLeon Scroggins            // phone
228d746a94137a87ffcc1fcefdac9a3764c3bc3f5cdLeon Scroggins            mTitleBar.setProgress(100);
229d746a94137a87ffcc1fcefdac9a3764c3bc3f5cdLeon Scroggins            // Fake title bar is not needed in xlarge layout
230d746a94137a87ffcc1fcefdac9a3764c3bc3f5cdLeon Scroggins            mFakeTitleBar = new TitleBar(this);
231d746a94137a87ffcc1fcefdac9a3764c3bc3f5cdLeon Scroggins        }
2320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
2330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Create the tab control and our initial tab
2340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mTabControl = new TabControl(this);
2350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
2360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Open the icon database and retain all the bookmark urls for favicons
2370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        retainIconsOnStartup();
2380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
2390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Keep a settings instance handy.
2400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mSettings = BrowserSettings.getInstance();
2410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mSettings.setTabControl(mTabControl);
2420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
2430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
2440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "Browser");
2450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
2466adacc90222a3293bc631ef88ee5613e23b2d4c0Patrick Scott        // Find out if the network is currently up.
2476adacc90222a3293bc631ef88ee5613e23b2d4c0Patrick Scott        ConnectivityManager cm = (ConnectivityManager) getSystemService(
2486adacc90222a3293bc631ef88ee5613e23b2d4c0Patrick Scott                Context.CONNECTIVITY_SERVICE);
2496adacc90222a3293bc631ef88ee5613e23b2d4c0Patrick Scott        NetworkInfo info = cm.getActiveNetworkInfo();
2506adacc90222a3293bc631ef88ee5613e23b2d4c0Patrick Scott        if (info != null) {
2516adacc90222a3293bc631ef88ee5613e23b2d4c0Patrick Scott            mIsNetworkUp = info.isAvailable();
2526adacc90222a3293bc631ef88ee5613e23b2d4c0Patrick Scott        }
2536adacc90222a3293bc631ef88ee5613e23b2d4c0Patrick Scott
254a34f686112fb4f9fbea00b8c2c47153d34e93e41Grace Kloba        /* enables registration for changes in network status from
255a34f686112fb4f9fbea00b8c2c47153d34e93e41Grace Kloba           http stack */
256a34f686112fb4f9fbea00b8c2c47153d34e93e41Grace Kloba        mNetworkStateChangedFilter = new IntentFilter();
257a34f686112fb4f9fbea00b8c2c47153d34e93e41Grace Kloba        mNetworkStateChangedFilter.addAction(
258a34f686112fb4f9fbea00b8c2c47153d34e93e41Grace Kloba                ConnectivityManager.CONNECTIVITY_ACTION);
259a34f686112fb4f9fbea00b8c2c47153d34e93e41Grace Kloba        mNetworkStateIntentReceiver = new BroadcastReceiver() {
260a34f686112fb4f9fbea00b8c2c47153d34e93e41Grace Kloba                @Override
261a34f686112fb4f9fbea00b8c2c47153d34e93e41Grace Kloba                public void onReceive(Context context, Intent intent) {
262a34f686112fb4f9fbea00b8c2c47153d34e93e41Grace Kloba                    if (intent.getAction().equals(
263a34f686112fb4f9fbea00b8c2c47153d34e93e41Grace Kloba                            ConnectivityManager.CONNECTIVITY_ACTION)) {
264e4c98469644d3fa2689cf6658b1999add13c7e0eAndrei Popescu
265e4c98469644d3fa2689cf6658b1999add13c7e0eAndrei Popescu                        NetworkInfo info = intent.getParcelableExtra(
266e4c98469644d3fa2689cf6658b1999add13c7e0eAndrei Popescu                                ConnectivityManager.EXTRA_NETWORK_INFO);
267e4c98469644d3fa2689cf6658b1999add13c7e0eAndrei Popescu                        String typeName = info.getTypeName();
268e4c98469644d3fa2689cf6658b1999add13c7e0eAndrei Popescu                        String subtypeName = info.getSubtypeName();
269e4c98469644d3fa2689cf6658b1999add13c7e0eAndrei Popescu                        sendNetworkType(typeName.toLowerCase(),
270e4c98469644d3fa2689cf6658b1999add13c7e0eAndrei Popescu                                (subtypeName != null ? subtypeName.toLowerCase() : ""));
271e4c98469644d3fa2689cf6658b1999add13c7e0eAndrei Popescu
272e4c98469644d3fa2689cf6658b1999add13c7e0eAndrei Popescu                        onNetworkToggle(info.isAvailable());
273a34f686112fb4f9fbea00b8c2c47153d34e93e41Grace Kloba                    }
274a34f686112fb4f9fbea00b8c2c47153d34e93e41Grace Kloba                }
275a34f686112fb4f9fbea00b8c2c47153d34e93e41Grace Kloba            };
276a34f686112fb4f9fbea00b8c2c47153d34e93e41Grace Kloba
277615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba        IntentFilter filter = new IntentFilter(Intent.ACTION_PACKAGE_ADDED);
278615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba        filter.addAction(Intent.ACTION_PACKAGE_REMOVED);
279615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba        filter.addDataScheme("package");
280615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba        mPackageInstallationReceiver = new BroadcastReceiver() {
281615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba            @Override
282615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba            public void onReceive(Context context, Intent intent) {
283615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                final String action = intent.getAction();
284615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                final String packageName = intent.getData()
285615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                        .getSchemeSpecificPart();
286615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                final boolean replacing = intent.getBooleanExtra(
287615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                        Intent.EXTRA_REPLACING, false);
288615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                if (Intent.ACTION_PACKAGE_REMOVED.equals(action) && replacing) {
289615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                    // if it is replacing, refreshPlugins() when adding
290615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                    return;
291615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                }
29230995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu
29330995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu                if (sGoogleApps.contains(packageName)) {
29430995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu                    BrowserActivity.this.packageChanged(packageName,
29530995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu                            Intent.ACTION_PACKAGE_ADDED.equals(action));
29630995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu                }
29730995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu
298615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                PackageManager pm = BrowserActivity.this.getPackageManager();
299615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                PackageInfo pkgInfo = null;
300615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                try {
301615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                    pkgInfo = pm.getPackageInfo(packageName,
302615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                            PackageManager.GET_PERMISSIONS);
303615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                } catch (PackageManager.NameNotFoundException e) {
304615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                    return;
305615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                }
306615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                if (pkgInfo != null) {
307615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                    String permissions[] = pkgInfo.requestedPermissions;
308615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                    if (permissions == null) {
309615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                        return;
310615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                    }
311615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                    boolean permissionOk = false;
312615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                    for (String permit : permissions) {
313615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                        if (PluginManager.PLUGIN_PERMISSION.equals(permit)) {
314615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                            permissionOk = true;
315615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                            break;
316615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                        }
317615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                    }
318615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                    if (permissionOk) {
319615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                        PluginManager.getInstance(BrowserActivity.this)
320e56a0f21b2c1483e1854d31050bbcb10693dc0e2Grace Kloba                                .refreshPlugins(true);
321615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                    }
322615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                }
323615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba            }
324615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba        };
325615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba        registerReceiver(mPackageInstallationReceiver, filter);
326615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba
3270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (!mTabControl.restoreState(icicle)) {
3280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // clear up the thumbnail directory if we can't restore the state as
3290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // none of the files in the directory are referenced any more.
3300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            new ClearThumbnails().execute(
3310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    mTabControl.getThumbnailDir().listFiles());
332aab3f09b5c2d39b19067e57635614080b2403a46Grace Kloba            // there is no quit on Android. But if we can't restore the state,
333aab3f09b5c2d39b19067e57635614080b2403a46Grace Kloba            // we can treat it as a new Browser, remove the old session cookies.
334aab3f09b5c2d39b19067e57635614080b2403a46Grace Kloba            CookieManager.getInstance().removeSessionCookie();
3350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            final Intent intent = getIntent();
3360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            final Bundle extra = intent.getExtras();
3370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Create an initial tab.
3380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // If the intent is ACTION_VIEW and data is not null, the Browser is
3390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // invoked to view the content by another application. In this case,
3400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // the tab will be close when exit.
34125ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima            UrlData urlData = getUrlDataFromIntent(intent);
34225ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima
34358d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins            String action = intent.getAction();
34422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            final Tab t = mTabControl.createNewTab(
34558d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins                    (Intent.ACTION_VIEW.equals(action) &&
34658d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins                    intent.getData() != null)
347a1cc3fdce19a336c251297c61cd83ac6cf767cd1Leon Scroggins                    || RecognizerResultsIntent.ACTION_VOICE_SEARCH_RESULTS
348a1cc3fdce19a336c251297c61cd83ac6cf767cd1Leon Scroggins                    .equals(action),
34925ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima                    intent.getStringExtra(Browser.EXTRA_APPLICATION_ID), urlData.mUrl);
3500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mTabControl.setCurrentTab(t);
3510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            attachTabToContentView(t);
3520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            WebView webView = t.getWebView();
3530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (extra != null) {
3540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                int scale = extra.getInt(Browser.INITIAL_ZOOM_LEVEL, 0);
3550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (scale > 0 && scale <= 1000) {
3560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    webView.setInitialScale(scale);
3570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
3580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
3590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
36025ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima            if (urlData.isEmpty()) {
36198d5fce7c687cfcc956b10d44946d31f39b6dc15Shimeng (Simon) Wang                loadUrl(webView, mSettings.getHomePage());
3620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } else {
3639d53da05812f959745810a33bb4e06b273393c42Patrick Scott                loadUrlDataIn(t, urlData);
3640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
3650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
3660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // TabControl.restoreState() will create a new tab even if
3671f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins            // restoring the state fails.
3680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            attachTabToContentView(mTabControl.getCurrentTab());
3690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
370615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba
371b3c02da4553b1a629b16377970fdabae28394c94Feng Qian        // Read JavaScript flags if it exists.
372b3c02da4553b1a629b16377970fdabae28394c94Feng Qian        String jsFlags = mSettings.getJsFlags();
373b3c02da4553b1a629b16377970fdabae28394c94Feng Qian        if (jsFlags.trim().length() != 0) {
374b3c02da4553b1a629b16377970fdabae28394c94Feng Qian            mTabControl.getCurrentWebView().setJsFlags(jsFlags);
375b3c02da4553b1a629b16377970fdabae28394c94Feng Qian        }
37630995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu        // Work out which packages are installed on the system.
37730995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu        getInstalledPackages();
378a7611811e0d744a7220b7bf80c8f795af5ea53edBjorn Bringert
379a7611811e0d744a7220b7bf80c8f795af5ea53edBjorn Bringert        // Start watching the default geolocation permissions
380a7611811e0d744a7220b7bf80c8f795af5ea53edBjorn Bringert        mSystemAllowGeolocationOrigins
381a7611811e0d744a7220b7bf80c8f795af5ea53edBjorn Bringert                = new SystemAllowGeolocationOrigins(getApplicationContext());
382a7611811e0d744a7220b7bf80c8f795af5ea53edBjorn Bringert        mSystemAllowGeolocationOrigins.start();
3830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
3840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
38558d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    /**
38658d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins     * Feed the previously stored results strings to the BrowserProvider so that
38758d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins     * the SearchDialog will show them instead of the standard searches.
38858d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins     * @param result String to show on the editable line of the SearchDialog.
38958d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins     */
39058d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    /* package */ void showVoiceSearchResults(String result) {
39158d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        ContentProviderClient client = mResolver.acquireContentProviderClient(
39258d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins                Browser.BOOKMARKS_URI);
39358d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        ContentProvider prov = client.getLocalContentProvider();
39458d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        BrowserProvider bp = (BrowserProvider) prov;
39558d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        bp.setQueryResults(mTabControl.getCurrentTab().getVoiceSearchResults());
39658d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        client.release();
39758d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins
398fbb3f15f725e890837431f402b43e802045a4f3fLeon Scroggins        Bundle bundle = createGoogleSearchSourceBundle(
399fbb3f15f725e890837431f402b43e802045a4f3fLeon Scroggins                GOOGLE_SEARCH_SOURCE_SEARCHKEY);
400fbb3f15f725e890837431f402b43e802045a4f3fLeon Scroggins        bundle.putBoolean(SearchManager.CONTEXT_IS_VOICE, true);
401fbb3f15f725e890837431f402b43e802045a4f3fLeon Scroggins        startSearch(result, false, bundle, false);
40258d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    }
40358d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins
4040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    @Override
4050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    protected void onNewIntent(Intent intent) {
40622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        Tab current = mTabControl.getCurrentTab();
4070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // When a tab is closed on exit, the current tab index is set to -1.
4080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Reset before proceed as Browser requires the current tab to be set.
4090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (current == null) {
4100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Try to reset the tab in case the index was incorrect.
4110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            current = mTabControl.getTab(0);
4120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (current == null) {
4130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // No tabs at all so just ignore this intent.
4140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                return;
4150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
4160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mTabControl.setCurrentTab(current);
4170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            attachTabToContentView(current);
4180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            resetTitleAndIcon(current.getWebView());
4190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
4200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final String action = intent.getAction();
4210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final int flags = intent.getFlags();
4220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (Intent.ACTION_MAIN.equals(action) ||
4230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                (flags & Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY) != 0) {
4240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // just resume the browser
4250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
4260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
427b8a844da0049965b3cef5739dbab19c7ac766762Leon Scroggins        // In case the SearchDialog is open.
428b8a844da0049965b3cef5739dbab19c7ac766762Leon Scroggins        ((SearchManager) getSystemService(Context.SEARCH_SERVICE))
429b8a844da0049965b3cef5739dbab19c7ac766762Leon Scroggins                .stopSearch();
430a1cc3fdce19a336c251297c61cd83ac6cf767cd1Leon Scroggins        boolean activateVoiceSearch = RecognizerResultsIntent
431a1cc3fdce19a336c251297c61cd83ac6cf767cd1Leon Scroggins                .ACTION_VOICE_SEARCH_RESULTS.equals(action);
4320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (Intent.ACTION_VIEW.equals(action)
4330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                || Intent.ACTION_SEARCH.equals(action)
4340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                || MediaStore.INTENT_ACTION_MEDIA_SEARCH.equals(action)
43558d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins                || Intent.ACTION_WEB_SEARCH.equals(action)
43658d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins                || activateVoiceSearch) {
4373b18ce37c13fce7212948df90a012d7011924a6eLeon Scroggins            if (current.isInVoiceSearchMode()) {
4383b18ce37c13fce7212948df90a012d7011924a6eLeon Scroggins                String title = current.getVoiceDisplayTitle();
4393b18ce37c13fce7212948df90a012d7011924a6eLeon Scroggins                if (title != null && title.equals(intent.getStringExtra(
4403b18ce37c13fce7212948df90a012d7011924a6eLeon Scroggins                        SearchManager.QUERY))) {
4413b18ce37c13fce7212948df90a012d7011924a6eLeon Scroggins                    // The user submitted the same search as the last voice
4423b18ce37c13fce7212948df90a012d7011924a6eLeon Scroggins                    // search, so do nothing.
4433b18ce37c13fce7212948df90a012d7011924a6eLeon Scroggins                    return;
4443b18ce37c13fce7212948df90a012d7011924a6eLeon Scroggins                }
4451fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins                if (Intent.ACTION_SEARCH.equals(action)
4461fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins                        && current.voiceSearchSourceIsGoogle()) {
4471fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins                    Intent logIntent = new Intent(
4481fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins                            LoggingEvents.ACTION_LOG_EVENT);
4491fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins                    logIntent.putExtra(LoggingEvents.EXTRA_EVENT,
4501fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins                            LoggingEvents.VoiceSearch.QUERY_UPDATED);
4511fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins                    logIntent.putExtra(
4521fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins                            LoggingEvents.VoiceSearch.EXTRA_QUERY_UPDATED_VALUE,
4531fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins                            intent.getDataString());
4541fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins                    sendBroadcast(logIntent);
4551fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins                    // Note, onPageStarted will revert the voice title bar
4561fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins                    // When http://b/issue?id=2379215 is fixed, we should update
4571fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins                    // the title bar here.
4581fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins                }
4593b18ce37c13fce7212948df90a012d7011924a6eLeon Scroggins            }
460565505b1a2c1d3099496af5910760087602e994aSatish Sampath            // If this was a search request (e.g. search query directly typed into the address bar),
461565505b1a2c1d3099496af5910760087602e994aSatish Sampath            // pass it on to the default web search provider.
462565505b1a2c1d3099496af5910760087602e994aSatish Sampath            if (handleWebSearchIntent(intent)) {
463565505b1a2c1d3099496af5910760087602e994aSatish Sampath                return;
464565505b1a2c1d3099496af5910760087602e994aSatish Sampath            }
465565505b1a2c1d3099496af5910760087602e994aSatish Sampath
46625ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima            UrlData urlData = getUrlDataFromIntent(intent);
46725ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima            if (urlData.isEmpty()) {
46825ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima                urlData = new UrlData(mSettings.getHomePage());
4690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
47025ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima
471cc63403643786905262f505ab5266d8e80b9924cGrace Kloba            final String appId = intent
472cc63403643786905262f505ab5266d8e80b9924cGrace Kloba                    .getStringExtra(Browser.EXTRA_APPLICATION_ID);
4734720868afa09efffadd845019f2d8268ae3f2c78Leon Scroggins            if ((Intent.ACTION_VIEW.equals(action)
4744720868afa09efffadd845019f2d8268ae3f2c78Leon Scroggins                    // If a voice search has no appId, it means that it came
4754720868afa09efffadd845019f2d8268ae3f2c78Leon Scroggins                    // from the browser.  In that case, reuse the current tab.
4764720868afa09efffadd845019f2d8268ae3f2c78Leon Scroggins                    || (activateVoiceSearch && appId != null))
477cc63403643786905262f505ab5266d8e80b9924cGrace Kloba                    && !getPackageName().equals(appId)
478cc63403643786905262f505ab5266d8e80b9924cGrace Kloba                    && (flags & Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT) != 0) {
47922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                Tab appTab = mTabControl.getTabFromId(appId);
480f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                if (appTab != null) {
481f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    Log.i(LOGTAG, "Reusing tab for " + appId);
482f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    // Dismiss the subwindow if applicable.
483f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    dismissSubWindow(appTab);
484f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    // Since we might kill the WebView, remove it from the
485f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    // content view first.
486f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    removeTabFromContentView(appTab);
487f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    // Recreate the main WebView after destroying the old one.
488f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    // If the WebView has the same original url and is on that
489f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    // page, it can be reused.
490f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    boolean needsLoad =
4916eac63e78d43d04e31c4d16830c44c4d9df82639Leon Scroggins                            mTabControl.recreateWebView(appTab, urlData);
492bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch
493f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    if (current != appTab) {
4941f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                        switchToTab(mTabControl.getTabIndex(appTab));
4951f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                        if (needsLoad) {
4969d53da05812f959745810a33bb4e06b273393c42Patrick Scott                            loadUrlDataIn(appTab, urlData);
4971f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                        }
498f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    } else {
4991f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                        // If the tab was the current tab, we have to attach
5001f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                        // it to the view system again.
5011f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                        attachTabToContentView(appTab);
5021f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                        if (needsLoad) {
5039d53da05812f959745810a33bb4e06b273393c42Patrick Scott                            loadUrlDataIn(appTab, urlData);
504f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                        }
505f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    }
506f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    return;
507cd11589fc3930906d4b9b7dd18aa52a9f1eb0c8aPatrick Scott                } else {
508cd11589fc3930906d4b9b7dd18aa52a9f1eb0c8aPatrick Scott                    // No matching application tab, try to find a regular tab
509cd11589fc3930906d4b9b7dd18aa52a9f1eb0c8aPatrick Scott                    // with a matching url.
510cd11589fc3930906d4b9b7dd18aa52a9f1eb0c8aPatrick Scott                    appTab = mTabControl.findUnusedTabWithUrl(urlData.mUrl);
51125515f8bd458a2471d13d876cfb0e18d8ff2a00fLeon Scroggins                    if (appTab != null) {
51225515f8bd458a2471d13d876cfb0e18d8ff2a00fLeon Scroggins                        if (current != appTab) {
51325515f8bd458a2471d13d876cfb0e18d8ff2a00fLeon Scroggins                            switchToTab(mTabControl.getTabIndex(appTab));
51425515f8bd458a2471d13d876cfb0e18d8ff2a00fLeon Scroggins                        }
51525515f8bd458a2471d13d876cfb0e18d8ff2a00fLeon Scroggins                        // Otherwise, we are already viewing the correct tab.
516cd11589fc3930906d4b9b7dd18aa52a9f1eb0c8aPatrick Scott                    } else {
517cd11589fc3930906d4b9b7dd18aa52a9f1eb0c8aPatrick Scott                        // if FLAG_ACTIVITY_BROUGHT_TO_FRONT flag is on, the url
518cd11589fc3930906d4b9b7dd18aa52a9f1eb0c8aPatrick Scott                        // will be opened in a new tab unless we have reached
519cd11589fc3930906d4b9b7dd18aa52a9f1eb0c8aPatrick Scott                        // MAX_TABS. Then the url will be opened in the current
520cd11589fc3930906d4b9b7dd18aa52a9f1eb0c8aPatrick Scott                        // tab. If a new tab is created, it will have "true" for
521cd11589fc3930906d4b9b7dd18aa52a9f1eb0c8aPatrick Scott                        // exit on close.
5221f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                        openTabAndShow(urlData, true, appId);
523cd11589fc3930906d4b9b7dd18aa52a9f1eb0c8aPatrick Scott                    }
524f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                }
5250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } else {
526638d3f45791a31d0b290e180b93bad49576eb6d3Grace Kloba                if (!urlData.isEmpty()
527638d3f45791a31d0b290e180b93bad49576eb6d3Grace Kloba                        && urlData.mUrl.startsWith("about:debug")) {
528638d3f45791a31d0b290e180b93bad49576eb6d3Grace Kloba                    if ("about:debug.dom".equals(urlData.mUrl)) {
529638d3f45791a31d0b290e180b93bad49576eb6d3Grace Kloba                        current.getWebView().dumpDomTree(false);
530638d3f45791a31d0b290e180b93bad49576eb6d3Grace Kloba                    } else if ("about:debug.dom.file".equals(urlData.mUrl)) {
531638d3f45791a31d0b290e180b93bad49576eb6d3Grace Kloba                        current.getWebView().dumpDomTree(true);
532638d3f45791a31d0b290e180b93bad49576eb6d3Grace Kloba                    } else if ("about:debug.render".equals(urlData.mUrl)) {
533638d3f45791a31d0b290e180b93bad49576eb6d3Grace Kloba                        current.getWebView().dumpRenderTree(false);
534638d3f45791a31d0b290e180b93bad49576eb6d3Grace Kloba                    } else if ("about:debug.render.file".equals(urlData.mUrl)) {
535638d3f45791a31d0b290e180b93bad49576eb6d3Grace Kloba                        current.getWebView().dumpRenderTree(true);
536638d3f45791a31d0b290e180b93bad49576eb6d3Grace Kloba                    } else if ("about:debug.display".equals(urlData.mUrl)) {
537638d3f45791a31d0b290e180b93bad49576eb6d3Grace Kloba                        current.getWebView().dumpDisplayTree();
5389b78e1d1e0bd819ae03df5594d4a56519e5d87c7Mike Reed                    } else if (urlData.mUrl.startsWith("about:debug.drag")) {
5399b78e1d1e0bd819ae03df5594d4a56519e5d87c7Mike Reed                        int index = urlData.mUrl.codePointAt(16) - '0';
5409b78e1d1e0bd819ae03df5594d4a56519e5d87c7Mike Reed                        if (index <= 0 || index > 9) {
5419b78e1d1e0bd819ae03df5594d4a56519e5d87c7Mike Reed                            current.getWebView().setDragTracker(null);
5429b78e1d1e0bd819ae03df5594d4a56519e5d87c7Mike Reed                        } else {
5439b78e1d1e0bd819ae03df5594d4a56519e5d87c7Mike Reed                            current.getWebView().setDragTracker(new MeshTracker(index));
5449b78e1d1e0bd819ae03df5594d4a56519e5d87c7Mike Reed                        }
545638d3f45791a31d0b290e180b93bad49576eb6d3Grace Kloba                    } else {
546638d3f45791a31d0b290e180b93bad49576eb6d3Grace Kloba                        mSettings.toggleDebugSettings();
547638d3f45791a31d0b290e180b93bad49576eb6d3Grace Kloba                    }
5480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    return;
5490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
5501f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                // Get rid of the subwindow if it exists
5511f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                dismissSubWindow(current);
5528588d15a7c0b87049469fd80f9c53eb274cd837bLeon Scroggins                // If the current Tab is being used as an application tab,
5538588d15a7c0b87049469fd80f9c53eb274cd837bLeon Scroggins                // remove the association, since the new Intent means that it is
5548588d15a7c0b87049469fd80f9c53eb274cd837bLeon Scroggins                // no longer associated with that application.
5558588d15a7c0b87049469fd80f9c53eb274cd837bLeon Scroggins                current.setAppId(null);
5569d53da05812f959745810a33bb4e06b273393c42Patrick Scott                loadUrlDataIn(current, urlData);
5570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
5580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
5590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
5600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
561565505b1a2c1d3099496af5910760087602e994aSatish Sampath    private int parseUrlShortcut(String url) {
562565505b1a2c1d3099496af5910760087602e994aSatish Sampath        if (url == null) return SHORTCUT_INVALID;
563565505b1a2c1d3099496af5910760087602e994aSatish Sampath
564565505b1a2c1d3099496af5910760087602e994aSatish Sampath        // FIXME: quick search, need to be customized by setting
565565505b1a2c1d3099496af5910760087602e994aSatish Sampath        if (url.length() > 2 && url.charAt(1) == ' ') {
566565505b1a2c1d3099496af5910760087602e994aSatish Sampath            switch (url.charAt(0)) {
567565505b1a2c1d3099496af5910760087602e994aSatish Sampath            case 'g': return SHORTCUT_GOOGLE_SEARCH;
568565505b1a2c1d3099496af5910760087602e994aSatish Sampath            case 'w': return SHORTCUT_WIKIPEDIA_SEARCH;
569565505b1a2c1d3099496af5910760087602e994aSatish Sampath            case 'd': return SHORTCUT_DICTIONARY_SEARCH;
570565505b1a2c1d3099496af5910760087602e994aSatish Sampath            case 'l': return SHORTCUT_GOOGLE_MOBILE_LOCAL_SEARCH;
571565505b1a2c1d3099496af5910760087602e994aSatish Sampath            }
572565505b1a2c1d3099496af5910760087602e994aSatish Sampath        }
573565505b1a2c1d3099496af5910760087602e994aSatish Sampath        return SHORTCUT_INVALID;
574565505b1a2c1d3099496af5910760087602e994aSatish Sampath    }
575565505b1a2c1d3099496af5910760087602e994aSatish Sampath
576565505b1a2c1d3099496af5910760087602e994aSatish Sampath    /**
577565505b1a2c1d3099496af5910760087602e994aSatish Sampath     * Launches the default web search activity with the query parameters if the given intent's data
578565505b1a2c1d3099496af5910760087602e994aSatish Sampath     * are identified as plain search terms and not URLs/shortcuts.
579565505b1a2c1d3099496af5910760087602e994aSatish Sampath     * @return true if the intent was handled and web search activity was launched, false if not.
580565505b1a2c1d3099496af5910760087602e994aSatish Sampath     */
581565505b1a2c1d3099496af5910760087602e994aSatish Sampath    private boolean handleWebSearchIntent(Intent intent) {
582565505b1a2c1d3099496af5910760087602e994aSatish Sampath        if (intent == null) return false;
583565505b1a2c1d3099496af5910760087602e994aSatish Sampath
584565505b1a2c1d3099496af5910760087602e994aSatish Sampath        String url = null;
585565505b1a2c1d3099496af5910760087602e994aSatish Sampath        final String action = intent.getAction();
586a1cc3fdce19a336c251297c61cd83ac6cf767cd1Leon Scroggins        if (RecognizerResultsIntent.ACTION_VOICE_SEARCH_RESULTS.equals(
587a1cc3fdce19a336c251297c61cd83ac6cf767cd1Leon Scroggins                action)) {
58858d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins            return false;
58958d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        }
590565505b1a2c1d3099496af5910760087602e994aSatish Sampath        if (Intent.ACTION_VIEW.equals(action)) {
5911e70505659dd9bf0f7e03bce787ba880f9b7a8aaGrace Kloba            Uri data = intent.getData();
5921e70505659dd9bf0f7e03bce787ba880f9b7a8aaGrace Kloba            if (data != null) url = data.toString();
593565505b1a2c1d3099496af5910760087602e994aSatish Sampath        } else if (Intent.ACTION_SEARCH.equals(action)
594565505b1a2c1d3099496af5910760087602e994aSatish Sampath                || MediaStore.INTENT_ACTION_MEDIA_SEARCH.equals(action)
595565505b1a2c1d3099496af5910760087602e994aSatish Sampath                || Intent.ACTION_WEB_SEARCH.equals(action)) {
596565505b1a2c1d3099496af5910760087602e994aSatish Sampath            url = intent.getStringExtra(SearchManager.QUERY);
597565505b1a2c1d3099496af5910760087602e994aSatish Sampath        }
5980485170e03e079eb61b9dd52fc2c98da02fa7b2cBjorn Bringert        return handleWebSearchRequest(url, intent.getBundleExtra(SearchManager.APP_DATA),
5990485170e03e079eb61b9dd52fc2c98da02fa7b2cBjorn Bringert                intent.getStringExtra(SearchManager.EXTRA_DATA_KEY));
600565505b1a2c1d3099496af5910760087602e994aSatish Sampath    }
601565505b1a2c1d3099496af5910760087602e994aSatish Sampath
602565505b1a2c1d3099496af5910760087602e994aSatish Sampath    /**
603565505b1a2c1d3099496af5910760087602e994aSatish Sampath     * Launches the default web search activity with the query parameters if the given url string
604565505b1a2c1d3099496af5910760087602e994aSatish Sampath     * was identified as plain search terms and not URL/shortcut.
605565505b1a2c1d3099496af5910760087602e994aSatish Sampath     * @return true if the request was handled and web search activity was launched, false if not.
606565505b1a2c1d3099496af5910760087602e994aSatish Sampath     */
6070485170e03e079eb61b9dd52fc2c98da02fa7b2cBjorn Bringert    private boolean handleWebSearchRequest(String inUrl, Bundle appData, String extraData) {
608565505b1a2c1d3099496af5910760087602e994aSatish Sampath        if (inUrl == null) return false;
609565505b1a2c1d3099496af5910760087602e994aSatish Sampath
610565505b1a2c1d3099496af5910760087602e994aSatish Sampath        // In general, we shouldn't modify URL from Intent.
611565505b1a2c1d3099496af5910760087602e994aSatish Sampath        // But currently, we get the user-typed URL from search box as well.
612565505b1a2c1d3099496af5910760087602e994aSatish Sampath        String url = fixUrl(inUrl).trim();
613565505b1a2c1d3099496af5910760087602e994aSatish Sampath
614565505b1a2c1d3099496af5910760087602e994aSatish Sampath        // URLs and site specific search shortcuts are handled by the regular flow of control, so
615565505b1a2c1d3099496af5910760087602e994aSatish Sampath        // return early.
6165ee906c089567bca705e18561357510d7b55cb5aDan Egnor        if (Patterns.WEB_URL.matcher(url).matches()
617bc5b9f358a2b75bf3a104b9f5cd477ad2f6f740fSatish Sampath                || ACCEPTED_URI_SCHEMA.matcher(url).matches()
618565505b1a2c1d3099496af5910760087602e994aSatish Sampath                || parseUrlShortcut(url) != SHORTCUT_INVALID) {
619565505b1a2c1d3099496af5910760087602e994aSatish Sampath            return false;
620565505b1a2c1d3099496af5910760087602e994aSatish Sampath        }
621565505b1a2c1d3099496af5910760087602e994aSatish Sampath
6228d06e36fe80f516e04ad33ff8b446720e36cabfdLeon Scroggins        final ContentResolver cr = mResolver;
6238d06e36fe80f516e04ad33ff8b446720e36cabfdLeon Scroggins        final String newUrl = url;
6248d06e36fe80f516e04ad33ff8b446720e36cabfdLeon Scroggins        new AsyncTask<Void, Void, Void>() {
625e0a3666b5c0dca7352895fa8b9b4fbb2237df721Michael Kolb            @Override
6268d06e36fe80f516e04ad33ff8b446720e36cabfdLeon Scroggins            protected Void doInBackground(Void... unused) {
6278d06e36fe80f516e04ad33ff8b446720e36cabfdLeon Scroggins                Browser.updateVisitedHistory(cr, newUrl, false);
6288d06e36fe80f516e04ad33ff8b446720e36cabfdLeon Scroggins                Browser.addSearchUrl(cr, newUrl);
6298d06e36fe80f516e04ad33ff8b446720e36cabfdLeon Scroggins                return null;
6308d06e36fe80f516e04ad33ff8b446720e36cabfdLeon Scroggins            }
6318d06e36fe80f516e04ad33ff8b446720e36cabfdLeon Scroggins        }.execute();
632565505b1a2c1d3099496af5910760087602e994aSatish Sampath
633565505b1a2c1d3099496af5910760087602e994aSatish Sampath        Intent intent = new Intent(Intent.ACTION_WEB_SEARCH);
634565505b1a2c1d3099496af5910760087602e994aSatish Sampath        intent.addCategory(Intent.CATEGORY_DEFAULT);
635565505b1a2c1d3099496af5910760087602e994aSatish Sampath        intent.putExtra(SearchManager.QUERY, url);
63615e9f2dc92cf1621f95071b3c740f46079aa0f3bSatish Sampath        if (appData != null) {
63715e9f2dc92cf1621f95071b3c740f46079aa0f3bSatish Sampath            intent.putExtra(SearchManager.APP_DATA, appData);
63815e9f2dc92cf1621f95071b3c740f46079aa0f3bSatish Sampath        }
6390485170e03e079eb61b9dd52fc2c98da02fa7b2cBjorn Bringert        if (extraData != null) {
6400485170e03e079eb61b9dd52fc2c98da02fa7b2cBjorn Bringert            intent.putExtra(SearchManager.EXTRA_DATA_KEY, extraData);
6410485170e03e079eb61b9dd52fc2c98da02fa7b2cBjorn Bringert        }
642cc63403643786905262f505ab5266d8e80b9924cGrace Kloba        intent.putExtra(Browser.EXTRA_APPLICATION_ID, getPackageName());
643565505b1a2c1d3099496af5910760087602e994aSatish Sampath        startActivity(intent);
644565505b1a2c1d3099496af5910760087602e994aSatish Sampath
645565505b1a2c1d3099496af5910760087602e994aSatish Sampath        return true;
646565505b1a2c1d3099496af5910760087602e994aSatish Sampath    }
647565505b1a2c1d3099496af5910760087602e994aSatish Sampath
64825ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima    private UrlData getUrlDataFromIntent(Intent intent) {
64958d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        String url = "";
650068e48b469f5abca53ee3da38f933cf2c25c93b8Grace Kloba        Map<String, String> headers = null;
6510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (intent != null) {
6520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            final String action = intent.getAction();
6530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (Intent.ACTION_VIEW.equals(action)) {
6540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                url = smartUrlFilter(intent.getData());
6550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (url != null && url.startsWith("content:")) {
6560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    /* Append mimetype so webview knows how to display */
6570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    String mimeType = intent.resolveType(getContentResolver());
6580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    if (mimeType != null) {
6590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        url += "?" + mimeType;
6600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
6610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
662068e48b469f5abca53ee3da38f933cf2c25c93b8Grace Kloba                if (url != null && url.startsWith("http")) {
66300f54c589fd38431efd42ea2a551a49e64d595d5Grace Kloba                    final Bundle pairs = intent
66400f54c589fd38431efd42ea2a551a49e64d595d5Grace Kloba                            .getBundleExtra(Browser.EXTRA_HEADERS);
6652d508edbf54ea74cd4e89be8b622b1cbd587464aGrace Kloba                    if (pairs != null && !pairs.isEmpty()) {
66600f54c589fd38431efd42ea2a551a49e64d595d5Grace Kloba                        Iterator<String> iter = pairs.keySet().iterator();
667068e48b469f5abca53ee3da38f933cf2c25c93b8Grace Kloba                        headers = new HashMap<String, String>();
66800f54c589fd38431efd42ea2a551a49e64d595d5Grace Kloba                        while (iter.hasNext()) {
66900f54c589fd38431efd42ea2a551a49e64d595d5Grace Kloba                            String key = iter.next();
67000f54c589fd38431efd42ea2a551a49e64d595d5Grace Kloba                            headers.put(key, pairs.getString(key));
671068e48b469f5abca53ee3da38f933cf2c25c93b8Grace Kloba                        }
672068e48b469f5abca53ee3da38f933cf2c25c93b8Grace Kloba                    }
67325ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima                }
6740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } else if (Intent.ACTION_SEARCH.equals(action)
6750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    || MediaStore.INTENT_ACTION_MEDIA_SEARCH.equals(action)
6760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    || Intent.ACTION_WEB_SEARCH.equals(action)) {
6770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                url = intent.getStringExtra(SearchManager.QUERY);
6780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (url != null) {
6790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    mLastEnteredUrl = url;
6800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // In general, we shouldn't modify URL from Intent.
6810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // But currently, we get the user-typed URL from search box as well.
6820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    url = fixUrl(url);
6830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    url = smartUrlFilter(url);
6848d06e36fe80f516e04ad33ff8b446720e36cabfdLeon Scroggins                    final ContentResolver cr = mResolver;
6858d06e36fe80f516e04ad33ff8b446720e36cabfdLeon Scroggins                    final String newUrl = url;
6868d06e36fe80f516e04ad33ff8b446720e36cabfdLeon Scroggins                    new AsyncTask<Void, Void, Void>() {
687e0a3666b5c0dca7352895fa8b9b4fbb2237df721Michael Kolb                        @Override
6888d06e36fe80f516e04ad33ff8b446720e36cabfdLeon Scroggins                        protected Void doInBackground(Void... unused) {
6898d06e36fe80f516e04ad33ff8b446720e36cabfdLeon Scroggins                            Browser.updateVisitedHistory(cr, newUrl, false);
6908d06e36fe80f516e04ad33ff8b446720e36cabfdLeon Scroggins                            return null;
6918d06e36fe80f516e04ad33ff8b446720e36cabfdLeon Scroggins                        }
6928d06e36fe80f516e04ad33ff8b446720e36cabfdLeon Scroggins                    }.execute();
6930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    String searchSource = "&source=android-" + GOOGLE_SEARCH_SOURCE_SUGGEST + "&";
6940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    if (url.contains(searchSource)) {
6950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        String source = null;
6960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        final Bundle appData = intent.getBundleExtra(SearchManager.APP_DATA);
6970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        if (appData != null) {
69810d1cca0c208d1f9db23893a8515685e04cfe224Bjorn Bringert                            source = appData.getString(Search.SOURCE);
6990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }
7000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        if (TextUtils.isEmpty(source)) {
7010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            source = GOOGLE_SEARCH_SOURCE_UNKNOWN;
7020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }
7030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        url = url.replace(searchSource, "&source=android-"+source+"&");
7040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
7050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
7060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
7070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
70858d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        return new UrlData(url, headers, intent);
7090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
71058d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    /* package */ void showVoiceTitleBar(String title) {
71158d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        mTitleBar.setInVoiceMode(true);
71258d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        mTitleBar.setDisplayTitle(title);
713d746a94137a87ffcc1fcefdac9a3764c3bc3f5cdLeon Scroggins
714d746a94137a87ffcc1fcefdac9a3764c3bc3f5cdLeon Scroggins        if (!mXLargeScreenSize) {
715d746a94137a87ffcc1fcefdac9a3764c3bc3f5cdLeon Scroggins            mFakeTitleBar.setInVoiceMode(true);
716d746a94137a87ffcc1fcefdac9a3764c3bc3f5cdLeon Scroggins            mFakeTitleBar.setDisplayTitle(title);
717d746a94137a87ffcc1fcefdac9a3764c3bc3f5cdLeon Scroggins        }
71858d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    }
71958d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    /* package */ void revertVoiceTitleBar() {
72058d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        mTitleBar.setInVoiceMode(false);
721003a5ddf3a7ff1b30bfd82cddc8da49cb9fedf15Leon Scroggins        mTitleBar.setDisplayTitle(mUrl);
722d746a94137a87ffcc1fcefdac9a3764c3bc3f5cdLeon Scroggins
723d746a94137a87ffcc1fcefdac9a3764c3bc3f5cdLeon Scroggins        if (!mXLargeScreenSize) {
724d746a94137a87ffcc1fcefdac9a3764c3bc3f5cdLeon Scroggins            mFakeTitleBar.setInVoiceMode(false);
725d746a94137a87ffcc1fcefdac9a3764c3bc3f5cdLeon Scroggins            mFakeTitleBar.setDisplayTitle(mUrl);
726d746a94137a87ffcc1fcefdac9a3764c3bc3f5cdLeon Scroggins        }
72758d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    }
7280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /* package */ static String fixUrl(String inUrl) {
729652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark        // FIXME: Converting the url to lower case
730652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark        // duplicates functionality in smartUrlFilter().
731652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark        // However, changing all current callers of fixUrl to
732652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark        // call smartUrlFilter in addition may have unwanted
733652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark        // consequences, and is deferred for now.
734652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark        int colon = inUrl.indexOf(':');
735652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark        boolean allLower = true;
736652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark        for (int index = 0; index < colon; index++) {
737652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark            char ch = inUrl.charAt(index);
738652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark            if (!Character.isLetter(ch)) {
739652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark                break;
740652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark            }
741652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark            allLower &= Character.isLowerCase(ch);
742652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark            if (index == colon - 1 && !allLower) {
743652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark                inUrl = inUrl.substring(0, colon).toLowerCase()
744652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark                        + inUrl.substring(colon);
745652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark            }
746652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark        }
7470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (inUrl.startsWith("http://") || inUrl.startsWith("https://"))
7480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return inUrl;
7490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (inUrl.startsWith("http:") ||
7500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                inUrl.startsWith("https:")) {
7510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (inUrl.startsWith("http:/") || inUrl.startsWith("https:/")) {
7520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                inUrl = inUrl.replaceFirst("/", "//");
7530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } else inUrl = inUrl.replaceFirst(":", "://");
7540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
7550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return inUrl;
7560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
7570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
75822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    @Override
75922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    protected void onResume() {
7600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        super.onResume();
76131a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort        if (LOGV_ENABLED) {
7620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Log.v(LOGTAG, "BrowserActivity.onResume: this=" + this);
7630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
7640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
7650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (!mActivityInPause) {
7660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Log.e(LOGTAG, "BrowserActivity is already resumed.");
7670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
7680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
7690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
7707bfa63b55644fbf2da1fe6a24b3be0267529202cMike Reed        mTabControl.resumeCurrentTab();
7710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mActivityInPause = false;
7727bfa63b55644fbf2da1fe6a24b3be0267529202cMike Reed        resumeWebViewTimers();
7730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
7740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mWakeLock.isHeld()) {
7750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mHandler.removeMessages(RELEASE_WAKELOCK);
7760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mWakeLock.release();
7770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
7780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
7790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        registerReceiver(mNetworkStateIntentReceiver,
7800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                         mNetworkStateChangedFilter);
7810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebView.enablePlatformNotifications();
7820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
7830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
7843bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    /**
7853bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     * Since the actual title bar is embedded in the WebView, and removing it
786fe87bd3a3897e4bad65bb3d284659ae2f4e57570Leon Scroggins     * would change its appearance, use a different TitleBar to show overlayed
787fe87bd3a3897e4bad65bb3d284659ae2f4e57570Leon Scroggins     * at the top of the screen, when the menu is open or the page is loading.
7883bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     */
7893bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    private TitleBar mFakeTitleBar;
7903bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins
7913bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    /**
7923bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     * Keeps track of whether the options menu is open.  This is important in
7933bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     * determining whether to show or hide the title bar overlay.
7943bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     */
7953bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    private boolean mOptionsMenuOpen;
7963bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins
7973bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    /**
7983bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     * Only meaningful when mOptionsMenuOpen is true.  This variable keeps track
7993bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     * of whether the configuration has changed.  The first onMenuOpened call
8003bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     * after a configuration change is simply a reopening of the same menu
8013bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     * (i.e. mIconView did not change).
8023bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     */
8033bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    private boolean mConfigChanged;
8043bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins
8053bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    /**
8063bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     * Whether or not the options menu is in its smaller, icon menu form.  When
8073bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     * true, we want the title bar overlay to be up.  When false, we do not.
8083bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     * Only meaningful if mOptionsMenuOpen is true.
8093bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     */
8103bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    private boolean mIconView;
8113bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins
812a81a764063d2f849fba0cbc3039f86e67c2960ddLeon Scroggins    @Override
813a81a764063d2f849fba0cbc3039f86e67c2960ddLeon Scroggins    public boolean onMenuOpened(int featureId, Menu menu) {
8143bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins        if (Window.FEATURE_OPTIONS_PANEL == featureId) {
8153bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins            if (mOptionsMenuOpen) {
8163bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                if (mConfigChanged) {
8173bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                    // We do not need to make any changes to the state of the
8183bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                    // title bar, since the only thing that happened was a
8193bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                    // change in orientation
8203bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                    mConfigChanged = false;
8213bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                } else {
8223bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                    if (mIconView) {
8233bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                        // Switching the menu to expanded view, so hide the
8243bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                        // title bar.
8253bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                        hideFakeTitleBar();
8263bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                        mIconView = false;
8273bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                    } else {
8283bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                        // Switching the menu back to icon view, so show the
8293bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                        // title bar once again.
8303bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                        showFakeTitleBar();
8313bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                        mIconView = true;
8323bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                    }
8333bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                }
8343bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins            } else {
8353bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                // The options menu is closed, so open it, and show the title
8363bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                showFakeTitleBar();
8373bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                mOptionsMenuOpen = true;
8383bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                mConfigChanged = false;
8393bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                mIconView = true;
8403bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins            }
8413bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins        }
842a81a764063d2f849fba0cbc3039f86e67c2960ddLeon Scroggins        return true;
843a81a764063d2f849fba0cbc3039f86e67c2960ddLeon Scroggins    }
844a81a764063d2f849fba0cbc3039f86e67c2960ddLeon Scroggins
8453bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    private void showFakeTitleBar() {
846d746a94137a87ffcc1fcefdac9a3764c3bc3f5cdLeon Scroggins        if (mXLargeScreenSize) return;
847fe87bd3a3897e4bad65bb3d284659ae2f4e57570Leon Scroggins        if (mFakeTitleBar.getParent() == null && mActiveTabsPage == null
848847c25b877f1c912fe54ba7d3890df7ed3798e47Grace Kloba                && !mActivityInPause) {
849847c25b877f1c912fe54ba7d3890df7ed3798e47Grace Kloba            WebView mainView = mTabControl.getCurrentWebView();
850847c25b877f1c912fe54ba7d3890df7ed3798e47Grace Kloba            // if there is no current WebView, don't show the faked title bar;
85165190702c53f2d3ceb8e3c88d707bd6ff874034cGrace Kloba            if (mainView == null) {
852a04645545690d9f637ccae4d043a5a1b8478a832Cary Clark                return;
853a04645545690d9f637ccae4d043a5a1b8478a832Cary Clark            }
85479e36d97b67bf06b1e0c0edf773882e93a3293e4Leon Scroggins            // Do not need to check for null, since the current tab will have
85579e36d97b67bf06b1e0c0edf773882e93a3293e4Leon Scroggins            // at least a main WebView, or we would have returned above.
85601cfcdd0b77d672f5c09d98af683c6732c8250d8Cary Clark            if (dialogIsUp()) {
85779e36d97b67bf06b1e0c0edf773882e93a3293e4Leon Scroggins                // Do not show the fake title bar, which would cover up the
85801cfcdd0b77d672f5c09d98af683c6732c8250d8Cary Clark                // find or select dialog.
85979e36d97b67bf06b1e0c0edf773882e93a3293e4Leon Scroggins                return;
86079e36d97b67bf06b1e0c0edf773882e93a3293e4Leon Scroggins            }
8613bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins
8623bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins            WindowManager manager
8633bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                    = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
8643bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins
8653bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins            // Add the title bar to the window manager so it can receive touches
8663bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins            // while the menu is up
8673bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins            WindowManager.LayoutParams params
8683bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                    = new WindowManager.LayoutParams(
86915b8ec6b226f4d57307716e1f495e10a91f8cbf4Romain Guy                    ViewGroup.LayoutParams.MATCH_PARENT,
8703bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                    ViewGroup.LayoutParams.WRAP_CONTENT,
871847c25b877f1c912fe54ba7d3890df7ed3798e47Grace Kloba                    WindowManager.LayoutParams.TYPE_APPLICATION,
8723bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                    WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
873685498685d8424f48d77d26d8d5790da34645f44Leon Scroggins                    PixelFormat.TRANSLUCENT);
8743bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins            params.gravity = Gravity.TOP;
875847c25b877f1c912fe54ba7d3890df7ed3798e47Grace Kloba            boolean atTop = mainView.getScrollY() == 0;
87683932c74ba031eb2f581f1557c1a90f4b5bbb423Leon Scroggins            params.windowAnimations = atTop ? 0 : R.style.TitleBar;
87713f9aced9c949d452a5cb44ffc55c82f97871c89Grace Kloba            manager.addView(mFakeTitleBar, params);
8783bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins        }
8793bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    }
8803bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins
8813bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    @Override
8823bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    public void onOptionsMenuClosed(Menu menu) {
8833bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins        mOptionsMenuOpen = false;
884a27ff19e24cb1c9fef5624dbc4554548349b5b31Leon Scroggins        if (!mInLoad) {
885a27ff19e24cb1c9fef5624dbc4554548349b5b31Leon Scroggins            hideFakeTitleBar();
886a27ff19e24cb1c9fef5624dbc4554548349b5b31Leon Scroggins        } else if (!mIconView) {
887a27ff19e24cb1c9fef5624dbc4554548349b5b31Leon Scroggins            // The page is currently loading, and we are in expanded mode, so
888a27ff19e24cb1c9fef5624dbc4554548349b5b31Leon Scroggins            // we were not showing the menu.  Show it once again.  It will be
889a27ff19e24cb1c9fef5624dbc4554548349b5b31Leon Scroggins            // removed when the page finishes.
890a27ff19e24cb1c9fef5624dbc4554548349b5b31Leon Scroggins            showFakeTitleBar();
891a27ff19e24cb1c9fef5624dbc4554548349b5b31Leon Scroggins        }
8923bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    }
89322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
8943bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    private void hideFakeTitleBar() {
895d746a94137a87ffcc1fcefdac9a3764c3bc3f5cdLeon Scroggins        if (mXLargeScreenSize || mFakeTitleBar.getParent() == null) return;
89620329570ba9409637298da90b83f25801d7a3d55Leon Scroggins        WindowManager.LayoutParams params = (WindowManager.LayoutParams)
89713f9aced9c949d452a5cb44ffc55c82f97871c89Grace Kloba                mFakeTitleBar.getLayoutParams();
89820329570ba9409637298da90b83f25801d7a3d55Leon Scroggins        WebView mainView = mTabControl.getCurrentWebView();
89920329570ba9409637298da90b83f25801d7a3d55Leon Scroggins        // Although we decided whether or not to animate based on the current
90020329570ba9409637298da90b83f25801d7a3d55Leon Scroggins        // scroll position, the scroll position may have changed since the
90120329570ba9409637298da90b83f25801d7a3d55Leon Scroggins        // fake title bar was displayed.  Make sure it has the appropriate
90220329570ba9409637298da90b83f25801d7a3d55Leon Scroggins        // animation/lack thereof before removing.
90320329570ba9409637298da90b83f25801d7a3d55Leon Scroggins        params.windowAnimations = mainView != null && mainView.getScrollY() == 0
90483932c74ba031eb2f581f1557c1a90f4b5bbb423Leon Scroggins                ? 0 : R.style.TitleBar;
9053bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins        WindowManager manager
9063bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                    = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
90713f9aced9c949d452a5cb44ffc55c82f97871c89Grace Kloba        manager.updateViewLayout(mFakeTitleBar, params);
90813f9aced9c949d452a5cb44ffc55c82f97871c89Grace Kloba        manager.removeView(mFakeTitleBar);
9093bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    }
9103bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins
9110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
912c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins     * Special method for the fake title bar to call when displaying its context
913c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins     * menu, since it is in its own Window, and its parent does not show a
914c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins     * context menu.
915c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins     */
916c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins    /* package */ void showTitleBarContextMenu() {
91765f4a3ce9e5c4a5227bbcbb995e5e15f1f85d3d7Cary Clark        if (null == mTitleBar.getParent()) {
91865f4a3ce9e5c4a5227bbcbb995e5e15f1f85d3d7Cary Clark            return;
91965f4a3ce9e5c4a5227bbcbb995e5e15f1f85d3d7Cary Clark        }
920c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins        openContextMenu(mTitleBar);
921c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins    }
922c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins
923b2b19f501ee05448ca81bddaaca70e9b2f51cb54Leon Scroggins    @Override
924b2b19f501ee05448ca81bddaaca70e9b2f51cb54Leon Scroggins    public void onContextMenuClosed(Menu menu) {
925b2b19f501ee05448ca81bddaaca70e9b2f51cb54Leon Scroggins        super.onContextMenuClosed(menu);
926b2b19f501ee05448ca81bddaaca70e9b2f51cb54Leon Scroggins        if (mInLoad) {
927b2b19f501ee05448ca81bddaaca70e9b2f51cb54Leon Scroggins            showFakeTitleBar();
928b2b19f501ee05448ca81bddaaca70e9b2f51cb54Leon Scroggins        }
929b2b19f501ee05448ca81bddaaca70e9b2f51cb54Leon Scroggins    }
930b2b19f501ee05448ca81bddaaca70e9b2f51cb54Leon Scroggins
931c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins    /**
9320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *  onSaveInstanceState(Bundle map)
9330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *  onSaveInstanceState is called right before onStop(). The map contains
9340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *  the saved state.
9350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
93622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    @Override
93722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    protected void onSaveInstanceState(Bundle outState) {
93831a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort        if (LOGV_ENABLED) {
9390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Log.v(LOGTAG, "BrowserActivity.onSaveInstanceState: this=" + this);
9400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
9410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // the default implementation requires each view to have an id. As the
9420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // browser handles the state itself and it doesn't use id for the views,
9430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // don't call the default implementation. Otherwise it will trigger the
9440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // warning like this, "couldn't save which view has focus because the
9450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // focused view XXX has no id".
9460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
9470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Save all the tabs
9480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mTabControl.saveState(outState);
9490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
9500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
95122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    @Override
95222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    protected void onPause() {
9530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        super.onPause();
9540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
9550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mActivityInPause) {
9560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Log.e(LOGTAG, "BrowserActivity is already paused.");
9570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
9580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
9590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
9607bfa63b55644fbf2da1fe6a24b3be0267529202cMike Reed        mTabControl.pauseCurrentTab();
9610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mActivityInPause = true;
9627bfa63b55644fbf2da1fe6a24b3be0267529202cMike Reed        if (mTabControl.getCurrentIndex() >= 0 && !pauseWebViewTimers()) {
9630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mWakeLock.acquire();
9640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mHandler.sendMessageDelayed(mHandler
9650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    .obtainMessage(RELEASE_WAKELOCK), WAKELOCK_TIMEOUT);
9660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
9670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
968a2ab6a7dc0f7023c1d7ebb1cbad397c5dc3d6453Leon Scroggins        // FIXME: This removes the active tabs page and resets the menu to
969a2ab6a7dc0f7023c1d7ebb1cbad397c5dc3d6453Leon Scroggins        // MAIN_MENU.  A better solution might be to do this work in onNewIntent
970a2ab6a7dc0f7023c1d7ebb1cbad397c5dc3d6453Leon Scroggins        // but then we would need to save it in onSaveInstanceState and restore
971a2ab6a7dc0f7023c1d7ebb1cbad397c5dc3d6453Leon Scroggins        // it in onCreate/onRestoreInstanceState
972a2ab6a7dc0f7023c1d7ebb1cbad397c5dc3d6453Leon Scroggins        if (mActiveTabsPage != null) {
973a2ab6a7dc0f7023c1d7ebb1cbad397c5dc3d6453Leon Scroggins            removeActiveTabPage(true);
974a2ab6a7dc0f7023c1d7ebb1cbad397c5dc3d6453Leon Scroggins        }
975a2ab6a7dc0f7023c1d7ebb1cbad397c5dc3d6453Leon Scroggins
9760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        cancelStopToast();
9770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
9780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // unregister network state listener
9790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        unregisterReceiver(mNetworkStateIntentReceiver);
9800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebView.disablePlatformNotifications();
9810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
9820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
98322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    @Override
98422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    protected void onDestroy() {
98531a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort        if (LOGV_ENABLED) {
9860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Log.v(LOGTAG, "BrowserActivity.onDestroy: this=" + this);
9870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
9880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        super.onDestroy();
9890923d69a8ca45222cabd82a80eaa88da9f132e9aGrace Kloba
9908d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins        if (mUploadMessage != null) {
9918d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins            mUploadMessage.onReceiveValue(null);
9928d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins            mUploadMessage = null;
9938d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins        }
9948d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins
9950923d69a8ca45222cabd82a80eaa88da9f132e9aGrace Kloba        if (mTabControl == null) return;
9960923d69a8ca45222cabd82a80eaa88da9f132e9aGrace Kloba
9971fc98a322e9df6b0e797c26de6b2cb23d69ad5d3Grace Kloba        // Remove the fake title bar if it is there
9981fc98a322e9df6b0e797c26de6b2cb23d69ad5d3Grace Kloba        hideFakeTitleBar();
9991fc98a322e9df6b0e797c26de6b2cb23d69ad5d3Grace Kloba
10000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Remove the current tab and sub window
100122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        Tab t = mTabControl.getCurrentTab();
1002fb5e77fac7b8b311fe72827183f8988f5ee92a5fPatrick Scott        if (t != null) {
1003fb5e77fac7b8b311fe72827183f8988f5ee92a5fPatrick Scott            dismissSubWindow(t);
1004fb5e77fac7b8b311fe72827183f8988f5ee92a5fPatrick Scott            removeTabFromContentView(t);
1005fb5e77fac7b8b311fe72827183f8988f5ee92a5fPatrick Scott        }
10060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Destroy all the tabs
10070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mTabControl.destroy();
10080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebIconDatabase.getInstance().close();
10090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
1010b4da0ad0351996f639b50f9f29b123a9b5c24fd0Grace Kloba        unregisterReceiver(mPackageInstallationReceiver);
1011a7611811e0d744a7220b7bf80c8f795af5ea53edBjorn Bringert
1012a7611811e0d744a7220b7bf80c8f795af5ea53edBjorn Bringert        // Stop watching the default geolocation permissions
1013a7611811e0d744a7220b7bf80c8f795af5ea53edBjorn Bringert        mSystemAllowGeolocationOrigins.stop();
1014a7611811e0d744a7220b7bf80c8f795af5ea53edBjorn Bringert        mSystemAllowGeolocationOrigins = null;
10150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
10160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
10170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    @Override
10180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public void onConfigurationChanged(Configuration newConfig) {
10193bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins        mConfigChanged = true;
10200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        super.onConfigurationChanged(newConfig);
10210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
10220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mPageInfoDialog != null) {
10230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mPageInfoDialog.dismiss();
10240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            showPageInfo(
10250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mPageInfoView,
1026c7b92f811dfa3572578ddc6714c98a03936d9ce5Leon Scroggins                mPageInfoFromShowSSLCertificateOnError);
10270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
10280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mSSLCertificateDialog != null) {
10290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mSSLCertificateDialog.dismiss();
10300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            showSSLCertificate(
10310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mSSLCertificateView);
10320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
10330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mSSLCertificateOnErrorDialog != null) {
10340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mSSLCertificateOnErrorDialog.dismiss();
10350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            showSSLCertificateOnError(
10360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mSSLCertificateOnErrorView,
10370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mSSLCertificateOnErrorHandler,
10380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mSSLCertificateOnErrorError);
10390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
10400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mHttpAuthenticationDialog != null) {
10410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            String title = ((TextView) mHttpAuthenticationDialog
10420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    .findViewById(com.android.internal.R.id.alertTitle)).getText()
10430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    .toString();
10440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            String name = ((TextView) mHttpAuthenticationDialog
10450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    .findViewById(R.id.username_edit)).getText().toString();
10460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            String password = ((TextView) mHttpAuthenticationDialog
10470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    .findViewById(R.id.password_edit)).getText().toString();
10480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            int focusId = mHttpAuthenticationDialog.getCurrentFocus()
10490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    .getId();
10500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mHttpAuthenticationDialog.dismiss();
10510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            showHttpAuthentication(mHttpAuthHandler, null, null, title,
10520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    name, password, focusId);
10530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
10540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
10550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
105622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    @Override
105722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    public void onLowMemory() {
10580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        super.onLowMemory();
10590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mTabControl.freeMemory();
10600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
10610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
1062ff4d92ca529f8b77db67d0aea5d9988d5e390211Cary Clark    private void resumeWebViewTimers() {
106322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        Tab tab = mTabControl.getCurrentTab();
1064ff4d92ca529f8b77db67d0aea5d9988d5e390211Cary Clark        if (tab == null) return; // monkey can trigger this
106522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        boolean inLoad = tab.inLoad();
106622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if ((!mActivityInPause && !inLoad) || (mActivityInPause && inLoad)) {
10670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            CookieSyncManager.getInstance().startSync();
106822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            WebView w = tab.getWebView();
10690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (w != null) {
10700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                w.resumeTimers();
10710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
10720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
10730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
10740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
10757bfa63b55644fbf2da1fe6a24b3be0267529202cMike Reed    private boolean pauseWebViewTimers() {
107622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        Tab tab = mTabControl.getCurrentTab();
107722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        boolean inLoad = tab.inLoad();
107822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mActivityInPause && !inLoad) {
10790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            CookieSyncManager.getInstance().stopSync();
10800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            WebView w = mTabControl.getCurrentWebView();
10810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (w != null) {
10820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                w.pauseTimers();
10830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
10840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return true;
10850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
10860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return false;
10870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
10880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
10890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
10900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Open the icon database and retain all the icons for visited sites.
10910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void retainIconsOnStartup() {
10920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final WebIconDatabase db = WebIconDatabase.getInstance();
10930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        db.open(getDir("icons", 0).getPath());
10942c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins        Cursor c = null;
10950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        try {
10962c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins            c = Browser.getAllBookmarks(mResolver);
10972c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins            if (c.moveToFirst()) {
10982c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins                int urlIndex = c.getColumnIndex(Browser.BookmarkColumns.URL);
10992c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins                do {
11002c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins                    String url = c.getString(urlIndex);
11012c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins                    db.retainIconForPageUrl(url);
11022c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins                } while (c.moveToNext());
11030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
11040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } catch (IllegalStateException e) {
11050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Log.e(LOGTAG, "retainIconsOnStartup", e);
11062c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins        } finally {
11072c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins            if (c!= null) c.close();
11080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
11090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
11100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
11110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Helper method for getting the top window.
11120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    WebView getTopWindow() {
11130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return mTabControl.getCurrentTopWebView();
11140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
11150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
111622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    TabControl getTabControl() {
111722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return mTabControl;
111822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
111922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
11200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    @Override
11210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public boolean onCreateOptionsMenu(Menu menu) {
11220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        super.onCreateOptionsMenu(menu);
11230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
11240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        MenuInflater inflater = getMenuInflater();
11250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        inflater.inflate(R.menu.browser, menu);
11260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mMenu = menu;
11270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        updateInLoadMenuItems();
11280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return true;
11290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
11300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
11310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
11320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * As the menu can be open when loading state changes
11330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * we must manually update the state of the stop/reload menu
11340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * item
11350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
11360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void updateInLoadMenuItems() {
11370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mMenu == null) {
11380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
11390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
1140e0a3666b5c0dca7352895fa8b9b4fbb2237df721Michael Kolb        MenuItem dest = mMenu.findItem(R.id.stop_reload_menu_id);
11410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        MenuItem src = mInLoad ?
11420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mMenu.findItem(R.id.stop_menu_id):
1143e0a3666b5c0dca7352895fa8b9b4fbb2237df721Michael Kolb                mMenu.findItem(R.id.reload_menu_id);
1144e0a3666b5c0dca7352895fa8b9b4fbb2237df721Michael Kolb        if (src != null) {
1145e0a3666b5c0dca7352895fa8b9b4fbb2237df721Michael Kolb            dest.setIcon(src.getIcon());
1146e0a3666b5c0dca7352895fa8b9b4fbb2237df721Michael Kolb            dest.setTitle(src.getTitle());
1147e0a3666b5c0dca7352895fa8b9b4fbb2237df721Michael Kolb        }
11480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
11490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
11500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    @Override
11510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public boolean onContextItemSelected(MenuItem item) {
11520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // chording is not an issue with context menus, but we use the same
11530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // options selector, so set mCanChord to true so we can access them.
11540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mCanChord = true;
11550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        int id = item.getItemId();
115696afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins        boolean result = true;
11570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        switch (id) {
1158c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins            // For the context menu from the title bar
1159c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins            case R.id.title_bar_copy_page_url:
116096afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                Tab currentTab = mTabControl.getCurrentTab();
116196afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                if (null == currentTab) {
116296afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                    result = false;
116396afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                    break;
1164c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins                }
116596afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                WebView mainView = currentTab.getWebView();
116696afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                if (null == mainView) {
116796afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                    result = false;
116896afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                    break;
1169c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins                }
117096afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                copy(mainView.getUrl());
1171c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins                break;
11720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // -- Browser context menu
11730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.open_context_menu_id:
11740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.bookmark_context_menu_id:
11750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.save_link_context_menu_id:
11760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.share_link_context_menu_id:
11770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.copy_link_context_menu_id:
1178c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins                final WebView webView = getTopWindow();
1179c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins                if (null == webView) {
118096afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                    result = false;
118196afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                    break;
1182c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins                }
1183c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins                final HashMap hrefMap = new HashMap();
1184c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins                hrefMap.put("webview", webView);
1185c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins                final Message msg = mHandler.obtainMessage(
1186c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins                        FOCUS_NODE_HREF, id, 0, hrefMap);
11870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                webView.requestFocusNodeHref(msg);
11880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
11890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
11900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            default:
11910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // For other context menus
119296afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                result = onOptionsItemSelected(item);
11930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
11940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mCanChord = false;
119596afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins        return result;
11960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
11970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
11980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private Bundle createGoogleSearchSourceBundle(String source) {
11990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        Bundle bundle = new Bundle();
120010d1cca0c208d1f9db23893a8515685e04cfe224Bjorn Bringert        bundle.putString(Search.SOURCE, source);
12010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return bundle;
12020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
12030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
12048ad299270a97dfa3f9bcb956096bc152498fb727Leon Scroggins    /* package */ void editUrl() {
120568579393973f745fc65a2781061af9bb8f2d7020Leon Scroggins        if (mOptionsMenuOpen) closeOptionsMenu();
12065bbe98025a2c606a35c91b826760020890daadb1Leon Scroggins        String url = (getTopWindow() == null) ? null : getTopWindow().getUrl();
120783f473462fcd7869031a423c02b957c6e938a2f6Grace Kloba        startSearch(mSettings.getHomePage().equals(url) ? null : url, true,
12088ad299270a97dfa3f9bcb956096bc152498fb727Leon Scroggins                null, false);
12090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
12100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
12118ad299270a97dfa3f9bcb956096bc152498fb727Leon Scroggins    /**
12128ad299270a97dfa3f9bcb956096bc152498fb727Leon Scroggins     * Overriding this to insert a local information bundle
12138ad299270a97dfa3f9bcb956096bc152498fb727Leon Scroggins     */
12140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    @Override
12150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public void startSearch(String initialQuery, boolean selectInitialQuery,
12160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Bundle appSearchData, boolean globalSearch) {
12170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (appSearchData == null) {
12180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            appSearchData = createGoogleSearchSourceBundle(GOOGLE_SEARCH_SOURCE_TYPE);
12190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
12200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        super.startSearch(initialQuery, selectInitialQuery, appSearchData, globalSearch);
12210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
12220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
12231f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins    /**
12241f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins     * Switch tabs.  Called by the TitleBarSet when sliding the title bar
12251f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins     * results in changing tabs.
1226160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins     * @param index Index of the tab to change to, as defined by
1227160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins     *              mTabControl.getTabIndex(Tab t).
1228160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins     * @return boolean True if we successfully switched to a different tab.  If
1229160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins     *                 the indexth tab is null, or if that tab is the same as
1230160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins     *                 the current one, return false.
12311f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins     */
1232160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins    /* package */ boolean switchToTab(int index) {
123322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        Tab tab = mTabControl.getTab(index);
123422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        Tab currentTab = mTabControl.getCurrentTab();
12351f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins        if (tab == null || tab == currentTab) {
1236160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins            return false;
12371f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins        }
12381f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins        if (currentTab != null) {
12391f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins            // currentTab may be null if it was just removed.  In that case,
12401f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins            // we do not need to remove it
12411f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins            removeTabFromContentView(currentTab);
12421f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins        }
12431f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins        mTabControl.setCurrentTab(tab);
12441f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins        attachTabToContentView(tab);
1245eb6eef4c45df2d65c3e70660493a147a2be405e3Grace Kloba        resetTitleIconAndProgress();
1246eb6eef4c45df2d65c3e70660493a147a2be405e3Grace Kloba        updateLockIconToLatest();
1247160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins        return true;
12481f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins    }
12491f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins
125022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /* package */ Tab openTabToHomePage() {
12510a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins        return openTabAndShow(mSettings.getHomePage(), false, null);
12520a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins    }
12530a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins
12541f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins    /* package */ void closeCurrentWindow() {
125522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        final Tab current = mTabControl.getCurrentTab();
1256160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins        if (mTabControl.getTabCount() == 1) {
1257304442375719effd41dbd53ae62de7a8d0cec7d9Leon Scroggins            // This is the last tab.  Open a new one, with the home
1258304442375719effd41dbd53ae62de7a8d0cec7d9Leon Scroggins            // page and close the current one.
125922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            openTabToHomePage();
1260160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins            closeTab(current);
1261160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins            return;
1262160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins        }
126322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        final Tab parent = current.getParentTab();
12641f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins        int indexToShow = -1;
12651f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins        if (parent != null) {
12661f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins            indexToShow = mTabControl.getTabIndex(parent);
12671f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins        } else {
1268160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins            final int currentIndex = mTabControl.getCurrentIndex();
1269160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins            // Try to move to the tab to the right
1270160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins            indexToShow = currentIndex + 1;
1271160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins            if (indexToShow > mTabControl.getTabCount() - 1) {
1272160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins                // Try to move to the tab to the left
1273160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins                indexToShow = currentIndex - 1;
12741f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins            }
12751f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins        }
1276160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins        if (switchToTab(indexToShow)) {
1277160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins            // Close window
1278160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins            closeTab(current);
1279160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins        }
12801f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins    }
12811f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins
12820a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins    private ActiveTabsPage mActiveTabsPage;
12830a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins
12840a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins    /**
12850a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins     * Remove the active tabs page.
12860a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins     * @param needToAttach If true, the active tabs page did not attach a tab
12870a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins     *                     to the content view, so we need to do that here.
12880a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins     */
12890a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins    /* package */ void removeActiveTabPage(boolean needToAttach) {
12900a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins        mContentView.removeView(mActiveTabsPage);
1291d746a94137a87ffcc1fcefdac9a3764c3bc3f5cdLeon Scroggins        mTitleBar.setVisibility(View.VISIBLE);
12920a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins        mActiveTabsPage = null;
12930a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins        mMenuState = R.id.MAIN_MENU;
12940a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins        if (needToAttach) {
12950a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins            attachTabToContentView(mTabControl.getCurrentTab());
12960a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins        }
12970a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins        getTopWindow().requestFocus();
12980a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins    }
12990a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins
130001cfcdd0b77d672f5c09d98af683c6732c8250d8Cary Clark    private WebView showDialog(WebDialog dialog) {
130101cfcdd0b77d672f5c09d98af683c6732c8250d8Cary Clark        // Need to do something special for Tablet
130201cfcdd0b77d672f5c09d98af683c6732c8250d8Cary Clark        Tab tab = mTabControl.getCurrentTab();
130301cfcdd0b77d672f5c09d98af683c6732c8250d8Cary Clark        if (tab.getSubWebView() == null) {
130401cfcdd0b77d672f5c09d98af683c6732c8250d8Cary Clark            // If the find or select is being performed on the main webview,
130501cfcdd0b77d672f5c09d98af683c6732c8250d8Cary Clark            // remove the embedded title bar.
130601cfcdd0b77d672f5c09d98af683c6732c8250d8Cary Clark            WebView mainView = tab.getWebView();
130701cfcdd0b77d672f5c09d98af683c6732c8250d8Cary Clark            if (mainView != null) {
130801cfcdd0b77d672f5c09d98af683c6732c8250d8Cary Clark                mainView.setEmbeddedTitleBar(null);
130901cfcdd0b77d672f5c09d98af683c6732c8250d8Cary Clark            }
131001cfcdd0b77d672f5c09d98af683c6732c8250d8Cary Clark        }
131101cfcdd0b77d672f5c09d98af683c6732c8250d8Cary Clark        hideFakeTitleBar();
131201cfcdd0b77d672f5c09d98af683c6732c8250d8Cary Clark        mMenuState = EMPTY_MENU;
131301cfcdd0b77d672f5c09d98af683c6732c8250d8Cary Clark        return tab.showDialog(dialog);
131401cfcdd0b77d672f5c09d98af683c6732c8250d8Cary Clark    }
131501cfcdd0b77d672f5c09d98af683c6732c8250d8Cary Clark
13160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    @Override
13170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public boolean onOptionsItemSelected(MenuItem item) {
13180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (!mCanChord) {
13190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // The user has already fired a shortcut with this hold down of the
13200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // menu key.
13210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return false;
13220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
13231f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins        if (null == getTopWindow()) {
13240d7ae0ed82e21d472cde8cf92b5657d8ee8ca0d8Leon Scroggins            return false;
13250d7ae0ed82e21d472cde8cf92b5657d8ee8ca0d8Leon Scroggins        }
13266ee9c498b8cf648f1507281ed5a1834ba3390907Grace Kloba        if (mMenuIsDown) {
13276ee9c498b8cf648f1507281ed5a1834ba3390907Grace Kloba            // The shortcut action consumes the MENU. Even if it is still down,
13286ee9c498b8cf648f1507281ed5a1834ba3390907Grace Kloba            // it won't trigger the next shortcut action. In the case of the
13296ee9c498b8cf648f1507281ed5a1834ba3390907Grace Kloba            // shortcut action triggering a new activity, like Bookmarks, we
13306ee9c498b8cf648f1507281ed5a1834ba3390907Grace Kloba            // won't get onKeyUp for MENU. So it is important to reset it here.
13316ee9c498b8cf648f1507281ed5a1834ba3390907Grace Kloba            mMenuIsDown = false;
13326ee9c498b8cf648f1507281ed5a1834ba3390907Grace Kloba        }
13330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        switch (item.getItemId()) {
13340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // -- Main menu
1335a81a764063d2f849fba0cbc3039f86e67c2960ddLeon Scroggins            case R.id.new_tab_menu_id:
13360a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins                openTabToHomePage();
1337a81a764063d2f849fba0cbc3039f86e67c2960ddLeon Scroggins                break;
1338a81a764063d2f849fba0cbc3039f86e67c2960ddLeon Scroggins
133964b80f3efd95d7b5192731e995ccde79c4c6c11fLeon Scroggins            case R.id.goto_menu_id:
13408ad299270a97dfa3f9bcb956096bc152498fb727Leon Scroggins                editUrl();
1341b3a5bedeede968b53363a6c517f92bc2484bb42dLeon Scroggins                break;
1342b3a5bedeede968b53363a6c517f92bc2484bb42dLeon Scroggins
1343b3a5bedeede968b53363a6c517f92bc2484bb42dLeon Scroggins            case R.id.bookmarks_menu_id:
1344304442375719effd41dbd53ae62de7a8d0cec7d9Leon Scroggins                bookmarksOrHistoryPicker(false);
13450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
13460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
13470a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins            case R.id.active_tabs_menu_id:
13480a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins                mActiveTabsPage = new ActiveTabsPage(this, mTabControl);
13490a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins                removeTabFromContentView(mTabControl.getCurrentTab());
1350d746a94137a87ffcc1fcefdac9a3764c3bc3f5cdLeon Scroggins                mTitleBar.setVisibility(View.GONE);
135143de61666cfc98a3acc41c7161a1a8b0bdb2b72bLeon Scroggins                hideFakeTitleBar();
13520a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins                mContentView.addView(mActiveTabsPage, COVER_SCREEN_PARAMS);
13530a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins                mActiveTabsPage.requestFocus();
13540a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins                mMenuState = EMPTY_MENU;
13550a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins                break;
13560a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins
13571f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins            case R.id.add_bookmark_menu_id:
1358571b3762a5eb9e492283e0a1e437edd209fdc0deLeon Scroggins                bookmarkCurrentPage();
13590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
13600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
13610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.stop_reload_menu_id:
13620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (mInLoad) {
13630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    stopLoading();
13640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                } else {
13650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    getTopWindow().reload();
13660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
13670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
13680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
13690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.back_menu_id:
13700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                getTopWindow().goBack();
13710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
13720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
13730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.forward_menu_id:
13740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                getTopWindow().goForward();
13750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
13760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
13770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.close_menu_id:
13780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // Close the subwindow if it exists.
13790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (mTabControl.getCurrentSubWindow() != null) {
13800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    dismissSubWindow(mTabControl.getCurrentTab());
13810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    break;
13820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
13831f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                closeCurrentWindow();
13840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
13850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
13860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.homepage_menu_id:
138722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                Tab current = mTabControl.getCurrentTab();
13880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (current != null) {
13890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    dismissSubWindow(current);
139092472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins                    loadUrl(current.getWebView(), mSettings.getHomePage());
13910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
13920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
13930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
13940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.preferences_menu_id:
13950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                Intent intent = new Intent(this,
13960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        BrowserPreferencesPage.class);
1397d530494de9c182af4aff97ddd46343b32594da51Leon Scroggins                intent.putExtra(BrowserPreferencesPage.CURRENT_PAGE,
1398d530494de9c182af4aff97ddd46343b32594da51Leon Scroggins                        getTopWindow().getUrl());
13990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                startActivityForResult(intent, PREFERENCES_PAGE);
14000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
14010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
14020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.find_menu_id:
140301cfcdd0b77d672f5c09d98af683c6732c8250d8Cary Clark                showFindDialog();
14040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
14050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
14060ced08c2332b6e3af5bc31a12568840e9160bb6aElliott Slaughter            case R.id.save_webarchive_menu_id:
14070ced08c2332b6e3af5bc31a12568840e9160bb6aElliott Slaughter                if (LOGD_ENABLED) {
14080ced08c2332b6e3af5bc31a12568840e9160bb6aElliott Slaughter                    Log.d(LOGTAG, "Save as Web Archive");
14090ced08c2332b6e3af5bc31a12568840e9160bb6aElliott Slaughter                }
14100ced08c2332b6e3af5bc31a12568840e9160bb6aElliott Slaughter                String directory = getExternalFilesDir(null).getAbsolutePath() + File.separator;
14110ced08c2332b6e3af5bc31a12568840e9160bb6aElliott Slaughter                getTopWindow().saveWebArchive(directory, true, new ValueCallback<String>() {
14120ced08c2332b6e3af5bc31a12568840e9160bb6aElliott Slaughter                    @Override
14130ced08c2332b6e3af5bc31a12568840e9160bb6aElliott Slaughter                    public void onReceiveValue(String value) {
14140ced08c2332b6e3af5bc31a12568840e9160bb6aElliott Slaughter                        if (value != null) {
14150ced08c2332b6e3af5bc31a12568840e9160bb6aElliott Slaughter                            Toast.makeText(BrowserActivity.this, R.string.webarchive_saved, Toast.LENGTH_SHORT).show();
14160ced08c2332b6e3af5bc31a12568840e9160bb6aElliott Slaughter                        } else {
14170ced08c2332b6e3af5bc31a12568840e9160bb6aElliott Slaughter                            Toast.makeText(BrowserActivity.this, R.string.webarchive_failed, Toast.LENGTH_SHORT).show();
14180ced08c2332b6e3af5bc31a12568840e9160bb6aElliott Slaughter                        }
14190ced08c2332b6e3af5bc31a12568840e9160bb6aElliott Slaughter                    }
14200ced08c2332b6e3af5bc31a12568840e9160bb6aElliott Slaughter                });
14210ced08c2332b6e3af5bc31a12568840e9160bb6aElliott Slaughter                break;
14220ced08c2332b6e3af5bc31a12568840e9160bb6aElliott Slaughter
14230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.page_info_menu_id:
14240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                showPageInfo(mTabControl.getCurrentTab(), false);
14250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
14260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
14270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.classic_history_menu_id:
1428304442375719effd41dbd53ae62de7a8d0cec7d9Leon Scroggins                bookmarksOrHistoryPicker(true);
14290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
14300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
143196afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins            case R.id.title_bar_share_page_url:
14320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.share_page_menu_id:
143396afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                Tab currentTab = mTabControl.getCurrentTab();
143496afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                if (null == currentTab) {
143596afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                    mCanChord = false;
143696afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                    return false;
143796afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                }
143896afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                currentTab.populatePickerData();
143996afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                sharePage(this, currentTab.getTitle(),
144096afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                        currentTab.getUrl(), currentTab.getFavicon(),
144187cc65d95c80c5e3a1c343ad5177a7dc2de874f6Ben Murdoch                        createScreenshot(currentTab.getWebView(), getDesiredThumbnailWidth(this),
144287cc65d95c80c5e3a1c343ad5177a7dc2de874f6Ben Murdoch                                getDesiredThumbnailHeight(this)));
14430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
14440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
14450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.dump_nav_menu_id:
14460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                getTopWindow().debugDump();
14470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
14480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
14497a8b88b0e0f20544df5ee34b798398603261b733Andrei Popescu            case R.id.dump_counters_menu_id:
14507a8b88b0e0f20544df5ee34b798398603261b733Andrei Popescu                getTopWindow().dumpV8Counters();
14517a8b88b0e0f20544df5ee34b798398603261b733Andrei Popescu                break;
14527a8b88b0e0f20544df5ee34b798398603261b733Andrei Popescu
14530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.zoom_in_menu_id:
14540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                getTopWindow().zoomIn();
14550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
14560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
14570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.zoom_out_menu_id:
14580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                getTopWindow().zoomOut();
14590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
14600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
14610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.view_downloads_menu_id:
14620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                viewDownloads(null);
14630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
14640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
14650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.window_one_menu_id:
14660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.window_two_menu_id:
14670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.window_three_menu_id:
14680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.window_four_menu_id:
14690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.window_five_menu_id:
14700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.window_six_menu_id:
14710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.window_seven_menu_id:
14720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.window_eight_menu_id:
14730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                {
14740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    int menuid = item.getItemId();
14750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    for (int id = 0; id < WINDOW_SHORTCUT_ID_ARRAY.length; id++) {
14760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        if (WINDOW_SHORTCUT_ID_ARRAY[id] == menuid) {
147722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            Tab desiredTab = mTabControl.getTab(id);
14780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            if (desiredTab != null &&
14790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    desiredTab != mTabControl.getCurrentTab()) {
14801f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                                switchToTab(id);
14810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            }
14820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            break;
14830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }
14840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
14850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
14860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
14870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
14880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            default:
14890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (!super.onOptionsItemSelected(item)) {
14900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    return false;
14910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
14920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // Otherwise fall through.
14930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
14940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mCanChord = false;
14950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return true;
14960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
14970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
1498571b3762a5eb9e492283e0a1e437edd209fdc0deLeon Scroggins    /* package */ void bookmarkCurrentPage() {
1499571b3762a5eb9e492283e0a1e437edd209fdc0deLeon Scroggins        Intent i = new Intent(BrowserActivity.this,
1500571b3762a5eb9e492283e0a1e437edd209fdc0deLeon Scroggins                AddBookmarkPage.class);
1501571b3762a5eb9e492283e0a1e437edd209fdc0deLeon Scroggins        WebView w = getTopWindow();
1502571b3762a5eb9e492283e0a1e437edd209fdc0deLeon Scroggins        i.putExtra("url", w.getUrl());
1503571b3762a5eb9e492283e0a1e437edd209fdc0deLeon Scroggins        i.putExtra("title", w.getTitle());
1504571b3762a5eb9e492283e0a1e437edd209fdc0deLeon Scroggins        i.putExtra("touch_icon_url", w.getTouchIconUrl());
150587cc65d95c80c5e3a1c343ad5177a7dc2de874f6Ben Murdoch        i.putExtra("thumbnail", createScreenshot(w, getDesiredThumbnailWidth(this),
150687cc65d95c80c5e3a1c343ad5177a7dc2de874f6Ben Murdoch                getDesiredThumbnailHeight(this)));
1507eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch        i.putExtra("url_editable", false);
1508571b3762a5eb9e492283e0a1e437edd209fdc0deLeon Scroggins        startActivity(i);
1509571b3762a5eb9e492283e0a1e437edd209fdc0deLeon Scroggins    }
1510571b3762a5eb9e492283e0a1e437edd209fdc0deLeon Scroggins
151101cfcdd0b77d672f5c09d98af683c6732c8250d8Cary Clark    private boolean dialogIsUp() {
151201cfcdd0b77d672f5c09d98af683c6732c8250d8Cary Clark        return null != mFindDialog && mFindDialog.isVisible() ||
151301cfcdd0b77d672f5c09d98af683c6732c8250d8Cary Clark            null != mSelectDialog && mSelectDialog.isVisible();
151401cfcdd0b77d672f5c09d98af683c6732c8250d8Cary Clark    }
151501cfcdd0b77d672f5c09d98af683c6732c8250d8Cary Clark
151601cfcdd0b77d672f5c09d98af683c6732c8250d8Cary Clark    private boolean closeDialog(WebDialog dialog) {
151701cfcdd0b77d672f5c09d98af683c6732c8250d8Cary Clark        if (null == dialog || !dialog.isVisible()) return false;
151801cfcdd0b77d672f5c09d98af683c6732c8250d8Cary Clark        Tab currentTab = mTabControl.getCurrentTab();
151901cfcdd0b77d672f5c09d98af683c6732c8250d8Cary Clark        currentTab.closeDialog(dialog);
152001cfcdd0b77d672f5c09d98af683c6732c8250d8Cary Clark        dialog.dismiss();
152101cfcdd0b77d672f5c09d98af683c6732c8250d8Cary Clark        return true;
152201cfcdd0b77d672f5c09d98af683c6732c8250d8Cary Clark    }
152301cfcdd0b77d672f5c09d98af683c6732c8250d8Cary Clark
1524211ba54a3052f7e68bf8af035ea1ef4e9445130cLeon Scroggins III    /*
152501cfcdd0b77d672f5c09d98af683c6732c8250d8Cary Clark     * Remove the find dialog or select dialog.
1526211ba54a3052f7e68bf8af035ea1ef4e9445130cLeon Scroggins III     */
152701cfcdd0b77d672f5c09d98af683c6732c8250d8Cary Clark    public void closeDialogs() {
152801cfcdd0b77d672f5c09d98af683c6732c8250d8Cary Clark        if (!(closeDialog(mFindDialog) || closeDialog(mSelectDialog))) return;
1529d746a94137a87ffcc1fcefdac9a3764c3bc3f5cdLeon Scroggins        if (!mXLargeScreenSize) {
1530d746a94137a87ffcc1fcefdac9a3764c3bc3f5cdLeon Scroggins            // If the Find was being performed in the main WebView, replace the
1531d746a94137a87ffcc1fcefdac9a3764c3bc3f5cdLeon Scroggins            // embedded title bar.
153201cfcdd0b77d672f5c09d98af683c6732c8250d8Cary Clark            Tab currentTab = mTabControl.getCurrentTab();
1533d746a94137a87ffcc1fcefdac9a3764c3bc3f5cdLeon Scroggins            if (currentTab.getSubWebView() == null) {
1534d746a94137a87ffcc1fcefdac9a3764c3bc3f5cdLeon Scroggins                WebView mainView = currentTab.getWebView();
1535d746a94137a87ffcc1fcefdac9a3764c3bc3f5cdLeon Scroggins                if (mainView != null) {
1536d746a94137a87ffcc1fcefdac9a3764c3bc3f5cdLeon Scroggins                    mainView.setEmbeddedTitleBar(mTitleBar);
1537d746a94137a87ffcc1fcefdac9a3764c3bc3f5cdLeon Scroggins                }
153879e36d97b67bf06b1e0c0edf773882e93a3293e4Leon Scroggins            }
153979e36d97b67bf06b1e0c0edf773882e93a3293e4Leon Scroggins        }
15400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mMenuState = R.id.MAIN_MENU;
154179e36d97b67bf06b1e0c0edf773882e93a3293e4Leon Scroggins        if (mInLoad) {
154279e36d97b67bf06b1e0c0edf773882e93a3293e4Leon Scroggins            // The title bar was hidden, because otherwise it would cover up the
154301cfcdd0b77d672f5c09d98af683c6732c8250d8Cary Clark            // find or select dialog.  Now that the dialog has been removed,
154401cfcdd0b77d672f5c09d98af683c6732c8250d8Cary Clark            // show the fake title bar once again.
154579e36d97b67bf06b1e0c0edf773882e93a3293e4Leon Scroggins            showFakeTitleBar();
154679e36d97b67bf06b1e0c0edf773882e93a3293e4Leon Scroggins        }
15470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
15480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
154901cfcdd0b77d672f5c09d98af683c6732c8250d8Cary Clark    public void showFindDialog() {
155001cfcdd0b77d672f5c09d98af683c6732c8250d8Cary Clark        if (null == mFindDialog) {
155101cfcdd0b77d672f5c09d98af683c6732c8250d8Cary Clark            mFindDialog = new FindDialog(this);
155201cfcdd0b77d672f5c09d98af683c6732c8250d8Cary Clark        }
155301cfcdd0b77d672f5c09d98af683c6732c8250d8Cary Clark        showDialog(mFindDialog).setFindIsUp(true);
155401cfcdd0b77d672f5c09d98af683c6732c8250d8Cary Clark    }
155501cfcdd0b77d672f5c09d98af683c6732c8250d8Cary Clark
155601cfcdd0b77d672f5c09d98af683c6732c8250d8Cary Clark    public void setFindDialogText(String text) {
155701cfcdd0b77d672f5c09d98af683c6732c8250d8Cary Clark        mFindDialog.setText(text);
155801cfcdd0b77d672f5c09d98af683c6732c8250d8Cary Clark    }
155901cfcdd0b77d672f5c09d98af683c6732c8250d8Cary Clark
156001cfcdd0b77d672f5c09d98af683c6732c8250d8Cary Clark    public void showSelectDialog() {
156101cfcdd0b77d672f5c09d98af683c6732c8250d8Cary Clark        if (null == mSelectDialog) {
156201cfcdd0b77d672f5c09d98af683c6732c8250d8Cary Clark            mSelectDialog = new SelectDialog(this);
156301cfcdd0b77d672f5c09d98af683c6732c8250d8Cary Clark        }
156401cfcdd0b77d672f5c09d98af683c6732c8250d8Cary Clark        showDialog(mSelectDialog).setUpSelect();
156501cfcdd0b77d672f5c09d98af683c6732c8250d8Cary Clark        mSelectDialog.hideSoftInput();
156601cfcdd0b77d672f5c09d98af683c6732c8250d8Cary Clark    }
156701cfcdd0b77d672f5c09d98af683c6732c8250d8Cary Clark
156822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    @Override
156922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    public boolean onPrepareOptionsMenu(Menu menu) {
15700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // This happens when the user begins to hold down the menu key, so
15710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // allow them to chord to get a shortcut.
15720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mCanChord = true;
15730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Note: setVisible will decide whether an item is visible; while
15740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // setEnabled() will decide whether an item is enabled, which also means
15750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // whether the matching shortcut key will function.
15760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        super.onPrepareOptionsMenu(menu);
15770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        switch (mMenuState) {
15780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case EMPTY_MENU:
15790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (mCurrentMenuState != mMenuState) {
15800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    menu.setGroupVisible(R.id.MAIN_MENU, false);
15810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    menu.setGroupEnabled(R.id.MAIN_MENU, false);
15820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    menu.setGroupEnabled(R.id.MAIN_SHORTCUT_MENU, false);
15830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
15840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
15850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            default:
15860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (mCurrentMenuState != mMenuState) {
15870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    menu.setGroupVisible(R.id.MAIN_MENU, true);
15880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    menu.setGroupEnabled(R.id.MAIN_MENU, true);
15890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    menu.setGroupEnabled(R.id.MAIN_SHORTCUT_MENU, true);
15900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
15910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                final WebView w = getTopWindow();
15920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                boolean canGoBack = false;
15930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                boolean canGoForward = false;
15940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                boolean isHome = false;
15950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (w != null) {
15960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    canGoBack = w.canGoBack();
15970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    canGoForward = w.canGoForward();
15980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    isHome = mSettings.getHomePage().equals(w.getUrl());
15990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
16000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                final MenuItem back = menu.findItem(R.id.back_menu_id);
16010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                back.setEnabled(canGoBack);
16020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
16030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                final MenuItem home = menu.findItem(R.id.homepage_menu_id);
16040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                home.setEnabled(!isHome);
16050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
1606e0a3666b5c0dca7352895fa8b9b4fbb2237df721Michael Kolb                final MenuItem forward = menu.findItem(R.id.forward_menu_id);
1607e0a3666b5c0dca7352895fa8b9b4fbb2237df721Michael Kolb                forward.setEnabled(canGoForward);
16080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
1609e0a3666b5c0dca7352895fa8b9b4fbb2237df721Michael Kolb                final MenuItem newtab = menu.findItem(R.id.new_tab_menu_id);
1610e0a3666b5c0dca7352895fa8b9b4fbb2237df721Michael Kolb                newtab.setEnabled(mTabControl.canCreateNewTab());
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();
17319e997c7c92175c8e24cef90e265cc35fd9b8710eLeon Scroggins III                                    final Tab newTab = openTab(extra);
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
1789d746a94137a87ffcc1fcefdac9a3764c3bc3f5cdLeon Scroggins        if (!mXLargeScreenSize){
1790d746a94137a87ffcc1fcefdac9a3764c3bc3f5cdLeon Scroggins            WebView view = t.getWebView();
1791d746a94137a87ffcc1fcefdac9a3764c3bc3f5cdLeon Scroggins            view.setEmbeddedTitleBar(mTitleBar);
1792d746a94137a87ffcc1fcefdac9a3764c3bc3f5cdLeon Scroggins        }
179358d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        if (t.isInVoiceSearchMode()) {
179458d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins            showVoiceTitleBar(t.getVoiceDisplayTitle());
179558d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        } else {
179658d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins            revertVoiceTitleBar();
179758d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        }
17980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Request focus on the top window.
17990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        t.getTopWindow().requestFocus();
18000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
18010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
18020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Attach a sub window to the main WebView of the given tab.
180322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void attachSubWindow(Tab t) {
1804d0119535d0c490e087be114ae8fd1639bb1945dcPatrick Scott        t.attachSubWindow(mContentView);
1805d0119535d0c490e087be114ae8fd1639bb1945dcPatrick Scott        getTopWindow().requestFocus();
18060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
18070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
18080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Remove the given tab from the content view.
180922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private void removeTabFromContentView(Tab t) {
18102bc69918d97a767a02132090e58718077381ba1aSteve Block        // Remove the container that contains the main WebView.
1811d0119535d0c490e087be114ae8fd1639bb1945dcPatrick Scott        t.removeTabFromContentView(mContentView);
1812bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch
181322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        ErrorConsoleView errorConsole = t.getErrorConsole(false);
181422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (errorConsole != null) {
181522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mErrorConsoleContainer.removeView(errorConsole);
1816bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch        }
1817bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch
1818d746a94137a87ffcc1fcefdac9a3764c3bc3f5cdLeon Scroggins        if (!mXLargeScreenSize) {
1819d746a94137a87ffcc1fcefdac9a3764c3bc3f5cdLeon Scroggins            WebView view = t.getWebView();
1820d746a94137a87ffcc1fcefdac9a3764c3bc3f5cdLeon Scroggins            if (view != null) {
1821d746a94137a87ffcc1fcefdac9a3764c3bc3f5cdLeon Scroggins                view.setEmbeddedTitleBar(null);
1822d746a94137a87ffcc1fcefdac9a3764c3bc3f5cdLeon Scroggins            }
1823bb85b9016201d45ea939d7cb7edd0ba6616a111cLeon Scroggins        }
18240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
18250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
18260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Remove the sub window if it exists. Also called by TabControl when the
18270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // user clicks the 'X' to dismiss a sub window.
182822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /* package */ void dismissSubWindow(Tab t) {
1829d0119535d0c490e087be114ae8fd1639bb1945dcPatrick Scott        t.removeSubWindow(mContentView);
183022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // dismiss the subwindow. This will destroy the WebView.
183122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        t.dismissSubWindow();
1832d0119535d0c490e087be114ae8fd1639bb1945dcPatrick Scott        getTopWindow().requestFocus();
18330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
18340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
18351f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins    // A wrapper function of {@link #openTabAndShow(UrlData, boolean, String)}
183625ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima    // that accepts url as string.
183722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private Tab openTabAndShow(String url, boolean closeOnExit, String appId) {
18381f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins        return openTabAndShow(new UrlData(url), closeOnExit, appId);
18390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
18400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
18410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // This method does a ton of stuff. It will attempt to create a new tab
18420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // if we haven't reached MAX_TABS. Otherwise it uses the current tab. If
18431f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins    // url isn't null, it will load the given url.
184422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /* package */Tab openTabAndShow(UrlData urlData, boolean closeOnExit,
184522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            String appId) {
184622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        final Tab currentTab = mTabControl.getCurrentTab();
184722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mTabControl.canCreateNewTab()) {
184822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            final Tab tab = mTabControl.createNewTab(closeOnExit, appId,
184922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    urlData.mUrl);
18501f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins            WebView webview = tab.getWebView();
18510a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins            // If the last tab was removed from the active tabs page, currentTab
18520a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins            // will be null.
18530a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins            if (currentTab != null) {
18540a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins                removeTabFromContentView(currentTab);
18550a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins            }
18568bbd69f50abd537bfe7eb314b3a3e20241ac22bdPatrick Scott            // We must set the new tab as the current tab to reflect the old
18578bbd69f50abd537bfe7eb314b3a3e20241ac22bdPatrick Scott            // animation behavior.
18588bbd69f50abd537bfe7eb314b3a3e20241ac22bdPatrick Scott            mTabControl.setCurrentTab(tab);
1859eb6eef4c45df2d65c3e70660493a147a2be405e3Grace Kloba            attachTabToContentView(tab);
1860160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins            if (!urlData.isEmpty()) {
18619d53da05812f959745810a33bb4e06b273393c42Patrick Scott                loadUrlDataIn(tab, urlData);
18620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
18631f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins            return tab;
186464b80f3efd95d7b5192731e995ccde79c4c6c11fLeon Scroggins        } else {
18651f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins            // Get rid of the subwindow if it exists
18661f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins            dismissSubWindow(currentTab);
18671f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins            if (!urlData.isEmpty()) {
18681f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                // Load the given url.
18699d53da05812f959745810a33bb4e06b273393c42Patrick Scott                loadUrlDataIn(currentTab, urlData);
18700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
187158d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins            return currentTab;
18720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
18730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
18740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
187522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private Tab openTab(String url) {
18760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mSettings.openInBackground()) {
187722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            Tab t = mTabControl.createNewTab();
18780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (t != null) {
18791f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                WebView view = t.getWebView();
188092472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins                loadUrl(view, url);
18810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
1882c9181841c7ed6b9f7dfc953eab8dc7ba1047022cGrace Kloba            return t;
18830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
18841f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins            return openTabAndShow(url, false, null);
18850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
18860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
18870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
18880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private class Copy implements OnMenuItemClickListener {
18890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        private CharSequence mText;
18900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
18910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public boolean onMenuItemClick(MenuItem item) {
18920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            copy(mText);
18930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return true;
18940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
18950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
18960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public Copy(CharSequence toCopy) {
18970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mText = toCopy;
18980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
18990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
19000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
19010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private class Download implements OnMenuItemClickListener {
19020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        private String mText;
19030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
19040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public boolean onMenuItemClick(MenuItem item) {
19050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            onDownloadStartNoStream(mText, null, null, null, -1);
19060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return true;
19070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
19080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
19090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public Download(String toDownload) {
19100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mText = toDownload;
19110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
19120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
19130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
19144f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch    private class SetAsWallpaper extends Thread implements
19154f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch            OnMenuItemClickListener, DialogInterface.OnCancelListener {
19164f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch        private URL mUrl;
19174f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch        private ProgressDialog mWallpaperProgress;
19184f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch        private boolean mCanceled = false;
19194f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch
19204f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch        public SetAsWallpaper(String url) {
19214f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch            try {
19224f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                mUrl = new URL(url);
19234f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch            } catch (MalformedURLException e) {
19244f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                mUrl = null;
19254f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch            }
19264f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch        }
19274f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch
19284f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch        public void onCancel(DialogInterface dialog) {
19294f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch            mCanceled = true;
19304f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch        }
19314f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch
19324f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch        public boolean onMenuItemClick(MenuItem item) {
19334f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch            if (mUrl != null) {
19344f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                // The user may have tried to set a image with a large file size as their
19354f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                // background so it may take a few moments to perform the operation. Display
19364f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                // a progress spinner while it is working.
19374f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                mWallpaperProgress = new ProgressDialog(BrowserActivity.this);
19384f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                mWallpaperProgress.setIndeterminate(true);
19394f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                mWallpaperProgress.setMessage(getText(R.string.progress_dialog_setting_wallpaper));
19404f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                mWallpaperProgress.setCancelable(true);
19414f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                mWallpaperProgress.setOnCancelListener(this);
19424f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                mWallpaperProgress.show();
19434f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                start();
19444f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch            }
19454f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch            return true;
19464f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch        }
19474f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch
1948e0a3666b5c0dca7352895fa8b9b4fbb2237df721Michael Kolb        @Override
19494f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch        public void run() {
19504f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch            Drawable oldWallpaper = BrowserActivity.this.getWallpaper();
19514f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch            try {
19524f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                // TODO: This will cause the resource to be downloaded again, when we
19534f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                // should in most cases be able to grab it from the cache. To fix this
19544f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                // we should query WebCore to see if we can access a cached version and
19554f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                // instead open an input stream on that. This pattern could also be used
19564f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                // in the download manager where the same problem exists.
19574f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                InputStream inputstream = mUrl.openStream();
19584f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                if (inputstream != null) {
19594f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                    setWallpaper(inputstream);
19604f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                }
19614f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch            } catch (IOException e) {
19624f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                Log.e(LOGTAG, "Unable to set new wallpaper");
19634f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                // Act as though the user canceled the operation so we try to
19644f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                // restore the old wallpaper.
19654f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                mCanceled = true;
19664f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch            }
19674f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch
19684f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch            if (mCanceled) {
19694f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                // Restore the old wallpaper if the user cancelled whilst we were setting
19704f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                // the new wallpaper.
19714f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                int width = oldWallpaper.getIntrinsicWidth();
19724f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                int height = oldWallpaper.getIntrinsicHeight();
19734f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                Bitmap bm = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);
19744f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                Canvas canvas = new Canvas(bm);
19754f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                oldWallpaper.setBounds(0, 0, width, height);
19764f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                oldWallpaper.draw(canvas);
19774f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                try {
19784f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                    setWallpaper(bm);
19794f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                } catch (IOException e) {
19804f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                    Log.e(LOGTAG, "Unable to restore old wallpaper.");
19814f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                }
19824f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                mCanceled = false;
19834f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch            }
19844f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch
19854f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch            if (mWallpaperProgress.isShowing()) {
19864f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                mWallpaperProgress.dismiss();
19874f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch            }
19884f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch        }
19894f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch    }
19904f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch
19910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void copy(CharSequence text) {
19920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        try {
19930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            IClipboard clip = IClipboard.Stub.asInterface(ServiceManager.getService("clipboard"));
19940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (clip != null) {
19950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                clip.setClipboardText(text);
19960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
19970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } catch (android.os.RemoteException e) {
19980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Log.e(LOGTAG, "Copy failed", e);
19990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
20000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
20010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
20020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
20030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Resets the browser title-view to whatever it must be
20040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * (for example, if we had a loading error)
20050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * When we have a new page, we call resetTitle, when we
20060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * have to reset the titlebar to whatever it used to be
20070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * (for example, if the user chose to stop loading), we
20080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * call resetTitleAndRevertLockIcon.
20090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
20100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /* package */ void resetTitleAndRevertLockIcon() {
201122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mTabControl.getCurrentTab().revertLockIcon();
201222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        updateLockIconToLatest();
20130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        resetTitleIconAndProgress();
20140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
20150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
20160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
20170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Reset the title, favicon, and progress.
20180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
20190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void resetTitleIconAndProgress() {
20200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebView current = mTabControl.getCurrentWebView();
20210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (current == null) {
20220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
20230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
20240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        resetTitleAndIcon(current);
20250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        int progress = current.getProgress();
202622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        current.getWebChromeClient().onProgressChanged(current, progress);
20270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
20280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
20290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Reset the title and the icon based on the given item.
20300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void resetTitleAndIcon(WebView view) {
20310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebHistoryItem item = view.copyBackForwardList().getCurrentItem();
20320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (item != null) {
203368579393973f745fc65a2781061af9bb8f2d7020Leon Scroggins            setUrlTitle(item.getUrl(), item.getTitle());
20340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            setFavicon(item.getFavicon());
20350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
203668579393973f745fc65a2781061af9bb8f2d7020Leon Scroggins            setUrlTitle(null, null);
20370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            setFavicon(null);
20380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
20390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
20400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
20410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
20420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Sets a title composed of the URL and the title string.
20430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param url The URL of the site being loaded.
20440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param title The title of the site being loaded.
20450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
204622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void setUrlTitle(String url, String title) {
20470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mUrl = url;
20480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mTitle = title;
20490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
205058d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        // If we are in voice search mode, the title has already been set.
205158d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        if (mTabControl.getCurrentTab().isInVoiceSearchMode()) return;
205258d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        mTitleBar.setDisplayTitle(url);
2053d746a94137a87ffcc1fcefdac9a3764c3bc3f5cdLeon Scroggins        if (!mXLargeScreenSize) {
2054d746a94137a87ffcc1fcefdac9a3764c3bc3f5cdLeon Scroggins            mFakeTitleBar.setDisplayTitle(url);
2055d746a94137a87ffcc1fcefdac9a3764c3bc3f5cdLeon Scroggins        }
20560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
20570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
20580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
20590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param url The URL to build a title version of the URL from.
20600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @return The title version of the URL or null if fails.
20610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * The title version of the URL can be either the URL hostname,
20620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * or the hostname with an "https://" prefix (for secure URLs),
20630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * or an empty string if, for example, the URL in question is a
20640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * file:// URL with no hostname.
20650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
206632e14a6deccfa75490b3032bb4ddd5ae90f89de8Leon Scroggins    /* package */ static String buildTitleUrl(String url) {
20670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String titleUrl = null;
20680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
20690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (url != null) {
20700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            try {
20710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // parse the url string
20720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                URL urlObj = new URL(url);
20730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (urlObj != null) {
20740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    titleUrl = "";
20750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
20760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    String protocol = urlObj.getProtocol();
20770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    String host = urlObj.getHost();
20780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
20790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    if (host != null && 0 < host.length()) {
20800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        titleUrl = host;
20810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        if (protocol != null) {
20820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            // if a secure site, add an "https://" prefix!
20830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            if (protocol.equalsIgnoreCase("https")) {
20840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                titleUrl = protocol + "://" + host;
20850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            }
20860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }
20870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
20880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
20890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } catch (MalformedURLException e) {}
20900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
20910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
20920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return titleUrl;
20930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
20940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
20950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Set the favicon in the title bar.
209622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void setFavicon(Bitmap icon) {
209768579393973f745fc65a2781061af9bb8f2d7020Leon Scroggins        mTitleBar.setFavicon(icon);
2098d746a94137a87ffcc1fcefdac9a3764c3bc3f5cdLeon Scroggins        if (!mXLargeScreenSize) {
2099d746a94137a87ffcc1fcefdac9a3764c3bc3f5cdLeon Scroggins            mFakeTitleBar.setFavicon(icon);
2100d746a94137a87ffcc1fcefdac9a3764c3bc3f5cdLeon Scroggins        }
21010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
21020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
21030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
21040a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins     * Close the tab, remove its associated title bar, and adjust mTabControl's
21050a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins     * current tab to a valid value.
21061f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins     */
210722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /* package */ void closeTab(Tab t) {
21080a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins        int currentIndex = mTabControl.getCurrentIndex();
21090a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins        int removeIndex = mTabControl.getTabIndex(t);
21101f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins        mTabControl.removeTab(t);
21110a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins        if (currentIndex >= removeIndex && currentIndex != 0) {
21120a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins            currentIndex--;
21130a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins        }
21140a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins        mTabControl.setCurrentTab(mTabControl.getTab(currentIndex));
2115a5bf1deca120315a2643ea5b010f94d853461b15Andrei Popescu        resetTitleIconAndProgress();
2116654899b4b7a280efc01aac4977b74369024e5c94Leon Scroggins        updateLockIconToLatest();
21170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
21180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
2119dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins    /* package */ void goBackOnePageOrQuit() {
212022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        Tab current = mTabControl.getCurrentTab();
21210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (current == null) {
21220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            /*
21230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project             * Instead of finishing the activity, simply push this to the back
21240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project             * of the stack and let ActivityManager to choose the foreground
21250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project             * activity. As BrowserActivity is singleTask, it will be always the
21260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project             * root of the task. So we can use either true or false for
21270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project             * moveTaskToBack().
21280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project             */
21290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            moveTaskToBack(true);
213000d85e74921459b34e70eb93368245b4c0a9bf5fGrace Kloba            return;
21310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
21320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebView w = current.getWebView();
21330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (w.canGoBack()) {
21340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            w.goBack();
21350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
21360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Check to see if we are closing a window that was created by
21370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // another window. If so, we switch back to that window.
213822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            Tab parent = current.getParentTab();
21390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (parent != null) {
21401f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                switchToTab(mTabControl.getTabIndex(parent));
21411f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                // Now we close the other tab
21421f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                closeTab(current);
21430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } else {
21440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (current.closeOnExit()) {
214522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    // force the tab's inLoad() to be false as we are going to
214622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    // either finish the activity or remove the tab. This will
214722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    // ensure pauseWebViewTimers() taking action.
214822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    mTabControl.getCurrentTab().clearInLoad();
21490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    if (mTabControl.getTabCount() == 1) {
21500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        finish();
21510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        return;
21520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
21537bfa63b55644fbf2da1fe6a24b3be0267529202cMike Reed                    // call pauseWebViewTimers() now, we won't be able to call
21547bfa63b55644fbf2da1fe6a24b3be0267529202cMike Reed                    // it in onPause() as the WebView won't be valid.
2155ec1b5ad8d8283b1fbbc5d7fa1cd50ef95b9e594dGrace Kloba                    // Temporarily change mActivityInPause to be true as
2156ec1b5ad8d8283b1fbbc5d7fa1cd50ef95b9e594dGrace Kloba                    // pauseWebViewTimers() will do nothing if mActivityInPause
2157ec1b5ad8d8283b1fbbc5d7fa1cd50ef95b9e594dGrace Kloba                    // is false.
2158918e1d78b2db6ef21c71a07868572d9cda498476Grace Kloba                    boolean savedState = mActivityInPause;
2159918e1d78b2db6ef21c71a07868572d9cda498476Grace Kloba                    if (savedState) {
2160ec1b5ad8d8283b1fbbc5d7fa1cd50ef95b9e594dGrace Kloba                        Log.e(LOGTAG, "BrowserActivity is already paused "
2161ec1b5ad8d8283b1fbbc5d7fa1cd50ef95b9e594dGrace Kloba                                + "while handing goBackOnePageOrQuit.");
2162918e1d78b2db6ef21c71a07868572d9cda498476Grace Kloba                    }
2163918e1d78b2db6ef21c71a07868572d9cda498476Grace Kloba                    mActivityInPause = true;
21647bfa63b55644fbf2da1fe6a24b3be0267529202cMike Reed                    pauseWebViewTimers();
2165918e1d78b2db6ef21c71a07868572d9cda498476Grace Kloba                    mActivityInPause = savedState;
21660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    removeTabFromContentView(current);
21670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    mTabControl.removeTab(current);
21680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
21690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                /*
21700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                 * Instead of finishing the activity, simply push this to the back
21710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                 * of the stack and let ActivityManager to choose the foreground
21720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                 * activity. As BrowserActivity is singleTask, it will be always the
21730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                 * root of the task. So we can use either true or false for
21740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                 * moveTaskToBack().
21750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                 */
21760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                moveTaskToBack(true);
21770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
21780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
21790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
21800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
218122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    boolean isMenuDown() {
218222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return mMenuIsDown;
218322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
218422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
21855942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba    @Override
21865942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba    public boolean onKeyDown(int keyCode, KeyEvent event) {
2187f65b50ddd2f7ed1205002d74082fff1ac2336d5cLeon Scroggins        // Even if MENU is already held down, we need to call to super to open
2188f65b50ddd2f7ed1205002d74082fff1ac2336d5cLeon Scroggins        // the IME on long press.
2189f65b50ddd2f7ed1205002d74082fff1ac2336d5cLeon Scroggins        if (KeyEvent.KEYCODE_MENU == keyCode) {
2190f65b50ddd2f7ed1205002d74082fff1ac2336d5cLeon Scroggins            mMenuIsDown = true;
2191f65b50ddd2f7ed1205002d74082fff1ac2336d5cLeon Scroggins            return super.onKeyDown(keyCode, event);
2192f65b50ddd2f7ed1205002d74082fff1ac2336d5cLeon Scroggins        }
21935942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba        // The default key mode is DEFAULT_KEYS_SEARCH_LOCAL. As the MENU is
21945942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba        // still down, we don't want to trigger the search. Pretend to consume
21955942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba        // the key and do nothing.
21965942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba        if (mMenuIsDown) return true;
21975942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba
21985942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba        switch(keyCode) {
21995942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba            case KeyEvent.KEYCODE_SPACE:
2200da0fe556a00773ce2af25eb6dcc5442bd08c7addGrace Kloba                // WebView/WebTextView handle the keys in the KeyDown. As
2201da0fe556a00773ce2af25eb6dcc5442bd08c7addGrace Kloba                // the Activity's shortcut keys are only handled when WebView
2202da0fe556a00773ce2af25eb6dcc5442bd08c7addGrace Kloba                // doesn't, have to do it in onKeyDown instead of onKeyUp.
2203da0fe556a00773ce2af25eb6dcc5442bd08c7addGrace Kloba                if (event.isShiftPressed()) {
2204da0fe556a00773ce2af25eb6dcc5442bd08c7addGrace Kloba                    getTopWindow().pageUp(false);
2205da0fe556a00773ce2af25eb6dcc5442bd08c7addGrace Kloba                } else {
2206da0fe556a00773ce2af25eb6dcc5442bd08c7addGrace Kloba                    getTopWindow().pageDown(false);
2207da0fe556a00773ce2af25eb6dcc5442bd08c7addGrace Kloba                }
22085942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                return true;
22095942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba            case KeyEvent.KEYCODE_BACK:
22105942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                if (event.getRepeatCount() == 0) {
22115942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                    event.startTracking();
22125942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                    return true;
22135942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                } else if (mCustomView == null && mActiveTabsPage == null
22145942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                        && event.isLongPress()) {
22155942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                    bookmarksOrHistoryPicker(true);
22165942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                    return true;
22170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
22185942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                break;
22190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
22205942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba        return super.onKeyDown(keyCode, event);
22210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
22220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
22235942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba    @Override
22245942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba    public boolean onKeyUp(int keyCode, KeyEvent event) {
22255942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba        switch(keyCode) {
22265942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba            case KeyEvent.KEYCODE_MENU:
22275942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                mMenuIsDown = false;
22285942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                break;
22295942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba            case KeyEvent.KEYCODE_BACK:
22305942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                if (event.isTracking() && !event.isCanceled()) {
22315942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                    if (mCustomView != null) {
22325942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                        // if a custom view is showing, hide it
223322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        mTabControl.getCurrentWebView().getWebChromeClient()
223422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                .onHideCustomView();
22355942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                    } else if (mActiveTabsPage != null) {
22365942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                        // if tab page is showing, hide it
22375942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                        removeActiveTabPage(true);
22380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    } else {
22395942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                        WebView subwindow = mTabControl.getCurrentSubWindow();
22405942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                        if (subwindow != null) {
22415942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                            if (subwindow.canGoBack()) {
22425942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                                subwindow.goBack();
22435942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                            } else {
22445942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                                dismissSubWindow(mTabControl.getCurrentTab());
22455942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                            }
22465942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                        } else {
22475942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                            goBackOnePageOrQuit();
22485942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                        }
22490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
22505942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                    return true;
22515942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                }
22525942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                break;
22530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
22545942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba        return super.onKeyUp(keyCode, event);
22550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
22560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
225768579393973f745fc65a2781061af9bb8f2d7020Leon Scroggins    /* package */ void stopLoading() {
2258b7cc8b439dc595dc48e1c2183b35d23ad72dfbe5Ben Murdoch        mDidStopLoad = true;
22590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        resetTitleAndRevertLockIcon();
22600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebView w = getTopWindow();
22610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        w.stopLoading();
226222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // FIXME: before refactor, it is using mWebViewClient. So I keep the
226322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // same logic here. But for subwindow case, should we call into the main
226422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // WebView's onPageFinished as we never call its onPageStarted and if
226522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // the page finishes itself, we don't call onPageFinished.
226622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mTabControl.getCurrentWebView().getWebViewClient().onPageFinished(w,
226722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                w.getUrl());
22680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
22690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        cancelStopToast();
22700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mStopToast = Toast
22710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .makeText(this, R.string.stopping, Toast.LENGTH_SHORT);
22720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mStopToast.show();
22730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
22740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
227522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    boolean didUserStopLoading() {
227622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return mDidStopLoad;
227722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
227822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
22790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void cancelStopToast() {
22800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mStopToast != null) {
22810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mStopToast.cancel();
22820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mStopToast = null;
22830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
22840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
22850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
228622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // called by a UI or non-UI thread to post the message
228722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    public void postMessage(int what, int arg1, int arg2, Object obj,
228822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            long delayMillis) {
228922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mHandler.sendMessageDelayed(mHandler.obtainMessage(what, arg1, arg2,
229022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                obj), delayMillis);
229122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
229222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
229322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // called by a UI or non-UI thread to remove the message
229422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void removeMessages(int what, Object object) {
229522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mHandler.removeMessages(what, object);
22960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
22970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
22980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // public message ids
22990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public final static int LOAD_URL                = 1001;
23000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public final static int STOP_LOAD               = 1002;
23010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
23020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Message Ids
23030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private static final int FOCUS_NODE_HREF         = 102;
230492c18a52ca7a79c114028b5ba22c3dfe443bd1a4Grace Kloba    private static final int RELEASE_WAKELOCK        = 107;
23050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
230622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    static final int UPDATE_BOOKMARK_THUMBNAIL       = 108;
23072694e23a55d5ca526fc29534a80a200e2c58698bBen Murdoch
2308eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch    private static final int TOUCH_ICON_DOWNLOADED   = 109;
2309eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch
23100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Private handler for handling javascript and saving passwords
23110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private Handler mHandler = new Handler() {
23120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
2313e0a3666b5c0dca7352895fa8b9b4fbb2237df721Michael Kolb        @Override
23140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public void handleMessage(Message msg) {
23150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            switch (msg.what) {
23160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                case FOCUS_NODE_HREF:
23172694e23a55d5ca526fc29534a80a200e2c58698bBen Murdoch                {
23180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    String url = (String) msg.getData().get("url");
231990d088caeee718f89755ee9c25249ba6da15ab97Ben Murdoch                    String title = (String) msg.getData().get("title");
23200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    if (url == null || url.length() == 0) {
23210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        break;
23220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
23230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    HashMap focusNodeMap = (HashMap) msg.obj;
23240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    WebView view = (WebView) focusNodeMap.get("webview");
23250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // Only apply the action if the top window did not change.
23260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    if (getTopWindow() != view) {
23270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        break;
23280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
23290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    switch (msg.arg1) {
23300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        case R.id.open_context_menu_id:
23310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        case R.id.view_image_context_menu_id:
233292472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins                            loadUrlFromContext(getTopWindow(), url);
23330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            break;
23340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        case R.id.bookmark_context_menu_id:
23350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            Intent intent = new Intent(BrowserActivity.this,
23360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    AddBookmarkPage.class);
23370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            intent.putExtra("url", url);
233890d088caeee718f89755ee9c25249ba6da15ab97Ben Murdoch                            intent.putExtra("title", title);
23390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            startActivity(intent);
23400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            break;
23410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        case R.id.share_link_context_menu_id:
23423e20445506307d2c8d699e1d17fb82a0cedde1d0Leon Scroggins                            sharePage(BrowserActivity.this, title, url, null,
234396afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                                    null);
23440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            break;
23450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        case R.id.copy_link_context_menu_id:
23460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            copy(url);
23470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            break;
23480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        case R.id.save_link_context_menu_id:
23490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        case R.id.download_context_menu_id:
23500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            onDownloadStartNoStream(url, null, null, null, -1);
23510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            break;
23520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
23530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    break;
23542694e23a55d5ca526fc29534a80a200e2c58698bBen Murdoch                }
23550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
23560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                case LOAD_URL:
235792472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins                    loadUrlFromContext(getTopWindow(), (String) msg.obj);
23580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    break;
23590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
23600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                case STOP_LOAD:
23610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    stopLoading();
23620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    break;
23630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
23640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                case RELEASE_WAKELOCK:
23650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    if (mWakeLock.isHeld()) {
23660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        mWakeLock.release();
23675d0e02e646e46b14289168f75c2a8f6ed43cac54Grace Kloba                        // if we reach here, Browser should be still in the
23685d0e02e646e46b14289168f75c2a8f6ed43cac54Grace Kloba                        // background loading after WAKELOCK_TIMEOUT (5-min).
23695d0e02e646e46b14289168f75c2a8f6ed43cac54Grace Kloba                        // To avoid burning the battery, stop loading.
23705d0e02e646e46b14289168f75c2a8f6ed43cac54Grace Kloba                        mTabControl.stopAllLoading();
23710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
23720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    break;
23732694e23a55d5ca526fc29534a80a200e2c58698bBen Murdoch
23742694e23a55d5ca526fc29534a80a200e2c58698bBen Murdoch                case UPDATE_BOOKMARK_THUMBNAIL:
23752694e23a55d5ca526fc29534a80a200e2c58698bBen Murdoch                    WebView view = (WebView) msg.obj;
23762694e23a55d5ca526fc29534a80a200e2c58698bBen Murdoch                    if (view != null) {
23772694e23a55d5ca526fc29534a80a200e2c58698bBen Murdoch                        updateScreenshot(view);
23782694e23a55d5ca526fc29534a80a200e2c58698bBen Murdoch                    }
23792694e23a55d5ca526fc29534a80a200e2c58698bBen Murdoch                    break;
2380eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch
2381eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch                case TOUCH_ICON_DOWNLOADED:
2382eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch                    Bundle b = msg.getData();
2383eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch                    showSaveToHomescreenDialog(b.getString("url"),
2384eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch                        b.getString("title"),
2385eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch                        (Bitmap) b.getParcelable("touchIcon"),
2386eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch                        (Bitmap) b.getParcelable("favicon"));
2387eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch                    break;
23880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
23890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
23900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    };
23910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
239296afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins    /**
239396afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins     * Share a page, providing the title, url, favicon, and a screenshot.  Uses
239496afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins     * an {@link Intent} to launch the Activity chooser.
239596afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins     * @param c Context used to launch a new Activity.
239696afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins     * @param title Title of the page.  Stored in the Intent with
239703e6d39560d7de359782485d4c863d600b34fb51Paul Westbrook     *          {@link Intent#EXTRA_SUBJECT}
239896afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins     * @param url URL of the page.  Stored in the Intent with
239996afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins     *          {@link Intent#EXTRA_TEXT}
240096afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins     * @param favicon Bitmap of the favicon for the page.  Stored in the Intent
240196afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins     *          with {@link Browser#EXTRA_SHARE_FAVICON}
240296afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins     * @param screenshot Bitmap of a screenshot of the page.  Stored in the
240396afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins     *          Intent with {@link Browser#EXTRA_SHARE_SCREENSHOT}
240496afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins     */
240596afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins    public static final void sharePage(Context c, String title, String url,
240696afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins            Bitmap favicon, Bitmap screenshot) {
240796afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins        Intent send = new Intent(Intent.ACTION_SEND);
240896afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins        send.setType("text/plain");
240996afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins        send.putExtra(Intent.EXTRA_TEXT, url);
241003e6d39560d7de359782485d4c863d600b34fb51Paul Westbrook        send.putExtra(Intent.EXTRA_SUBJECT, title);
241196afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins        send.putExtra(Browser.EXTRA_SHARE_FAVICON, favicon);
241296afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins        send.putExtra(Browser.EXTRA_SHARE_SCREENSHOT, screenshot);
241396afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins        try {
241496afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins            c.startActivity(Intent.createChooser(send, c.getString(
241596afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                    R.string.choosertitle_sharevia)));
241696afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins        } catch(android.content.ActivityNotFoundException ex) {
241796afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins            // if no app handles it, do nothing
241896afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins        }
241996afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins    }
242096afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins
242189c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins    private void updateScreenshot(WebView view) {
242289c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins        // If this is a bookmarked site, add a screenshot to the database.
242389c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins        // FIXME: When should we update?  Every time?
242489c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins        // FIXME: Would like to make sure there is actually something to
242589c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins        // draw, but the API for that (WebViewCore.pictureReady()) is not
242689c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins        // currently accessible here.
2427aac7aa6fcfcb519755987ec126be066323f589c8Ben Murdoch
242887cc65d95c80c5e3a1c343ad5177a7dc2de874f6Ben Murdoch        final Bitmap bm = createScreenshot(view, getDesiredThumbnailWidth(this),
242987cc65d95c80c5e3a1c343ad5177a7dc2de874f6Ben Murdoch                getDesiredThumbnailHeight(this));
2430cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott        if (bm == null) {
2431cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott            return;
2432cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott        }
2433cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott
2434cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott        final ContentResolver cr = getContentResolver();
2435cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott        final String url = view.getUrl();
2436cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott        final String originalUrl = view.getOriginalUrl();
2437cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott
2438cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott        new AsyncTask<Void, Void, Void>() {
2439cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott            @Override
2440cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott            protected Void doInBackground(Void... unused) {
2441cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott                Cursor c = null;
2442cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott                try {
2443cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott                    c = BrowserBookmarksAdapter.queryBookmarksForUrl(
2444cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott                            cr, originalUrl, url, true);
2445cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott                    if (c != null) {
2446cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott                        if (c.moveToFirst()) {
2447cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott                            ContentValues values = new ContentValues();
2448cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott                            final ByteArrayOutputStream os
2449cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott                                    = new ByteArrayOutputStream();
2450cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott                            bm.compress(Bitmap.CompressFormat.PNG, 100, os);
2451cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott                            values.put(Browser.BookmarkColumns.THUMBNAIL,
2452cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott                                    os.toByteArray());
2453cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott                            do {
2454cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott                                cr.update(ContentUris.withAppendedId(
2455cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott                                        Browser.BOOKMARKS_URI, c.getInt(0)),
2456cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott                                        values, null, null);
2457cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott                            } while (c.moveToNext());
2458cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott                        }
24594580057e772b60433272af5cd691825748892693Leon Scroggins                    }
2460cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott                } catch (IllegalStateException e) {
2461cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott                    // Ignore
2462cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott                } finally {
2463cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott                    if (c != null) c.close();
246489c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins                }
2465cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott                return null;
246689c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins            }
2467cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott        }.execute();
246889c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins    }
246989c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins
247006ec5f2d8735d1ba17b779deb0f8da032e0a62eaLeon Scroggins    /**
2471f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins     * Values for the size of the thumbnail created when taking a screenshot.
2472f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins     * Lazily initialized.  Instead of using these directly, use
2473f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins     * getDesiredThumbnailWidth() or getDesiredThumbnailHeight().
247406ec5f2d8735d1ba17b779deb0f8da032e0a62eaLeon Scroggins     */
2475f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins    private static int THUMBNAIL_WIDTH = 0;
2476f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins    private static int THUMBNAIL_HEIGHT = 0;
2477f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins
2478f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins    /**
2479f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins     * Return the desired width for thumbnail screenshots, which are stored in
2480f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins     * the database, and used on the bookmarks screen.
2481f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins     * @param context Context for finding out the density of the screen.
2482f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins     * @return int desired width for thumbnail screenshot.
2483f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins     */
2484f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins    /* package */ static int getDesiredThumbnailWidth(Context context) {
2485f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins        if (THUMBNAIL_WIDTH == 0) {
2486f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins            float density = context.getResources().getDisplayMetrics().density;
2487f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins            THUMBNAIL_WIDTH = (int) (90 * density);
2488f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins            THUMBNAIL_HEIGHT = (int) (80 * density);
2489f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins        }
2490f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins        return THUMBNAIL_WIDTH;
2491f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins    }
2492f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins
2493f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins    /**
2494f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins     * Return the desired height for thumbnail screenshots, which are stored in
2495f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins     * the database, and used on the bookmarks screen.
2496f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins     * @param context Context for finding out the density of the screen.
2497f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins     * @return int desired height for thumbnail screenshot.
2498f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins     */
2499f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins    /* package */ static int getDesiredThumbnailHeight(Context context) {
2500f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins        // To ensure that they are both initialized.
2501f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins        getDesiredThumbnailWidth(context);
2502f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins        return THUMBNAIL_HEIGHT;
2503f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins    }
250406ec5f2d8735d1ba17b779deb0f8da032e0a62eaLeon Scroggins
250587cc65d95c80c5e3a1c343ad5177a7dc2de874f6Ben Murdoch    private Bitmap createScreenshot(WebView view, int width, int height) {
2506dcc2b6f08dd5677bc6ba761a9ba6f1c655113051Ben Murdoch        Picture thumbnail = view.capturePicture();
25074580057e772b60433272af5cd691825748892693Leon Scroggins        if (thumbnail == null) {
25084580057e772b60433272af5cd691825748892693Leon Scroggins            return null;
25094580057e772b60433272af5cd691825748892693Leon Scroggins        }
251087cc65d95c80c5e3a1c343ad5177a7dc2de874f6Ben Murdoch        Bitmap bm = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);
2511dcc2b6f08dd5677bc6ba761a9ba6f1c655113051Ben Murdoch        Canvas canvas = new Canvas(bm);
2512dcc2b6f08dd5677bc6ba761a9ba6f1c655113051Ben Murdoch        // May need to tweak these values to determine what is the
2513dcc2b6f08dd5677bc6ba761a9ba6f1c655113051Ben Murdoch        // best scale factor
25142694e23a55d5ca526fc29534a80a200e2c58698bBen Murdoch        int thumbnailWidth = thumbnail.getWidth();
2515ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch        int thumbnailHeight = thumbnail.getHeight();
2516ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch        float scaleFactorX = 1.0f;
2517ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch        float scaleFactorY = 1.0f;
25182694e23a55d5ca526fc29534a80a200e2c58698bBen Murdoch        if (thumbnailWidth > 0) {
251987cc65d95c80c5e3a1c343ad5177a7dc2de874f6Ben Murdoch            scaleFactorX = (float) width / (float)thumbnailWidth;
2520ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch        } else {
2521ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch            return null;
252206ec5f2d8735d1ba17b779deb0f8da032e0a62eaLeon Scroggins        }
2523ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch
2524ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch        if (view.getWidth() > view.getHeight() &&
2525ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch                thumbnailHeight < view.getHeight() && thumbnailHeight > 0) {
2526ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch            // If the device is in landscape and the page is shorter
2527ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch            // than the height of the view, stretch the thumbnail to fill the
2528ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch            // space.
252987cc65d95c80c5e3a1c343ad5177a7dc2de874f6Ben Murdoch            scaleFactorY = (float) height / (float)thumbnailHeight;
2530ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch        } else {
2531ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch            // In the portrait case, this looks nice.
2532ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch            scaleFactorY = scaleFactorX;
2533ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch        }
2534ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch
2535ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch        canvas.scale(scaleFactorX, scaleFactorY);
2536ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch
2537dcc2b6f08dd5677bc6ba761a9ba6f1c655113051Ben Murdoch        thumbnail.draw(canvas);
2538dcc2b6f08dd5677bc6ba761a9ba6f1c655113051Ben Murdoch        return bm;
2539dcc2b6f08dd5677bc6ba761a9ba6f1c655113051Ben Murdoch    }
2540dcc2b6f08dd5677bc6ba761a9ba6f1c655113051Ben Murdoch
25410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // -------------------------------------------------------------------------
254222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // Helper function for WebViewClient.
25430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    //-------------------------------------------------------------------------
25440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
25450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Use in overrideUrlLoading
25460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /* package */ final static String SCHEME_WTAI = "wtai://wp/";
25470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /* package */ final static String SCHEME_WTAI_MC = "wtai://wp/mc;";
25480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /* package */ final static String SCHEME_WTAI_SD = "wtai://wp/sd;";
25490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /* package */ final static String SCHEME_WTAI_AP = "wtai://wp/ap;";
25500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
255192472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins    // Keep this initial progress in sync with initialProgressValue (* 100)
255292472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins    // in ProgressTracker.cpp
255392472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins    private final static int INITIAL_PROGRESS = 10;
255492472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins
255522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void onPageStarted(WebView view, String url, Bitmap favicon) {
255622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // when BrowserActivity just starts, onPageStarted may be called before
255722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // onResume as it is triggered from onCreate. Call resumeWebViewTimers
255822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // to start the timer. As we won't switch tabs while an activity is in
255922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // pause state, we can ensure calling resume and pause in pair.
256022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mActivityInPause) resumeWebViewTimers();
256122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
256222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        resetLockIcon(url);
256322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        setUrlTitle(url, null);
256422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        setFavicon(favicon);
25658cf8f682e90f004d4b8028d2f5b74f72c0cf4e19Leon Scroggins        // Show some progress so that the user knows the page is beginning to
25668cf8f682e90f004d4b8028d2f5b74f72c0cf4e19Leon Scroggins        // load
256792472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins        onProgressChanged(view, INITIAL_PROGRESS);
256822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mDidStopLoad = false;
256922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (!mIsNetworkUp) createAndShowNetworkDialog();
257001cfcdd0b77d672f5c09d98af683c6732c8250d8Cary Clark        closeDialogs();
257122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mSettings.isTracing()) {
257222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            String host;
257322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            try {
257422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                WebAddress uri = new WebAddress(url);
257522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                host = uri.mHost;
257622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            } catch (android.net.ParseException ex) {
257722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                host = "browser";
257822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
257922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            host = host.replace('.', '_');
258022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            host += ".trace";
258122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mInTrace = true;
258222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            Debug.startMethodTracing(host, 20 * 1024 * 1024);
258315525d48024d325c8a52766d8ca727191251a8d4Patrick Scott        }
258415525d48024d325c8a52766d8ca727191251a8d4Patrick Scott
258522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Performance probe
258622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (false) {
258722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mStart = SystemClock.uptimeMillis();
258822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mProcessStart = Process.getElapsedCpuTime();
258922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            long[] sysCpu = new long[7];
259022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (Process.readProcFile("/proc/stat", SYSTEM_CPU_FORMAT, null,
259122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    sysCpu, null)) {
259222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                mUserStart = sysCpu[0] + sysCpu[1];
259322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                mSystemStart = sysCpu[2];
259422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                mIdleStart = sysCpu[3];
259522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                mIrqStart = sysCpu[4] + sysCpu[5] + sysCpu[6];
259622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
259722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mUiStart = SystemClock.currentThreadTimeMillis();
25980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
25990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
26000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
260122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void onPageFinished(WebView view, String url) {
260222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Reset the title and icon in case we stopped a provisional load.
260322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        resetTitleAndIcon(view);
260422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Update the lock icon image only once we are done loading
260522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        updateLockIconToLatest();
260622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // pause the WebView timer and release the wake lock if it is finished
260722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // while BrowserActivity is in pause state.
260822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mActivityInPause && pauseWebViewTimers()) {
260922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (mWakeLock.isHeld()) {
261022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                mHandler.removeMessages(RELEASE_WAKELOCK);
261122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                mWakeLock.release();
261222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
261322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
261422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
261522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Performance probe
261622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (false) {
261722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            long[] sysCpu = new long[7];
261822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (Process.readProcFile("/proc/stat", SYSTEM_CPU_FORMAT, null,
261922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    sysCpu, null)) {
262022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                String uiInfo = "UI thread used "
262122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        + (SystemClock.currentThreadTimeMillis() - mUiStart)
262222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        + " ms";
262322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                if (LOGD_ENABLED) {
262422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    Log.d(LOGTAG, uiInfo);
262522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                }
262622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                //The string that gets written to the log
262722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                String performanceString = "It took total "
262822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        + (SystemClock.uptimeMillis() - mStart)
262922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        + " ms clock time to load the page."
263022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        + "\nbrowser process used "
263122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        + (Process.getElapsedCpuTime() - mProcessStart)
263222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        + " ms, user processes used "
263322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        + (sysCpu[0] + sysCpu[1] - mUserStart) * 10
263422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        + " ms, kernel used "
263522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        + (sysCpu[2] - mSystemStart) * 10
263622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        + " ms, idle took " + (sysCpu[3] - mIdleStart) * 10
263722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        + " ms and irq took "
263822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        + (sysCpu[4] + sysCpu[5] + sysCpu[6] - mIrqStart)
263922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        * 10 + " ms, " + uiInfo;
264022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                if (LOGD_ENABLED) {
264122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    Log.d(LOGTAG, performanceString + "\nWebpage: " + url);
26420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
264322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                if (url != null) {
264422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    // strip the url to maintain consistency
264522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    String newUrl = new String(url);
264622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    if (newUrl.startsWith("http://www.")) {
264722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        newUrl = newUrl.substring(11);
264822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    } else if (newUrl.startsWith("http://")) {
264922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        newUrl = newUrl.substring(7);
265022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    } else if (newUrl.startsWith("https://www.")) {
265122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        newUrl = newUrl.substring(12);
265222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    } else if (newUrl.startsWith("https://")) {
265322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        newUrl = newUrl.substring(8);
26540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
265531a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort                    if (LOGD_ENABLED) {
265622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        Log.d(LOGTAG, newUrl + " loaded");
26570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
26580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
26590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
266022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         }
26610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
266222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mInTrace) {
266322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mInTrace = false;
266422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            Debug.stopMethodTracing();
26650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
266622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
26670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
2668e7fe26bb1af55ec9e1535dcff8c9611692a7132dGrace Kloba    private void closeEmptyChildTab() {
2669e7fe26bb1af55ec9e1535dcff8c9611692a7132dGrace Kloba        Tab current = mTabControl.getCurrentTab();
2670e7fe26bb1af55ec9e1535dcff8c9611692a7132dGrace Kloba        if (current != null
2671e7fe26bb1af55ec9e1535dcff8c9611692a7132dGrace Kloba                && current.getWebView().copyBackForwardList().getSize() == 0) {
2672e7fe26bb1af55ec9e1535dcff8c9611692a7132dGrace Kloba            Tab parent = current.getParentTab();
2673e7fe26bb1af55ec9e1535dcff8c9611692a7132dGrace Kloba            if (parent != null) {
2674e7fe26bb1af55ec9e1535dcff8c9611692a7132dGrace Kloba                switchToTab(mTabControl.getTabIndex(parent));
2675e7fe26bb1af55ec9e1535dcff8c9611692a7132dGrace Kloba                closeTab(current);
2676e7fe26bb1af55ec9e1535dcff8c9611692a7132dGrace Kloba            }
2677e7fe26bb1af55ec9e1535dcff8c9611692a7132dGrace Kloba        }
2678e7fe26bb1af55ec9e1535dcff8c9611692a7132dGrace Kloba    }
2679e7fe26bb1af55ec9e1535dcff8c9611692a7132dGrace Kloba
268022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    boolean shouldOverrideUrlLoading(WebView view, String url) {
268122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (url.startsWith(SCHEME_WTAI)) {
268222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // wtai://wp/mc;number
268322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // number=string(phone-number)
268422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (url.startsWith(SCHEME_WTAI_MC)) {
268522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                Intent intent = new Intent(Intent.ACTION_VIEW,
268622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        Uri.parse(WebView.SCHEME_TEL +
268722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        url.substring(SCHEME_WTAI_MC.length())));
268822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                startActivity(intent);
2689e7fe26bb1af55ec9e1535dcff8c9611692a7132dGrace Kloba                // before leaving BrowserActivity, close the empty child tab.
2690e7fe26bb1af55ec9e1535dcff8c9611692a7132dGrace Kloba                // If a new tab is created through JavaScript open to load this
2691e7fe26bb1af55ec9e1535dcff8c9611692a7132dGrace Kloba                // url, we would like to close it as we will load this url in a
2692e7fe26bb1af55ec9e1535dcff8c9611692a7132dGrace Kloba                // different Activity.
2693e7fe26bb1af55ec9e1535dcff8c9611692a7132dGrace Kloba                closeEmptyChildTab();
269422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                return true;
26950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
269622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // wtai://wp/sd;dtmf
269722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // dtmf=string(dialstring)
269822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (url.startsWith(SCHEME_WTAI_SD)) {
269922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                // TODO: only send when there is active voice connection
27009918943559193e3e047a1c18442e2cdb0fe22b15Dianne Hackborn                return false;
27019918943559193e3e047a1c18442e2cdb0fe22b15Dianne Hackborn            }
270222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // wtai://wp/ap;number;name
270322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // number=string(phone-number)
270422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // name=string
270522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (url.startsWith(SCHEME_WTAI_AP)) {
270622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                // TODO
27070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                return false;
27080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
27090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
27100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
271122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // The "about:" schemes are internal to the browser; don't want these to
271222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // be dispatched to other apps.
271322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (url.startsWith("about:")) {
271422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            return false;
27150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
27160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
271722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        Intent intent;
271822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // perform generic parsing of the URI to turn it into an Intent.
271922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        try {
272022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            intent = Intent.parseUri(url, Intent.URI_INTENT_SCHEME);
272122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        } catch (URISyntaxException ex) {
272222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            Log.w("Browser", "Bad URI " + url + ": " + ex.getMessage());
272322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            return false;
27240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
27250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
272622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // check whether the intent can be resolved. If not, we will see
272722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // whether we can download it from the Market.
272822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (getPackageManager().resolveActivity(intent, 0) == null) {
272922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            String packagename = intent.getPackage();
273022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (packagename != null) {
273122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                intent = new Intent(Intent.ACTION_VIEW, Uri
273222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        .parse("market://search?q=pname:" + packagename));
273322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                intent.addCategory(Intent.CATEGORY_BROWSABLE);
273422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                startActivity(intent);
2735e7fe26bb1af55ec9e1535dcff8c9611692a7132dGrace Kloba                // before leaving BrowserActivity, close the empty child tab.
2736e7fe26bb1af55ec9e1535dcff8c9611692a7132dGrace Kloba                // If a new tab is created through JavaScript open to load this
2737e7fe26bb1af55ec9e1535dcff8c9611692a7132dGrace Kloba                // url, we would like to close it as we will load this url in a
2738e7fe26bb1af55ec9e1535dcff8c9611692a7132dGrace Kloba                // different Activity.
2739e7fe26bb1af55ec9e1535dcff8c9611692a7132dGrace Kloba                closeEmptyChildTab();
274022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                return true;
27410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } else {
27420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                return false;
27430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
27440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
27450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
274622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // sanitize the Intent, ensuring web pages can not bypass browser
274722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // security (only access to BROWSABLE activities).
274822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        intent.addCategory(Intent.CATEGORY_BROWSABLE);
274922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        intent.setComponent(null);
275022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        try {
275122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (startActivityIfNeeded(intent, -1)) {
2752e7fe26bb1af55ec9e1535dcff8c9611692a7132dGrace Kloba                // before leaving BrowserActivity, close the empty child tab.
2753e7fe26bb1af55ec9e1535dcff8c9611692a7132dGrace Kloba                // If a new tab is created through JavaScript open to load this
2754e7fe26bb1af55ec9e1535dcff8c9611692a7132dGrace Kloba                // url, we would like to close it as we will load this url in a
2755e7fe26bb1af55ec9e1535dcff8c9611692a7132dGrace Kloba                // different Activity.
2756e7fe26bb1af55ec9e1535dcff8c9611692a7132dGrace Kloba                closeEmptyChildTab();
27570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                return true;
27580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
275922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        } catch (ActivityNotFoundException ex) {
276022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // ignore the error. If no application can handle the URL,
276122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // eg about:blank, assume the browser can handle it.
276222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
27630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
276422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mMenuIsDown) {
276522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            openTab(url);
276622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            closeOptionsMenu();
27670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return true;
27680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
276922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return false;
277022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
27710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
277222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // -------------------------------------------------------------------------
277322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // Helper function for WebChromeClient
277422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // -------------------------------------------------------------------------
27750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
277622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void onProgressChanged(WebView view, int newProgress) {
2777d746a94137a87ffcc1fcefdac9a3764c3bc3f5cdLeon Scroggins        if (mXLargeScreenSize) {
2778d746a94137a87ffcc1fcefdac9a3764c3bc3f5cdLeon Scroggins            mTitleBar.setProgress(newProgress);
2779d746a94137a87ffcc1fcefdac9a3764c3bc3f5cdLeon Scroggins        } else {
2780d746a94137a87ffcc1fcefdac9a3764c3bc3f5cdLeon Scroggins            // On the phone, the fake title bar will always cover up the
2781d746a94137a87ffcc1fcefdac9a3764c3bc3f5cdLeon Scroggins            // regular title bar (or the regular one is offscreen), so only the
2782d746a94137a87ffcc1fcefdac9a3764c3bc3f5cdLeon Scroggins            // fake title bar needs to change its progress
2783d746a94137a87ffcc1fcefdac9a3764c3bc3f5cdLeon Scroggins            mFakeTitleBar.setProgress(newProgress);
2784d746a94137a87ffcc1fcefdac9a3764c3bc3f5cdLeon Scroggins        }
278522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
278622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (newProgress == 100) {
278722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // onProgressChanged() may continue to be called after the main
278822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // frame has finished loading, as any remaining sub frames continue
278922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // to load. We'll only get called once though with newProgress as
279022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // 100 when everything is loaded. (onPageFinished is called once
279122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // when the main frame completes loading regardless of the state of
279222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // any sub frames so calls to onProgressChanges may continue after
279322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // onPageFinished has executed)
279422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (mInLoad) {
279522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                mInLoad = false;
2796a27ff19e24cb1c9fef5624dbc4554548349b5b31Leon Scroggins                updateInLoadMenuItems();
279722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                // If the options menu is open, leave the title bar
279822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                if (!mOptionsMenuOpen || !mIconView) {
279922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    hideFakeTitleBar();
28000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
28010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
2802aa37e7fdb52d0180b8eea25d53950c5c0791f968Leon Scroggins        } else {
2803aa37e7fdb52d0180b8eea25d53950c5c0791f968Leon Scroggins            if (!mInLoad) {
2804aa37e7fdb52d0180b8eea25d53950c5c0791f968Leon Scroggins                // onPageFinished may have already been called but a subframe is
2805aa37e7fdb52d0180b8eea25d53950c5c0791f968Leon Scroggins                // still loading and updating the progress. Reset mInLoad and
2806aa37e7fdb52d0180b8eea25d53950c5c0791f968Leon Scroggins                // update the menu items.
2807aa37e7fdb52d0180b8eea25d53950c5c0791f968Leon Scroggins                mInLoad = true;
2808aa37e7fdb52d0180b8eea25d53950c5c0791f968Leon Scroggins                updateInLoadMenuItems();
2809aa37e7fdb52d0180b8eea25d53950c5c0791f968Leon Scroggins            }
2810aa37e7fdb52d0180b8eea25d53950c5c0791f968Leon Scroggins            // When the page first begins to load, the Activity may still be
2811aa37e7fdb52d0180b8eea25d53950c5c0791f968Leon Scroggins            // paused, in which case showFakeTitleBar will do nothing.  Call
2812aa37e7fdb52d0180b8eea25d53950c5c0791f968Leon Scroggins            // again as the page continues to load so that it will be shown.
2813aa37e7fdb52d0180b8eea25d53950c5c0791f968Leon Scroggins            // (Calling it will the fake title bar is already showing will also
2814aa37e7fdb52d0180b8eea25d53950c5c0791f968Leon Scroggins            // do nothing.
281522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (!mOptionsMenuOpen || mIconView) {
281622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                // This page has begun to load, so show the title bar
281722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                showFakeTitleBar();
28183918d4443ff38ef1870e02aa51a8b29f8352bb1aPatrick Scott            }
28190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
282022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
2821092dd5d22d7f2ee0efcc68bd6e5a3afd1ea98953Ben Murdoch
282222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void onShowCustomView(View view, WebChromeClient.CustomViewCallback callback) {
28238ff57db0a8dc8eb659fbcdcd4a856208609e6070Derek Sollenberger        // if a view already exists then immediately terminate the new one
28248ff57db0a8dc8eb659fbcdcd4a856208609e6070Derek Sollenberger        if (mCustomView != null) {
28258ff57db0a8dc8eb659fbcdcd4a856208609e6070Derek Sollenberger            callback.onCustomViewHidden();
282622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            return;
28278ff57db0a8dc8eb659fbcdcd4a856208609e6070Derek Sollenberger        }
28282bc69918d97a767a02132090e58718077381ba1aSteve Block
282922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Add the custom view to its container.
283022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mCustomViewContainer.addView(view, COVER_SCREEN_GRAVITY_CENTER);
283122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mCustomView = view;
283222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mCustomViewCallback = callback;
283322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Save the menu state and set it to empty while the custom
283422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // view is showing.
283522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mOldMenuState = mMenuState;
283622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mMenuState = EMPTY_MENU;
283722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Hide the content view.
283822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mContentView.setVisibility(View.GONE);
283922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Finally show the custom view container.
2840163ab74e2f85b53a1a374c49677073fb64d35f28Andrei Popescu        setStatusBarVisibility(false);
284122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mCustomViewContainer.setVisibility(View.VISIBLE);
284222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mCustomViewContainer.bringToFront();
284322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
284422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
284522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void onHideCustomView() {
284622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mCustomView == null)
284722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            return;
28482bc69918d97a767a02132090e58718077381ba1aSteve Block
284922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Hide the custom view.
285022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mCustomView.setVisibility(View.GONE);
285122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Remove the custom view from its container.
285222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mCustomViewContainer.removeView(mCustomView);
285322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mCustomView = null;
285422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Reset the old menu state.
285522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mMenuState = mOldMenuState;
285622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mOldMenuState = EMPTY_MENU;
285722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mCustomViewContainer.setVisibility(View.GONE);
285822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mCustomViewCallback.onCustomViewHidden();
285922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Show the content view.
2860163ab74e2f85b53a1a374c49677073fb64d35f28Andrei Popescu        setStatusBarVisibility(true);
286122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mContentView.setVisibility(View.VISIBLE);
286222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
2863540035dfd1347c78eeec10ec0847e18fcc50ef36Andrei Popescu
286422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    Bitmap getDefaultVideoPoster() {
286522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mDefaultVideoPoster == null) {
286622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mDefaultVideoPoster = BitmapFactory.decodeResource(
286722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    getResources(), R.drawable.default_video_poster);
2868540035dfd1347c78eeec10ec0847e18fcc50ef36Andrei Popescu        }
286922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return mDefaultVideoPoster;
287022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
2871540035dfd1347c78eeec10ec0847e18fcc50ef36Andrei Popescu
287222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    View getVideoLoadingProgressView() {
287322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mVideoProgressView == null) {
287422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            LayoutInflater inflater = LayoutInflater.from(BrowserActivity.this);
287522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mVideoProgressView = inflater.inflate(
287622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    R.layout.video_loading_progress, null);
2877540035dfd1347c78eeec10ec0847e18fcc50ef36Andrei Popescu        }
287822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return mVideoProgressView;
287922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
28800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
28818d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins    /*
28828d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins     * The Object used to inform the WebView of the file to upload.
28838d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins     */
28848d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins    private ValueCallback<Uri> mUploadMessage;
288562b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch    private String mCameraFilePath;
288662b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch
288762b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch    void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType) {
288862b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch
288962b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch        final String imageMimeType = "image/*";
28906af492aeddda96c749142885e3b49455aa336309Ben Murdoch        final String videoMimeType = "video/*";
2891b50d7403816f316fdcaf5b5a318383e64f1a8775Ben Murdoch        final String mediaSourceKey = "capture";
28926af492aeddda96c749142885e3b49455aa336309Ben Murdoch        final String mediaSourceValueCamera = "camera";
2893b50d7403816f316fdcaf5b5a318383e64f1a8775Ben Murdoch        final String mediaSourceValueFileSystem = "filesystem";
28946af492aeddda96c749142885e3b49455aa336309Ben Murdoch        final String mediaSourceValueCamcorder = "camcorder";
289562b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch
28966af492aeddda96c749142885e3b49455aa336309Ben Murdoch        // media source can be 'gallery' or 'camera' or 'camcorder'
28976af492aeddda96c749142885e3b49455aa336309Ben Murdoch        String mediaSource = "";
289862b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch
28996af492aeddda96c749142885e3b49455aa336309Ben Murdoch        // We add the camera intent if there was no accept type (or '*/*' or 'image/*').
290062b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch        boolean addCameraIntent = true;
29016af492aeddda96c749142885e3b49455aa336309Ben Murdoch        // We add the camcorder intent if there was no accept type (or '*/*' or 'video/*').
29026af492aeddda96c749142885e3b49455aa336309Ben Murdoch        boolean addCamcorderIntent = true;
29036af492aeddda96c749142885e3b49455aa336309Ben Murdoch
29046af492aeddda96c749142885e3b49455aa336309Ben Murdoch        if (mUploadMessage != null) {
29056af492aeddda96c749142885e3b49455aa336309Ben Murdoch            // Already a file picker operation in progress.
29066af492aeddda96c749142885e3b49455aa336309Ben Murdoch            return;
29076af492aeddda96c749142885e3b49455aa336309Ben Murdoch        }
29088d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins
290922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mUploadMessage = uploadMsg;
291062b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch
291162b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch        // Parse the accept type.
291262b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch        String params[] = acceptType.split(";");
291362b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch        String mimeType = params[0];
291462b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch
291562b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch        for (String p : params) {
291662b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch            String[] keyValue = p.split("=");
291762b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch            if (keyValue.length == 2) {
291862b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch                // Process key=value parameters.
29196af492aeddda96c749142885e3b49455aa336309Ben Murdoch                if (mediaSourceKey.equals(keyValue[0])) {
29206af492aeddda96c749142885e3b49455aa336309Ben Murdoch                    mediaSource = keyValue[1];
292162b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch                }
292262b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch            }
292362b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch        }
292462b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch
292562b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch        // This intent will display the standard OPENABLE file picker.
292622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        Intent i = new Intent(Intent.ACTION_GET_CONTENT);
292722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        i.addCategory(Intent.CATEGORY_OPENABLE);
292862b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch
292962b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch        // Create an intent to add to the standard file picker that will
293062b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch        // capture an image from the camera. We'll combine this intent with
293162b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch        // the standard OPENABLE picker unless the web developer specifically
293262b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch        // requested the camera or gallery be opened by passing a parameter
293362b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch        // in the accept type.
293462b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch        Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
293562b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch        File externalDataDir = Environment.getExternalStoragePublicDirectory(
293662b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch                Environment.DIRECTORY_DCIM);
293762b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch        File cameraDataDir = new File(externalDataDir.getAbsolutePath() +
293862b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch                File.separator + "browser-photos");
293962b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch        cameraDataDir.mkdirs();
294062b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch        mCameraFilePath = cameraDataDir.getAbsolutePath() + File.separator +
294162b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch                System.currentTimeMillis() + ".jpg";
294262b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch        cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(new File(mCameraFilePath)));
294362b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch
29446af492aeddda96c749142885e3b49455aa336309Ben Murdoch        Intent camcorderIntent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
29456af492aeddda96c749142885e3b49455aa336309Ben Murdoch
294662b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch        if (mimeType.equals(imageMimeType)) {
294762b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch            i.setType(imageMimeType);
29486af492aeddda96c749142885e3b49455aa336309Ben Murdoch            addCamcorderIntent = false;
29496af492aeddda96c749142885e3b49455aa336309Ben Murdoch            if (mediaSource.equals(mediaSourceValueCamera)) {
295062b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch                // Specified 'image/*' and requested the camera, so go ahead and launch the camera
295162b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch                // directly.
295262b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch                BrowserActivity.this.startActivityForResult(cameraIntent, FILE_SELECTED);
295362b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch                return;
2954b50d7403816f316fdcaf5b5a318383e64f1a8775Ben Murdoch            } else if (mediaSource.equals(mediaSourceValueFileSystem)) {
2955b50d7403816f316fdcaf5b5a318383e64f1a8775Ben Murdoch                // Specified filesytem as the source, so don't want to consider the camera.
295662b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch                addCameraIntent = false;
295762b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch            }
29586af492aeddda96c749142885e3b49455aa336309Ben Murdoch        } else if (mimeType.equals(videoMimeType)) {
29596af492aeddda96c749142885e3b49455aa336309Ben Murdoch            i.setType(videoMimeType);
29606af492aeddda96c749142885e3b49455aa336309Ben Murdoch            addCameraIntent = false;
29616af492aeddda96c749142885e3b49455aa336309Ben Murdoch            // The camcorder saves it's own file and returns it to us in the intent, so
29626af492aeddda96c749142885e3b49455aa336309Ben Murdoch            // we don't need to generate one here.
29636af492aeddda96c749142885e3b49455aa336309Ben Murdoch            mCameraFilePath = null;
29646af492aeddda96c749142885e3b49455aa336309Ben Murdoch
29656af492aeddda96c749142885e3b49455aa336309Ben Murdoch            if (mediaSource.equals(mediaSourceValueCamcorder)) {
29666af492aeddda96c749142885e3b49455aa336309Ben Murdoch                // Specified 'video/*' and requested the camcorder, so go ahead and launch the camcorder
29676af492aeddda96c749142885e3b49455aa336309Ben Murdoch                // directly.
29686af492aeddda96c749142885e3b49455aa336309Ben Murdoch                BrowserActivity.this.startActivityForResult(camcorderIntent, FILE_SELECTED);
29696af492aeddda96c749142885e3b49455aa336309Ben Murdoch                return;
2970b50d7403816f316fdcaf5b5a318383e64f1a8775Ben Murdoch            } else if (mediaSource.equals(mediaSourceValueFileSystem)) {
2971b50d7403816f316fdcaf5b5a318383e64f1a8775Ben Murdoch                // Specified filesystem as the source, so don't want to consider the camcorder.
29726af492aeddda96c749142885e3b49455aa336309Ben Murdoch                addCamcorderIntent = false;
29736af492aeddda96c749142885e3b49455aa336309Ben Murdoch            }
297462b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch        } else {
297562b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch            i.setType("*/*");
297662b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch        }
297762b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch
29786af492aeddda96c749142885e3b49455aa336309Ben Murdoch        // Combine the chooser and the extra choices (like camera or camcorder)
297962b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch        Intent chooser = new Intent(Intent.ACTION_CHOOSER);
298062b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch        chooser.putExtra(Intent.EXTRA_INTENT, i);
298162b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch
29826af492aeddda96c749142885e3b49455aa336309Ben Murdoch        Vector<Intent> extraInitialIntents = new Vector<Intent>(0);
29836af492aeddda96c749142885e3b49455aa336309Ben Murdoch
298462b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch        if (addCameraIntent) {
29856af492aeddda96c749142885e3b49455aa336309Ben Murdoch            extraInitialIntents.add(cameraIntent);
29866af492aeddda96c749142885e3b49455aa336309Ben Murdoch        }
29876af492aeddda96c749142885e3b49455aa336309Ben Murdoch
29886af492aeddda96c749142885e3b49455aa336309Ben Murdoch        if (addCamcorderIntent) {
29896af492aeddda96c749142885e3b49455aa336309Ben Murdoch            extraInitialIntents.add(camcorderIntent);
29906af492aeddda96c749142885e3b49455aa336309Ben Murdoch        }
29916af492aeddda96c749142885e3b49455aa336309Ben Murdoch
29926af492aeddda96c749142885e3b49455aa336309Ben Murdoch        if (extraInitialIntents.size() > 0) {
29936af492aeddda96c749142885e3b49455aa336309Ben Murdoch            Intent[] extraIntents = new Intent[extraInitialIntents.size()];
29946af492aeddda96c749142885e3b49455aa336309Ben Murdoch            chooser.putExtra(Intent.EXTRA_INITIAL_INTENTS, extraInitialIntents.toArray(extraIntents));
299562b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch        }
299662b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch
299762b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch        chooser.putExtra(Intent.EXTRA_TITLE, getString(R.string.choose_upload));
299862b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch        BrowserActivity.this.startActivityForResult(chooser, FILE_SELECTED);
299922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
300022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
300122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // -------------------------------------------------------------------------
300222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // Implement functions for DownloadListener
300322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // -------------------------------------------------------------------------
300422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
30050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
30060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Notify the host application a download should be done, or that
30070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * the data should be streamed if a streaming viewer is available.
30080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param url The full url to the content that should be downloaded
30090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param contentDisposition Content-disposition http header, if
30100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *                           present.
30110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param mimetype The mimetype of the content reported by the server
30120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param contentLength The file size reported by the server
30130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
30140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public void onDownloadStart(String url, String userAgent,
30150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            String contentDisposition, String mimetype, long contentLength) {
30160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // if we're dealing wih A/V content that's not explicitly marked
30170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        //     for download, check if it's streamable.
30180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (contentDisposition == null
3019e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                || !contentDisposition.regionMatches(
3020e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                        true, 0, "attachment", 0, 10)) {
30210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // query the package manager to see if there's a registered handler
30220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            //     that matches.
30230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Intent intent = new Intent(Intent.ACTION_VIEW);
30240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            intent.setDataAndType(Uri.parse(url), mimetype);
3025e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott            ResolveInfo info = getPackageManager().resolveActivity(intent,
3026e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                    PackageManager.MATCH_DEFAULT_ONLY);
3027e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott            if (info != null) {
3028e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                ComponentName myName = getComponentName();
3029e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                // If we resolved to ourselves, we don't want to attempt to
3030e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                // load the url only to try and download it again.
3031e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                if (!myName.getPackageName().equals(
3032e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                        info.activityInfo.packageName)
3033e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                        || !myName.getClassName().equals(
3034e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                                info.activityInfo.name)) {
3035e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                    // someone (other than us) knows how to handle this mime
3036e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                    // type with this scheme, don't download.
3037e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                    try {
3038e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                        startActivity(intent);
3039e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                        return;
3040e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                    } catch (ActivityNotFoundException ex) {
3041e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                        if (LOGD_ENABLED) {
3042e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                            Log.d(LOGTAG, "activity not found for " + mimetype
3043e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                                    + " over " + Uri.parse(url).getScheme(),
3044e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                                    ex);
3045e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                        }
3046e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                        // Best behavior is to fall back to a download in this
3047e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                        // case
30480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
30490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
30500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
30510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
30520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        onDownloadStartNoStream(url, userAgent, contentDisposition, mimetype, contentLength);
30530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
30540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
3055fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen    // This is to work around the fact that java.net.URI throws Exceptions
3056fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen    // instead of just encoding URL's properly
3057fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen    // Helper method for onDownloadStartNoStream
3058fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen    private static String encodePath(String path) {
3059fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen        char[] chars = path.toCharArray();
3060fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen
3061fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen        boolean needed = false;
3062fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen        for (char c : chars) {
3063fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen            if (c == '[' || c == ']') {
3064fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen                needed = true;
3065fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen                break;
3066fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen            }
3067fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen        }
3068fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen        if (needed == false) {
3069fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen            return path;
3070fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen        }
3071fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen
3072fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen        StringBuilder sb = new StringBuilder("");
3073fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen        for (char c : chars) {
3074fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen            if (c == '[' || c == ']') {
3075fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen                sb.append('%');
3076fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen                sb.append(Integer.toHexString(c));
3077fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen            } else {
3078fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen                sb.append(c);
3079fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen            }
3080fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen        }
3081fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen
3082fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen        return sb.toString();
3083fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen    }
3084fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen
30850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
30860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Notify the host application a download should be done, even if there
30870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * is a streaming viewer available for thise type.
30880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param url The full url to the content that should be downloaded
30890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param contentDisposition Content-disposition http header, if
30900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *                           present.
30910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param mimetype The mimetype of the content reported by the server
30920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param contentLength The file size reported by the server
30930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
30940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /*package */ void onDownloadStartNoStream(String url, String userAgent,
30950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            String contentDisposition, String mimetype, long contentLength) {
30960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
30970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String filename = URLUtil.guessFileName(url,
30980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                contentDisposition, mimetype);
30990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
31000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Check to see if we have an SDCard
31010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String status = Environment.getExternalStorageState();
31020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (!status.equals(Environment.MEDIA_MOUNTED)) {
31030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            int title;
31040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            String msg;
31050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
31060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Check to see if the SDCard is busy, same as the music app
31070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (status.equals(Environment.MEDIA_SHARED)) {
31080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                msg = getString(R.string.download_sdcard_busy_dlg_msg);
31090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                title = R.string.download_sdcard_busy_dlg_title;
31100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } else {
31110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                msg = getString(R.string.download_no_sdcard_dlg_msg, filename);
31120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                title = R.string.download_no_sdcard_dlg_title;
31130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
31140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
31150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            new AlertDialog.Builder(this)
31160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setTitle(title)
31170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setIcon(android.R.drawable.ic_dialog_alert)
31180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setMessage(msg)
31190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setPositiveButton(R.string.ok, null)
31200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .show();
31210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
31220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
31230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
3124fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen        // java.net.URI is a lot stricter than KURL so we have to encode some
3125fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen        // extra characters. Fix for b 2538060 and b 1634719
3126fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen        WebAddress webAddress;
31270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        try {
3128fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen            webAddress = new WebAddress(url);
3129fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen            webAddress.mPath = encodePath(webAddress.mPath);
31300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } catch (Exception e) {
3131fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen            // This only happens for very bad urls, we want to chatch the
3132fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen            // exception here
3133fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen            Log.e(LOGTAG, "Exception trying to parse url:" + url);
31340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
31350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
31360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
31370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // XXX: Have to use the old url since the cookies were stored using the
31380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // old percent-encoded url.
31390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String cookies = CookieManager.getInstance().getCookie(url);
31400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
31410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        ContentValues values = new ContentValues();
3142fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen        values.put(Downloads.Impl.COLUMN_URI, webAddress.toString());
31431e5bad97ca8fb9b12501f4f747941d02f03e1362Jean-Baptiste Queru        values.put(Downloads.Impl.COLUMN_COOKIE_DATA, cookies);
31441e5bad97ca8fb9b12501f4f747941d02f03e1362Jean-Baptiste Queru        values.put(Downloads.Impl.COLUMN_USER_AGENT, userAgent);
31451e5bad97ca8fb9b12501f4f747941d02f03e1362Jean-Baptiste Queru        values.put(Downloads.Impl.COLUMN_NOTIFICATION_PACKAGE,
31460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                getPackageName());
31471e5bad97ca8fb9b12501f4f747941d02f03e1362Jean-Baptiste Queru        values.put(Downloads.Impl.COLUMN_NOTIFICATION_CLASS,
3148a563d09392905140893d7a017dd63721577e1953Leon Scroggins                OpenDownloadReceiver.class.getCanonicalName());
31491e5bad97ca8fb9b12501f4f747941d02f03e1362Jean-Baptiste Queru        values.put(Downloads.Impl.COLUMN_VISIBILITY,
31501e5bad97ca8fb9b12501f4f747941d02f03e1362Jean-Baptiste Queru                Downloads.Impl.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
31511e5bad97ca8fb9b12501f4f747941d02f03e1362Jean-Baptiste Queru        values.put(Downloads.Impl.COLUMN_MIME_TYPE, mimetype);
31521e5bad97ca8fb9b12501f4f747941d02f03e1362Jean-Baptiste Queru        values.put(Downloads.Impl.COLUMN_FILE_NAME_HINT, filename);
3153fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen        values.put(Downloads.Impl.COLUMN_DESCRIPTION, webAddress.mHost);
31540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (contentLength > 0) {
31551e5bad97ca8fb9b12501f4f747941d02f03e1362Jean-Baptiste Queru            values.put(Downloads.Impl.COLUMN_TOTAL_BYTES, contentLength);
31560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
31570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mimetype == null) {
31580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // We must have long pressed on a link or image to download it. We
31590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // are not sure of the mimetype in this case, so do a head request
31600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            new FetchUrlMimeType(this).execute(values);
31610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
31620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            final Uri contentUri =
31631e5bad97ca8fb9b12501f4f747941d02f03e1362Jean-Baptiste Queru                    getContentResolver().insert(Downloads.Impl.CONTENT_URI, values);
31640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
31659191a7f745c965cf57df94d0628890b413c710c9Leon Scroggins        Toast.makeText(this, R.string.download_pending, Toast.LENGTH_SHORT)
31669191a7f745c965cf57df94d0628890b413c710c9Leon Scroggins                .show();
31670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
31680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
316922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // -------------------------------------------------------------------------
317022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
31710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
31720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Resets the lock icon. This method is called when we start a new load and
31730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * know the url to be loaded.
31740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
31750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void resetLockIcon(String url) {
31760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Save the lock-icon state (we revert to it if the load gets cancelled)
317722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mTabControl.getCurrentTab().resetLockIcon(url);
31780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        updateLockIconImage(LOCK_ICON_UNSECURE);
31790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
31800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
31810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
31823bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     * Update the lock icon to correspond to our latest state.
31833bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     */
318422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private void updateLockIconToLatest() {
318591f65fccfd6feae560a42abdd3385ca3318f0430Leon Scroggins        Tab t = mTabControl.getCurrentTab();
318691f65fccfd6feae560a42abdd3385ca3318f0430Leon Scroggins        if (t != null) {
318791f65fccfd6feae560a42abdd3385ca3318f0430Leon Scroggins            updateLockIconImage(t.getLockIconType());
318891f65fccfd6feae560a42abdd3385ca3318f0430Leon Scroggins        }
31893bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    }
31903bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins
31913bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    /**
31920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Updates the lock-icon image in the title-bar.
31930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
31940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void updateLockIconImage(int lockIconType) {
31950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        Drawable d = null;
31960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (lockIconType == LOCK_ICON_SECURE) {
31970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            d = mSecLockIcon;
31980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else if (lockIconType == LOCK_ICON_MIXED) {
31990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            d = mMixLockIcon;
32000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
320168579393973f745fc65a2781061af9bb8f2d7020Leon Scroggins        mTitleBar.setLock(d);
3202d746a94137a87ffcc1fcefdac9a3764c3bc3f5cdLeon Scroggins        if (!mXLargeScreenSize) {
3203d746a94137a87ffcc1fcefdac9a3764c3bc3f5cdLeon Scroggins            mFakeTitleBar.setLock(d);
3204d746a94137a87ffcc1fcefdac9a3764c3bc3f5cdLeon Scroggins        }
32050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
32060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
32070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
32080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Displays a page-info dialog.
32090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param tab The tab to show info about
32100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param fromShowSSLCertificateOnError The flag that indicates whether
32110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * this dialog was opened from the SSL-certificate-on-error dialog or
32120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * not. This is important, since we need to know whether to return to
32130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * the parent dialog or simply dismiss.
32140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
321522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private void showPageInfo(final Tab tab,
32160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                              final boolean fromShowSSLCertificateOnError) {
32170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final LayoutInflater factory = LayoutInflater
32180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .from(this);
32190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
32200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final View pageInfoView = factory.inflate(R.layout.page_info, null);
32210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
32220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final WebView view = tab.getWebView();
32230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
32240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String url = null;
32250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String title = null;
32260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
32270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (view == null) {
32280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            url = tab.getUrl();
32290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            title = tab.getTitle();
32300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else if (view == mTabControl.getCurrentWebView()) {
32310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project             // Use the cached title and url if this is the current WebView
32320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            url = mUrl;
32330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            title = mTitle;
32340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
32350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            url = view.getUrl();
32360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            title = view.getTitle();
32370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
32380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
32390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (url == null) {
32400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            url = "";
32410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
32420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (title == null) {
32430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            title = "";
32440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
32450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
32460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        ((TextView) pageInfoView.findViewById(R.id.address)).setText(url);
32470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        ((TextView) pageInfoView.findViewById(R.id.title)).setText(title);
32480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
32490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mPageInfoView = tab;
3250c7b92f811dfa3572578ddc6714c98a03936d9ce5Leon Scroggins        mPageInfoFromShowSSLCertificateOnError = fromShowSSLCertificateOnError;
32510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
32520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        AlertDialog.Builder alertDialogBuilder =
32530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            new AlertDialog.Builder(this)
32540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            .setTitle(R.string.page_info).setIcon(android.R.drawable.ic_dialog_info)
32550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            .setView(pageInfoView)
32560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            .setPositiveButton(
32570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                R.string.ok,
32580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                new DialogInterface.OnClickListener() {
32590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    public void onClick(DialogInterface dialog,
32600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        int whichButton) {
32610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        mPageInfoDialog = null;
32620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        mPageInfoView = null;
32630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
32640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        // if we came here from the SSL error dialog
32650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        if (fromShowSSLCertificateOnError) {
32660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            // go back to the SSL error dialog
32670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            showSSLCertificateOnError(
32680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorView,
32690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorHandler,
32700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorError);
32710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }
32720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
32730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                })
32740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            .setOnCancelListener(
32750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                new DialogInterface.OnCancelListener() {
32760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    public void onCancel(DialogInterface dialog) {
32770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        mPageInfoDialog = null;
32780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        mPageInfoView = null;
32790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
32800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        // if we came here from the SSL error dialog
32810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        if (fromShowSSLCertificateOnError) {
32820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            // go back to the SSL error dialog
32830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            showSSLCertificateOnError(
32840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorView,
32850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorHandler,
32860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorError);
32870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }
32880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
32890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                });
32900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
32910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // if we have a main top-level page SSL certificate set or a certificate
32920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // error
32930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (fromShowSSLCertificateOnError ||
32940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                (view != null && view.getCertificate() != null)) {
32950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // add a 'View Certificate' button
32960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            alertDialogBuilder.setNeutralButton(
32970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                R.string.view_certificate,
32980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                new DialogInterface.OnClickListener() {
32990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    public void onClick(DialogInterface dialog,
33000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        int whichButton) {
33010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        mPageInfoDialog = null;
33020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        mPageInfoView = null;
33030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
33040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        // if we came here from the SSL error dialog
33050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        if (fromShowSSLCertificateOnError) {
33060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            // go back to the SSL error dialog
33070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            showSSLCertificateOnError(
33080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorView,
33090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorHandler,
33100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorError);
33110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        } else {
33120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            // otherwise, display the top-most certificate from
33130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            // the chain
33140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            if (view.getCertificate() != null) {
33150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                showSSLCertificate(tab);
33160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            }
33170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }
33180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
33190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                });
33200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
33210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
33220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mPageInfoDialog = alertDialogBuilder.show();
33230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
33240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
33250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project       /**
33260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Displays the main top-level page SSL certificate dialog
33270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * (accessible from the Page-Info dialog).
33280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param tab The tab to show certificate for.
33290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
333022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private void showSSLCertificate(final Tab tab) {
33310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final View certificateView =
33320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                inflateCertificateView(tab.getWebView().getCertificate());
33330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (certificateView == null) {
33340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
33350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
33360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
33370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        LayoutInflater factory = LayoutInflater.from(this);
33380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
33390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final LinearLayout placeholder =
33400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                (LinearLayout)certificateView.findViewById(R.id.placeholder);
33410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
33420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        LinearLayout ll = (LinearLayout) factory.inflate(
33430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            R.layout.ssl_success, placeholder);
33440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        ((TextView)ll.findViewById(R.id.success))
33450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            .setText(R.string.ssl_certificate_is_valid);
33460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
33470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mSSLCertificateView = tab;
33480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mSSLCertificateDialog =
33490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            new AlertDialog.Builder(this)
33500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setTitle(R.string.ssl_certificate).setIcon(
33510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    R.drawable.ic_dialog_browser_certificate_secure)
33520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setView(certificateView)
33530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setPositiveButton(R.string.ok,
33540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new DialogInterface.OnClickListener() {
33550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            public void onClick(DialogInterface dialog,
33560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    int whichButton) {
33570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateDialog = null;
33580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateView = null;
33590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
33600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                showPageInfo(tab, false);
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                                mSSLCertificateDialog = null;
33670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateView = null;
33680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
33690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                showPageInfo(tab, false);
33700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            }
33710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        })
33720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .show();
33730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
33740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
33750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
33760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Displays the SSL error certificate dialog.
33770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param view The target web-view.
33780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param handler The SSL error handler responsible for cancelling the
33790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * connection that resulted in an SSL error or proceeding per user request.
33800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param error The SSL error object.
33810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
338222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void showSSLCertificateOnError(
33830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final WebView view, final SslErrorHandler handler, final SslError error) {
33840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
33850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final View certificateView =
33860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            inflateCertificateView(error.getCertificate());
33870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (certificateView == null) {
33880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
33890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
33900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
33910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        LayoutInflater factory = LayoutInflater.from(this);
33920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
33930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final LinearLayout placeholder =
33940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                (LinearLayout)certificateView.findViewById(R.id.placeholder);
33950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
33960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (error.hasError(SslError.SSL_UNTRUSTED)) {
33970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            LinearLayout ll = (LinearLayout)factory
33980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .inflate(R.layout.ssl_warning, placeholder);
33990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((TextView)ll.findViewById(R.id.warning))
34000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setText(R.string.ssl_untrusted);
34010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
34020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
34030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (error.hasError(SslError.SSL_IDMISMATCH)) {
34040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            LinearLayout ll = (LinearLayout)factory
34050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .inflate(R.layout.ssl_warning, placeholder);
34060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((TextView)ll.findViewById(R.id.warning))
34070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setText(R.string.ssl_mismatch);
34080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
34090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
34100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (error.hasError(SslError.SSL_EXPIRED)) {
34110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            LinearLayout ll = (LinearLayout)factory
34120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .inflate(R.layout.ssl_warning, placeholder);
34130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((TextView)ll.findViewById(R.id.warning))
34140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setText(R.string.ssl_expired);
34150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
34160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
34170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (error.hasError(SslError.SSL_NOTYETVALID)) {
34180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            LinearLayout ll = (LinearLayout)factory
34190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .inflate(R.layout.ssl_warning, placeholder);
34200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((TextView)ll.findViewById(R.id.warning))
34210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setText(R.string.ssl_not_yet_valid);
34220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
34230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
34240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mSSLCertificateOnErrorHandler = handler;
34250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mSSLCertificateOnErrorView = view;
34260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mSSLCertificateOnErrorError = error;
34270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mSSLCertificateOnErrorDialog =
34280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            new AlertDialog.Builder(this)
34290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setTitle(R.string.ssl_certificate).setIcon(
34300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    R.drawable.ic_dialog_browser_certificate_partially_secure)
34310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setView(certificateView)
34320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setPositiveButton(R.string.ok,
34330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new DialogInterface.OnClickListener() {
34340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            public void onClick(DialogInterface dialog,
34350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    int whichButton) {
34360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorDialog = null;
34370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorView = null;
34380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorHandler = null;
34390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorError = null;
34400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
344122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                view.getWebViewClient().onReceivedSslError(
344222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                                view, handler, error);
34430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            }
34440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        })
34450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                 .setNeutralButton(R.string.page_info_view,
34460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new DialogInterface.OnClickListener() {
34470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            public void onClick(DialogInterface dialog,
34480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    int whichButton) {
34490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorDialog = null;
34500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
34510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                // do not clear the dialog state: we will
34520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                // need to show the dialog again once the
34530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                // user is done exploring the page-info details
34540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
34550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                showPageInfo(mTabControl.getTabFromView(view),
34560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        true);
34570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            }
34580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        })
34590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setOnCancelListener(
34600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new DialogInterface.OnCancelListener() {
34610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            public void onCancel(DialogInterface dialog) {
34620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorDialog = null;
34630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorView = null;
34640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorHandler = null;
34650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorError = null;
34660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
346722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                view.getWebViewClient().onReceivedSslError(
346822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                                view, handler, error);
34690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            }
34700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        })
34710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .show();
34720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
34730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
34740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
34750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Inflates the SSL certificate view (helper method).
34760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param certificate The SSL certificate.
34770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @return The resultant certificate view with issued-to, issued-by,
34780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * issued-on, expires-on, and possibly other fields set.
34790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * If the input certificate is null, returns null.
34800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
34810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private View inflateCertificateView(SslCertificate certificate) {
34820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (certificate == null) {
34830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return null;
34840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
34850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
34860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        LayoutInflater factory = LayoutInflater.from(this);
34870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
34880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        View certificateView = factory.inflate(
34890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            R.layout.ssl_certificate, null);
34900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
34910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // issued to:
34920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        SslCertificate.DName issuedTo = certificate.getIssuedTo();
34930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (issuedTo != null) {
34940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((TextView) certificateView.findViewById(R.id.to_common))
34950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setText(issuedTo.getCName());
34960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((TextView) certificateView.findViewById(R.id.to_org))
34970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setText(issuedTo.getOName());
34980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((TextView) certificateView.findViewById(R.id.to_org_unit))
34990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setText(issuedTo.getUName());
35000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
35010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
35020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // issued by:
35030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        SslCertificate.DName issuedBy = certificate.getIssuedBy();
35040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (issuedBy != null) {
35050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((TextView) certificateView.findViewById(R.id.by_common))
35060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setText(issuedBy.getCName());
35070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((TextView) certificateView.findViewById(R.id.by_org))
35080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setText(issuedBy.getOName());
35090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((TextView) certificateView.findViewById(R.id.by_org_unit))
35100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setText(issuedBy.getUName());
35110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
35120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
35130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // issued on:
351495a2e4ab94514e4e41033b0d27a0e66855cff8ebBrian Carlstrom        String issuedOn = formatCertificateDate(
351595a2e4ab94514e4e41033b0d27a0e66855cff8ebBrian Carlstrom            certificate.getValidNotBeforeDate());
35160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        ((TextView) certificateView.findViewById(R.id.issued_on))
35170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            .setText(issuedOn);
35180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
35190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // expires on:
352095a2e4ab94514e4e41033b0d27a0e66855cff8ebBrian Carlstrom        String expiresOn = formatCertificateDate(
352195a2e4ab94514e4e41033b0d27a0e66855cff8ebBrian Carlstrom            certificate.getValidNotAfterDate());
35220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        ((TextView) certificateView.findViewById(R.id.expires_on))
35230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            .setText(expiresOn);
35240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
35250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return certificateView;
35260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
35270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
35280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
352995a2e4ab94514e4e41033b0d27a0e66855cff8ebBrian Carlstrom     * Formats the certificate date to a properly localized date string.
35300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @return Properly localized version of the certificate date string and
353195a2e4ab94514e4e41033b0d27a0e66855cff8ebBrian Carlstrom     * the "" if it fails to localize.
35320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
353395a2e4ab94514e4e41033b0d27a0e66855cff8ebBrian Carlstrom    private String formatCertificateDate(Date certificateDate) {
353495a2e4ab94514e4e41033b0d27a0e66855cff8ebBrian Carlstrom      if (certificateDate == null) {
353595a2e4ab94514e4e41033b0d27a0e66855cff8ebBrian Carlstrom          return "";
35360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project      }
353795a2e4ab94514e4e41033b0d27a0e66855cff8ebBrian Carlstrom      String formattedDate = DateFormat.getDateFormat(this).format(certificateDate);
353895a2e4ab94514e4e41033b0d27a0e66855cff8ebBrian Carlstrom      if (formattedDate == null) {
353995a2e4ab94514e4e41033b0d27a0e66855cff8ebBrian Carlstrom          return "";
354095a2e4ab94514e4e41033b0d27a0e66855cff8ebBrian Carlstrom      }
354195a2e4ab94514e4e41033b0d27a0e66855cff8ebBrian Carlstrom      return formattedDate;
35420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
35430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
35440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
35450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Displays an http-authentication dialog.
35460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
354722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void showHttpAuthentication(final HttpAuthHandler handler,
35480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            final String host, final String realm, final String title,
35490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            final String name, final String password, int focusId) {
35500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        LayoutInflater factory = LayoutInflater.from(this);
35510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final View v = factory
35520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .inflate(R.layout.http_authentication, null);
35530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (name != null) {
35540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((EditText) v.findViewById(R.id.username_edit)).setText(name);
35550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
35560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (password != null) {
35570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((EditText) v.findViewById(R.id.password_edit)).setText(password);
35580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
35590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
35600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String titleText = title;
35610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (titleText == null) {
35620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            titleText = getText(R.string.sign_in_to).toString().replace(
35630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    "%s1", host).replace("%s2", realm);
35640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
35650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
35660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mHttpAuthHandler = handler;
35670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        AlertDialog dialog = new AlertDialog.Builder(this)
35680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setTitle(titleText)
35690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setIcon(android.R.drawable.ic_dialog_alert)
35700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setView(v)
35710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setPositiveButton(R.string.action,
35720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new DialogInterface.OnClickListener() {
35730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                             public void onClick(DialogInterface dialog,
35740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                     int whichButton) {
35750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                String nm = ((EditText) v
35760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        .findViewById(R.id.username_edit))
35770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        .getText().toString();
35780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                String pw = ((EditText) v
35790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        .findViewById(R.id.password_edit))
35800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        .getText().toString();
35810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                BrowserActivity.this.setHttpAuthUsernamePassword
35820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        (host, realm, nm, pw);
35830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                handler.proceed(nm, pw);
35840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mHttpAuthenticationDialog = null;
35850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mHttpAuthHandler = null;
35860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            }})
35870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setNegativeButton(R.string.cancel,
35880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new DialogInterface.OnClickListener() {
35890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            public void onClick(DialogInterface dialog,
35900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    int whichButton) {
35910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                handler.cancel();
35920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                BrowserActivity.this.resetTitleAndRevertLockIcon();
35930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mHttpAuthenticationDialog = null;
35940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mHttpAuthHandler = null;
35950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            }})
35960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setOnCancelListener(new DialogInterface.OnCancelListener() {
35970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        public void onCancel(DialogInterface dialog) {
35980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            handler.cancel();
35990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            BrowserActivity.this.resetTitleAndRevertLockIcon();
36000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            mHttpAuthenticationDialog = null;
36010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            mHttpAuthHandler = null;
36020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }})
36030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .create();
36040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Make the IME appear when the dialog is displayed if applicable.
36050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        dialog.getWindow().setSoftInputMode(
36060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);
36070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        dialog.show();
36080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (focusId != 0) {
36090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            dialog.findViewById(focusId).requestFocus();
36100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
36110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            v.findViewById(R.id.username_edit).requestFocus();
36120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
36130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mHttpAuthenticationDialog = dialog;
36140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
36150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
36160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public int getProgress() {
36170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebView w = mTabControl.getCurrentWebView();
36180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (w != null) {
36190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return w.getProgress();
36200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
36210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return 100;
36220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
36230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
36240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
36250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
36260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Set HTTP authentication password.
36270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *
36280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param host The host for the password
36290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param realm The realm for the password
36300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param username The username for the password. If it is null, it means
36310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *            password can't be saved.
36320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param password The password
36330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
36340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public void setHttpAuthUsernamePassword(String host, String realm,
36350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                            String username,
36360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                            String password) {
363795a53b25504f12c3a5f8ecbbfcff7ac1dc047e4fSteve Block        WebView w = getTopWindow();
36380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (w != null) {
36390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            w.setHttpAuthUsernamePassword(host, realm, username, password);
36400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
36410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
36420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
36430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
36440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * connectivity manager says net has come or gone... inform the user
36450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param up true if net has come up, false if net has gone down
36460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
36470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public void onNetworkToggle(boolean up) {
36480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (up == mIsNetworkUp) {
36490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
36500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else if (up) {
36510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mIsNetworkUp = true;
36520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (mAlertDialog != null) {
36530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mAlertDialog.cancel();
36540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mAlertDialog = null;
36550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
36560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
36570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mIsNetworkUp = false;
3658eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott            if (mInLoad) {
3659eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott                createAndShowNetworkDialog();
3660eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott           }
36610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
36620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebView w = mTabControl.getCurrentWebView();
36630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (w != null) {
36640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            w.setNetworkAvailable(up);
36650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
36660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
36670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
366822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    boolean isNetworkUp() {
366922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return mIsNetworkUp;
367022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
367122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
3672eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott    // This method shows the network dialog alerting the user that the net is
3673eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott    // down. It will only show the dialog if mAlertDialog is null.
3674eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott    private void createAndShowNetworkDialog() {
3675eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott        if (mAlertDialog == null) {
3676eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott            mAlertDialog = new AlertDialog.Builder(this)
3677eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott                    .setTitle(R.string.loadSuspendedTitle)
3678eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott                    .setMessage(R.string.loadSuspended)
3679eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott                    .setPositiveButton(R.string.ok, null)
3680eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott                    .show();
3681eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott        }
3682eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott    }
3683eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott
36840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    @Override
36850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    protected void onActivityResult(int requestCode, int resultCode,
36860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    Intent intent) {
3687bb394f3e134b6e5898ef7ae861b75e95e618688fGrace Kloba        if (getTopWindow() == null) return;
3688bb394f3e134b6e5898ef7ae861b75e95e618688fGrace Kloba
36890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        switch (requestCode) {
36900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case COMBO_PAGE:
36910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (resultCode == RESULT_OK && intent != null) {
36920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    String data = intent.getAction();
36930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    Bundle extras = intent.getExtras();
36940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    if (extras != null && extras.getBoolean("new_window", false)) {
369525d3547e0df084f963e38c6a93c99b02bd619de3Leon Scroggins                        openTab(data);
36960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    } else {
369722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        final Tab currentTab =
36980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mTabControl.getCurrentTab();
36991f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                        dismissSubWindow(currentTab);
37001f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                        if (data != null && data.length() != 0) {
370192472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins                            loadUrl(getTopWindow(), data);
37020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }
37030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
37040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
3705fde9746ac3055848e110c35f19ec5893c621f766Leon Scroggins                // Deliberately fall through to PREFERENCES_PAGE, since the
3706fde9746ac3055848e110c35f19ec5893c621f766Leon Scroggins                // same extra may be attached to the COMBO_PAGE
3707fde9746ac3055848e110c35f19ec5893c621f766Leon Scroggins            case PREFERENCES_PAGE:
3708fde9746ac3055848e110c35f19ec5893c621f766Leon Scroggins                if (resultCode == RESULT_OK && intent != null) {
3709fde9746ac3055848e110c35f19ec5893c621f766Leon Scroggins                    String action = intent.getStringExtra(Intent.EXTRA_TEXT);
3710fde9746ac3055848e110c35f19ec5893c621f766Leon Scroggins                    if (BrowserSettings.PREF_CLEAR_HISTORY.equals(action)) {
3711fde9746ac3055848e110c35f19ec5893c621f766Leon Scroggins                        mTabControl.removeParentChildRelationShips();
3712fde9746ac3055848e110c35f19ec5893c621f766Leon Scroggins                    }
3713fde9746ac3055848e110c35f19ec5893c621f766Leon Scroggins                }
37140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
37158d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins            // Choose a file from the file picker.
37168d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins            case FILE_SELECTED:
37178d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins                if (null == mUploadMessage) break;
37188d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins                Uri result = intent == null || resultCode != RESULT_OK ? null
37198d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins                        : intent.getData();
372062b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch
372162b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch                // As we ask the camera to save the result of the user taking
372262b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch                // a picture, the camera application does not return anything other
372362b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch                // than RESULT_OK. So we need to check whether the file we expected
372462b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch                // was written to disk in the in the case that we
372562b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch                // did not get an intent returned but did get a RESULT_OK. If it was,
372662b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch                // we assume that this result has came back from the camera.
372762b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch                if (result == null && intent == null && resultCode == RESULT_OK) {
372862b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch                    File cameraFile = new File(mCameraFilePath);
372962b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch                    if (cameraFile.exists()) {
373062b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch                        result = Uri.fromFile(cameraFile);
373107d3473804cdfd646b39001ca80ebf530e8f8749Ben Murdoch                        // Broadcast to the media scanner that we have a new photo
373207d3473804cdfd646b39001ca80ebf530e8f8749Ben Murdoch                        // so it will be added into the gallery for the user.
373307d3473804cdfd646b39001ca80ebf530e8f8749Ben Murdoch                        sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, result));
373462b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch                    }
373562b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch                }
37368d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins                mUploadMessage.onReceiveValue(result);
37378d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins                mUploadMessage = null;
373862b1b7ef20a1c9f4c6e6f7b73140701b3c6193c5Ben Murdoch                mCameraFilePath = null;
37398d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins                break;
37400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            default:
37410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
37420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
3743304442375719effd41dbd53ae62de7a8d0cec7d9Leon Scroggins        getTopWindow().requestFocus();
37440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
37450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
37460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /*
37470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * This method is called as a result of the user selecting the options
3748f08809b2cf7e502fef5965691a7fb6d7cf0322afLeon Scroggins     * menu to see the download window. It shows the download window on top of
3749f08809b2cf7e502fef5965691a7fb6d7cf0322afLeon Scroggins     * the current window.
37500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
3751f08809b2cf7e502fef5965691a7fb6d7cf0322afLeon Scroggins    private void viewDownloads(Uri downloadRecord) {
37520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        Intent intent = new Intent(this,
37530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                BrowserDownloadPage.class);
37540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        intent.setData(downloadRecord);
375522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        startActivityForResult(intent, BrowserActivity.DOWNLOAD_PAGE);
37560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
37570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
37580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
3759eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch    /* package*/ void promptAddOrInstallBookmark() {
3760eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch        final Tab current = mTabControl.getCurrentTab();
3761eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch        Resources resources = getResources();
3762eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch        CharSequence[] choices = {
3763eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch                resources.getString(R.string.save_to_bookmarks),
3764eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch                resources.getString(R.string.create_shortcut_bookmark)
3765eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch        };
3766eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch
3767eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch        AlertDialog.Builder builder = new AlertDialog.Builder(this);
3768eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch        builder.setTitle(R.string.add_new_bookmark);
3769eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch        builder.setItems(choices, new DialogInterface.OnClickListener() {
3770eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch                public void onClick(DialogInterface dialog, int item) {
3771eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch                    if (item == 0) {
3772eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch                        bookmarkCurrentPage();
3773eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch                    } else if (item == 1) {
3774eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch                        current.populatePickerData();
3775eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch                        String touchIconUrl = mTabControl.getCurrentWebView().getTouchIconUrl();
3776eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch                        if (touchIconUrl != null) {
3777eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch                            // Download the touch icon for this site then save it to the
3778eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch                            // homescreen.
3779eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch                            Bundle b = new Bundle();
3780eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch                            b.putString("url", current.getUrl());
3781eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch                            b.putString("title", current.getTitle());
3782eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch                            b.putParcelable("favicon", current.getFavicon());
3783eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch                            Message msg = mHandler.obtainMessage(TOUCH_ICON_DOWNLOADED);
3784eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch                            msg.setData(b);
3785ccb5de06714993c28d16f1e5abfcd9f0b1e656fcBen Murdoch                            new DownloadTouchIcon(BrowserActivity.this, msg,
3786eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch                                    mTabControl.getCurrentWebView().getSettings()
3787eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch                                    .getUserAgentString()).execute(touchIconUrl);
3788eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch                        } else {
3789eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch                            // add to homescreen, can do it immediately as there is no touch
3790eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch                            // icon.
3791eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch                            showSaveToHomescreenDialog(current.getUrl(), current.getTitle(),
3792eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch                                    null, current.getFavicon());
3793eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch                        }
3794eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch                     }
3795eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch                 }
3796eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch        });
3797eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch        builder.create().show();
3798eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch    }
3799eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch
3800160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins    /**
3801160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins     * Open the Go page.
3802160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins     * @param startWithHistory If true, open starting on the history tab.
3803160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins     *                         Otherwise, start with the bookmarks tab.
3804160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins     */
3805304442375719effd41dbd53ae62de7a8d0cec7d9Leon Scroggins    /* package */ void bookmarksOrHistoryPicker(boolean startWithHistory) {
38060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebView current = mTabControl.getCurrentWebView();
38070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (current == null) {
38080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
38090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
38100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        Intent intent = new Intent(this,
38110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                CombinedBookmarkHistoryActivity.class);
38120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String title = current.getTitle();
38130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String url = current.getUrl();
381487cc65d95c80c5e3a1c343ad5177a7dc2de874f6Ben Murdoch        Bitmap thumbnail = createScreenshot(current, getDesiredThumbnailWidth(this),
381587cc65d95c80c5e3a1c343ad5177a7dc2de874f6Ben Murdoch                getDesiredThumbnailHeight(this));
3816dcc2b6f08dd5677bc6ba761a9ba6f1c655113051Ben Murdoch
38170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Just in case the user opens bookmarks before a page finishes loading
38180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // so the current history item, and therefore the page, is null.
38190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (null == url) {
38200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            url = mLastEnteredUrl;
38210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // This can happen.
38220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (null == url) {
38230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                url = mSettings.getHomePage();
38240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
38250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
38260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // In case the web page has not yet received its associated title.
38270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (title == null) {
38280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            title = url;
38290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
38300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        intent.putExtra("title", title);
38310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        intent.putExtra("url", url);
3832dcc2b6f08dd5677bc6ba761a9ba6f1c655113051Ben Murdoch        intent.putExtra("thumbnail", thumbnail);
3833304442375719effd41dbd53ae62de7a8d0cec7d9Leon Scroggins        // Disable opening in a new window if we have maxed out the windows
383422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        intent.putExtra("disable_new_window", !mTabControl.canCreateNewTab());
38353918d4443ff38ef1870e02aa51a8b29f8352bb1aPatrick Scott        intent.putExtra("touch_icon_url", current.getTouchIconUrl());
38360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (startWithHistory) {
38370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            intent.putExtra(CombinedBookmarkHistoryActivity.STARTING_TAB,
38380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    CombinedBookmarkHistoryActivity.HISTORY_TAB);
38390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
38400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        startActivityForResult(intent, COMBO_PAGE);
38410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
38420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
3843eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch    private void showSaveToHomescreenDialog(String url, String title, Bitmap touchIcon,
3844eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch            Bitmap favicon) {
3845eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch        Intent intent = new Intent(this, SaveToHomescreenDialog.class);
3846eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch
3847eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch        // Just in case the user tries to save before a page finishes loading
3848eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch        // so the current history item, and therefore the page, is null.
3849eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch        if (null == url) {
3850eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch            url = mLastEnteredUrl;
3851eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch            // This can happen.
3852eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch            if (null == url) {
3853eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch                url = mSettings.getHomePage();
3854eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch            }
3855eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch        }
3856eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch
3857eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch        // In case the web page has not yet received its associated title.
3858eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch        if (title == null) {
3859eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch            title = url;
3860eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch        }
3861eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch
3862eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch        intent.putExtra("title", title);
3863eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch        intent.putExtra("url", url);
3864eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch        intent.putExtra("favicon", favicon);
3865eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch        intent.putExtra("touchIcon", touchIcon);
3866eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch        startActivity(intent);
3867eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch    }
3868eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch
3869eecb4e6cb64af03aad3f9facdbf6fd7190091b41Ben Murdoch
38700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Called when loading from context menu or LOAD_URL message
387192472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins    private void loadUrlFromContext(WebView view, String url) {
38720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // In case the user enters nothing.
38730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (url != null && url.length() != 0 && view != null) {
38740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            url = smartUrlFilter(url);
387522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (!view.getWebViewClient().shouldOverrideUrlLoading(view, url)) {
387692472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins                loadUrl(view, url);
38770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
38780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
38790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
38800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
388192472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins    /**
388292472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins     * Load the URL into the given WebView and update the title bar
388392472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins     * to reflect the new load.  Call this instead of WebView.loadUrl
388492472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins     * directly.
388592472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins     * @param view The WebView used to load url.
388692472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins     * @param url The URL to load.
388792472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins     */
388892472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins    private void loadUrl(WebView view, String url) {
388992472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins        updateTitleBarForNewLoad(view, url);
389092472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins        view.loadUrl(url);
389192472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins    }
389292472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins
389392472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins    /**
389492472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins     * Load UrlData into a Tab and update the title bar to reflect the new
389592472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins     * load.  Call this instead of UrlData.loadIn directly.
389692472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins     * @param t The Tab used to load.
389792472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins     * @param data The UrlData being loaded.
389892472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins     */
389992472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins    private void loadUrlDataIn(Tab t, UrlData data) {
390092472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins        updateTitleBarForNewLoad(t.getWebView(), data.mUrl);
390192472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins        data.loadIn(t);
390292472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins    }
390392472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins
390492472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins    /**
390592472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins     * If the WebView is the top window, update the title bar to reflect
390692472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins     * loading the new URL.  i.e. set its text, clear the favicon (which
390792472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins     * will be set once the page begins loading), and set the progress to
390892472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins     * INITIAL_PROGRESS to show that the page has begun to load. Called
390992472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins     * by loadUrl and loadUrlDataIn.
391092472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins     * @param view The WebView that is starting a load.
391192472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins     * @param url The URL that is being loaded.
391292472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins     */
391392472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins    private void updateTitleBarForNewLoad(WebView view, String url) {
391492472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins        if (view == getTopWindow()) {
391592472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins            setUrlTitle(url, null);
391692472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins            setFavicon(null);
391792472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins            onProgressChanged(view, INITIAL_PROGRESS);
391892472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins        }
391992472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins    }
392092472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins
39210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private String smartUrlFilter(Uri inUri) {
39220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (inUri != null) {
39230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return smartUrlFilter(inUri.toString());
39240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
39250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return null;
39260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
39270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
3928b34f87a2e13af13d697130482af01b537ab7c5fdFeng Qian    protected static final Pattern ACCEPTED_URI_SCHEMA = Pattern.compile(
39290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            "(?i)" + // switch on case insensitive matching
39300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            "(" +    // begin group for schema
39310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            "(?:http|https|file):\\/\\/" +
393225ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima            "|(?:inline|data|about|content|javascript):" +
39330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ")" +
39340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            "(.*)" );
39350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
39360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
39370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Attempts to determine whether user input is a URL or search
39380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * terms.  Anything with a space is passed to search.
39390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *
39400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Converts to lowercase any mistakenly uppercased schema (i.e.,
39410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * "Http://" converts to "http://"
39420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *
39430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @return Original or modified URL
39440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *
39450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
39460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    String smartUrlFilter(String url) {
39470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
39480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String inUrl = url.trim();
39490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        boolean hasSpace = inUrl.indexOf(' ') != -1;
39500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
39510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        Matcher matcher = ACCEPTED_URI_SCHEMA.matcher(inUrl);
39520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (matcher.matches()) {
39530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // force scheme to lowercase
39540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            String scheme = matcher.group(1);
39550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            String lcScheme = scheme.toLowerCase();
39560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (!lcScheme.equals(scheme)) {
3957123ecfb21e7ca670e3d04efe58780b3bac54a9a1Mitsuru Oshima                inUrl = lcScheme + matcher.group(2);
3958123ecfb21e7ca670e3d04efe58780b3bac54a9a1Mitsuru Oshima            }
3959123ecfb21e7ca670e3d04efe58780b3bac54a9a1Mitsuru Oshima            if (hasSpace) {
3960123ecfb21e7ca670e3d04efe58780b3bac54a9a1Mitsuru Oshima                inUrl = inUrl.replace(" ", "%20");
39610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
39620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return inUrl;
39630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
39640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (hasSpace) {
3965565505b1a2c1d3099496af5910760087602e994aSatish Sampath            // FIXME: Is this the correct place to add to searches?
3966565505b1a2c1d3099496af5910760087602e994aSatish Sampath            // what if someone else calls this function?
3967565505b1a2c1d3099496af5910760087602e994aSatish Sampath            int shortcut = parseUrlShortcut(inUrl);
3968565505b1a2c1d3099496af5910760087602e994aSatish Sampath            if (shortcut != SHORTCUT_INVALID) {
3969565505b1a2c1d3099496af5910760087602e994aSatish Sampath                Browser.addSearchUrl(mResolver, inUrl);
3970565505b1a2c1d3099496af5910760087602e994aSatish Sampath                String query = inUrl.substring(2);
3971565505b1a2c1d3099496af5910760087602e994aSatish Sampath                switch (shortcut) {
3972565505b1a2c1d3099496af5910760087602e994aSatish Sampath                case SHORTCUT_GOOGLE_SEARCH:
397347fdfdb989ffb79590a39c40792be995de32e521Grace Kloba                    return URLUtil.composeSearchUrl(query, QuickSearch_G, QUERY_PLACE_HOLDER);
3974565505b1a2c1d3099496af5910760087602e994aSatish Sampath                case SHORTCUT_WIKIPEDIA_SEARCH:
3975565505b1a2c1d3099496af5910760087602e994aSatish Sampath                    return URLUtil.composeSearchUrl(query, QuickSearch_W, QUERY_PLACE_HOLDER);
3976565505b1a2c1d3099496af5910760087602e994aSatish Sampath                case SHORTCUT_DICTIONARY_SEARCH:
3977565505b1a2c1d3099496af5910760087602e994aSatish Sampath                    return URLUtil.composeSearchUrl(query, QuickSearch_D, QUERY_PLACE_HOLDER);
3978565505b1a2c1d3099496af5910760087602e994aSatish Sampath                case SHORTCUT_GOOGLE_MOBILE_LOCAL_SEARCH:
39790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // FIXME: we need location in this case
3980565505b1a2c1d3099496af5910760087602e994aSatish Sampath                    return URLUtil.composeSearchUrl(query, QuickSearch_L, QUERY_PLACE_HOLDER);
39810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
39820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
39830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
39845ee906c089567bca705e18561357510d7b55cb5aDan Egnor            if (Patterns.WEB_URL.matcher(inUrl).matches()) {
39850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                return URLUtil.guessUrl(inUrl);
39860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
39870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
39880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
39890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        Browser.addSearchUrl(mResolver, inUrl);
399047fdfdb989ffb79590a39c40792be995de32e521Grace Kloba        return URLUtil.composeSearchUrl(inUrl, QuickSearch_G, QUERY_PLACE_HOLDER);
39910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
39920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
3993bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch    /* package */ void setShouldShowErrorConsole(boolean flag) {
3994bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch        if (flag == mShouldShowErrorConsole) {
3995bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch            // Nothing to do.
3996bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch            return;
3997bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch        }
3998bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch
3999bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch        mShouldShowErrorConsole = flag;
4000bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch
400122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        ErrorConsoleView errorConsole = mTabControl.getCurrentTab()
400222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                .getErrorConsole(true);
4003bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch
4004bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch        if (flag) {
4005bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch            // Setting the show state of the console will cause it's the layout to be inflated.
4006bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch            if (errorConsole.numberOfErrors() > 0) {
4007bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch                errorConsole.showConsole(ErrorConsoleView.SHOW_MINIMIZED);
4008bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch            } else {
4009bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch                errorConsole.showConsole(ErrorConsoleView.SHOW_NONE);
4010bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch            }
4011bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch
4012bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch            // Now we can add it to the main view.
4013bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch            mErrorConsoleContainer.addView(errorConsole,
401415b8ec6b226f4d57307716e1f495e10a91f8cbf4Romain Guy                    new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
4015bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch                                                  ViewGroup.LayoutParams.WRAP_CONTENT));
4016bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch        } else {
4017bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch            mErrorConsoleContainer.removeView(errorConsole);
4018bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch        }
4019bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch
4020bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch    }
4021bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch
402222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    boolean shouldShowErrorConsole() {
402322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return mShouldShowErrorConsole;
402422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
402522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
4026163ab74e2f85b53a1a374c49677073fb64d35f28Andrei Popescu    private void setStatusBarVisibility(boolean visible) {
4027163ab74e2f85b53a1a374c49677073fb64d35f28Andrei Popescu        int flag = visible ? 0 : WindowManager.LayoutParams.FLAG_FULLSCREEN;
4028163ab74e2f85b53a1a374c49677073fb64d35f28Andrei Popescu        getWindow().setFlags(flag, WindowManager.LayoutParams.FLAG_FULLSCREEN);
4029163ab74e2f85b53a1a374c49677073fb64d35f28Andrei Popescu    }
4030163ab74e2f85b53a1a374c49677073fb64d35f28Andrei Popescu
403156199cc25e7ee0455ec2a8099098b66b8554f677Andrei Popescu
403256199cc25e7ee0455ec2a8099098b66b8554f677Andrei Popescu    private void sendNetworkType(String type, String subtype) {
403356199cc25e7ee0455ec2a8099098b66b8554f677Andrei Popescu        WebView w = mTabControl.getCurrentWebView();
403456199cc25e7ee0455ec2a8099098b66b8554f677Andrei Popescu        if (w != null) {
403556199cc25e7ee0455ec2a8099098b66b8554f677Andrei Popescu            w.setNetworkType(type, subtype);
403656199cc25e7ee0455ec2a8099098b66b8554f677Andrei Popescu        }
403756199cc25e7ee0455ec2a8099098b66b8554f677Andrei Popescu    }
403856199cc25e7ee0455ec2a8099098b66b8554f677Andrei Popescu
403930995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu    private void packageChanged(String packageName, boolean wasAdded) {
404030995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu        WebView w = mTabControl.getCurrentWebView();
404130995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu        if (w == null) {
404230995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu            return;
404330995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu        }
404430995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu
404530995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu        if (wasAdded) {
404630995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu            w.addPackageName(packageName);
404730995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu        } else {
404830995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu            w.removePackageName(packageName);
404930995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu        }
405030995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu    }
405130995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu
405230995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu    private void addPackageNames(Set<String> packageNames) {
405330995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu        WebView w = mTabControl.getCurrentWebView();
405430995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu        if (w == null) {
405530995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu            return;
405630995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu        }
405730995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu
405830995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu        w.addPackageNames(packageNames);
405930995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu    }
406030995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu
406130995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu    private void getInstalledPackages() {
406230995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu        AsyncTask<Void, Void, Set<String> > task =
406330995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu            new AsyncTask<Void, Void, Set<String> >() {
4064e0a3666b5c0dca7352895fa8b9b4fbb2237df721Michael Kolb            @Override
406530995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu            protected Set<String> doInBackground(Void... unused) {
406630995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu                Set<String> installedPackages = new HashSet<String>();
406730995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu                PackageManager pm = BrowserActivity.this.getPackageManager();
406830995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu                if (pm != null) {
406930995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu                    List<PackageInfo> packages = pm.getInstalledPackages(0);
407030995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu                    for (PackageInfo p : packages) {
407130995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu                        if (BrowserActivity.this.sGoogleApps.contains(p.packageName)) {
407230995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu                            installedPackages.add(p.packageName);
407330995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu                        }
407430995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu                    }
407530995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu                }
407630995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu
407730995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu                return installedPackages;
407830995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu            }
407930995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu
408030995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu            // Executes on the UI thread
4081e0a3666b5c0dca7352895fa8b9b4fbb2237df721Michael Kolb            @Override
408230995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu            protected void onPostExecute(Set<String> installedPackages) {
408330995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu                addPackageNames(installedPackages);
408430995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu            }
408530995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu        };
408630995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu        task.execute();
408730995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu    }
408830995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu
4089eb6eef4c45df2d65c3e70660493a147a2be405e3Grace Kloba    final static int LOCK_ICON_UNSECURE = 0;
4090eb6eef4c45df2d65c3e70660493a147a2be405e3Grace Kloba    final static int LOCK_ICON_SECURE   = 1;
4091eb6eef4c45df2d65c3e70660493a147a2be405e3Grace Kloba    final static int LOCK_ICON_MIXED    = 2;
40920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
40930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private BrowserSettings mSettings;
40940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private TabControl      mTabControl;
40950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private ContentResolver mResolver;
40960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private FrameLayout     mContentView;
4097adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu    private View            mCustomView;
4098adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu    private FrameLayout     mCustomViewContainer;
4099c9b5556351b59caec77b4eec1ad30652fec6a4d9Andrei Popescu    private WebChromeClient.CustomViewCallback mCustomViewCallback;
41000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
41010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // FIXME, temp address onPrepareMenu performance problem. When we move everything out of
41020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // view, we should rewrite this.
41030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private int mCurrentMenuState = 0;
41040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private int mMenuState = R.id.MAIN_MENU;
4105adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu    private int mOldMenuState = EMPTY_MENU;
41060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private static final int EMPTY_MENU = -1;
41070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private Menu mMenu;
41080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
41090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private FindDialog mFindDialog;
411001cfcdd0b77d672f5c09d98af683c6732c8250d8Cary Clark    private SelectDialog mSelectDialog;
41110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Used to prevent chording to result in firing two shortcuts immediately
41120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // one after another.  Fixes bug 1211714.
41130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    boolean mCanChord;
41140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
41150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private boolean mInLoad;
41160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private boolean mIsNetworkUp;
4117b7cc8b439dc595dc48e1c2183b35d23ad72dfbe5Ben Murdoch    private boolean mDidStopLoad;
41180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
41191f10cbfca5bf96e1466e0ed3ce1dbcd6fcfd0608Cary Clark    /* package */ boolean mActivityInPause = true;
41200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
41210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private boolean mMenuIsDown;
41220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
41230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private static boolean mInTrace;
41240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
41250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Performance probe
41260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private static final int[] SYSTEM_CPU_FORMAT = new int[] {
41270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Process.PROC_SPACE_TERM | Process.PROC_COMBINE,
41280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Process.PROC_SPACE_TERM | Process.PROC_OUT_LONG, // 1: user time
41290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Process.PROC_SPACE_TERM | Process.PROC_OUT_LONG, // 2: nice time
41300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Process.PROC_SPACE_TERM | Process.PROC_OUT_LONG, // 3: sys time
41310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Process.PROC_SPACE_TERM | Process.PROC_OUT_LONG, // 4: idle time
41320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Process.PROC_SPACE_TERM | Process.PROC_OUT_LONG, // 5: iowait time
41330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Process.PROC_SPACE_TERM | Process.PROC_OUT_LONG, // 6: irq time
41340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Process.PROC_SPACE_TERM | Process.PROC_OUT_LONG  // 7: softirq time
41350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    };
41360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
41370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private long mStart;
41380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private long mProcessStart;
41390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private long mUserStart;
41400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private long mSystemStart;
41410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private long mIdleStart;
41420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private long mIrqStart;
41430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
41440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private long mUiStart;
41450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
41460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private Drawable    mMixLockIcon;
41470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private Drawable    mSecLockIcon;
41480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
41490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /* hold a ref so we can auto-cancel if necessary */
41500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private AlertDialog mAlertDialog;
41510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
41520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // The up-to-date URL and title (these can be different from those stored
41530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // in WebView, since it takes some time for the information in WebView to
41540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // get updated)
41550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private String mUrl;
41560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private String mTitle;
41570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
41580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // As PageInfo has different style for landscape / portrait, we have
41590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // to re-open it when configuration changed
41600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private AlertDialog mPageInfoDialog;
416122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private Tab mPageInfoView;
41620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // If the Page-Info dialog is launched from the SSL-certificate-on-error
41630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // dialog, we should not just dismiss it, but should get back to the
41640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // SSL-certificate-on-error dialog. This flag is used to store this state
4165c7b92f811dfa3572578ddc6714c98a03936d9ce5Leon Scroggins    private boolean mPageInfoFromShowSSLCertificateOnError;
41660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
41670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // as SSLCertificateOnError has different style for landscape / portrait,
41680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // we have to re-open it when configuration changed
41690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private AlertDialog mSSLCertificateOnErrorDialog;
41700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private WebView mSSLCertificateOnErrorView;
41710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private SslErrorHandler mSSLCertificateOnErrorHandler;
41720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private SslError mSSLCertificateOnErrorError;
41730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
41740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // as SSLCertificate has different style for landscape / portrait, we
41750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // have to re-open it when configuration changed
41760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private AlertDialog mSSLCertificateDialog;
417722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private Tab mSSLCertificateView;
41780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
41790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // as HttpAuthentication has different style for landscape / portrait, we
41800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // have to re-open it when configuration changed
41810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private AlertDialog mHttpAuthenticationDialog;
41820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private HttpAuthHandler mHttpAuthHandler;
41830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
41840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /*package*/ static final FrameLayout.LayoutParams COVER_SCREEN_PARAMS =
41850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                            new FrameLayout.LayoutParams(
418615b8ec6b226f4d57307716e1f495e10a91f8cbf4Romain Guy                                            ViewGroup.LayoutParams.MATCH_PARENT,
418715b8ec6b226f4d57307716e1f495e10a91f8cbf4Romain Guy                                            ViewGroup.LayoutParams.MATCH_PARENT);
4188adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu    /*package*/ static final FrameLayout.LayoutParams COVER_SCREEN_GRAVITY_CENTER =
4189adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu                                            new FrameLayout.LayoutParams(
419015b8ec6b226f4d57307716e1f495e10a91f8cbf4Romain Guy                                            ViewGroup.LayoutParams.MATCH_PARENT,
419115b8ec6b226f4d57307716e1f495e10a91f8cbf4Romain Guy                                            ViewGroup.LayoutParams.MATCH_PARENT,
4192adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu                                            Gravity.CENTER);
419347fdfdb989ffb79590a39c40792be995de32e521Grace Kloba    // Google search
419447fdfdb989ffb79590a39c40792be995de32e521Grace Kloba    final static String QuickSearch_G = "http://www.google.com/m?q=%s";
41950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Wikipedia search
41960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    final static String QuickSearch_W = "http://en.wikipedia.org/w/index.php?search=%s&go=Go";
41970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Dictionary search
41980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    final static String QuickSearch_D = "http://dictionary.reference.com/search?q=%s";
41990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Google Mobile Local search
42000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    final static String QuickSearch_L = "http://www.google.com/m/search?site=local&q=%s&near=mountain+view";
42010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
42020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    final static String QUERY_PLACE_HOLDER = "%s";
42030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
42040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // "source" parameter for Google search through search key
42050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    final static String GOOGLE_SEARCH_SOURCE_SEARCHKEY = "browser-key";
42060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // "source" parameter for Google search through goto menu
42070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    final static String GOOGLE_SEARCH_SOURCE_GOTO = "browser-goto";
42080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // "source" parameter for Google search through simplily type
42090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    final static String GOOGLE_SEARCH_SOURCE_TYPE = "browser-type";
42100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // "source" parameter for Google search suggested by the browser
42110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    final static String GOOGLE_SEARCH_SOURCE_SUGGEST = "browser-suggest";
42120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // "source" parameter for Google search from unknown source
42130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    final static String GOOGLE_SEARCH_SOURCE_UNKNOWN = "unknown";
42140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
42150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private final static String LOGTAG = "browser";
42160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
42170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private String mLastEnteredUrl;
42180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
42190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private PowerManager.WakeLock mWakeLock;
42200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private final static int WAKELOCK_TIMEOUT = 5 * 60 * 1000; // 5 minutes
42210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
42220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private Toast mStopToast;
42230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
4224571b3762a5eb9e492283e0a1e437edd209fdc0deLeon Scroggins    private TitleBarBase mTitleBar;
422581db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins
4226bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch    private LinearLayout mErrorConsoleContainer = null;
4227bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch    private boolean mShouldShowErrorConsole = false;
4228bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch
42290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // As the ids are dynamically created, we can't guarantee that they will
42300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // be in sequence, so this static array maps ids to a window number.
42310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    final static private int[] WINDOW_SHORTCUT_ID_ARRAY =
42320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    { R.id.window_one_menu_id, R.id.window_two_menu_id, R.id.window_three_menu_id,
42330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project      R.id.window_four_menu_id, R.id.window_five_menu_id, R.id.window_six_menu_id,
42340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project      R.id.window_seven_menu_id, R.id.window_eight_menu_id };
42350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
42360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // monitor platform changes
42370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private IntentFilter mNetworkStateChangedFilter;
42380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private BroadcastReceiver mNetworkStateIntentReceiver;
42390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
4240b4da0ad0351996f639b50f9f29b123a9b5c24fd0Grace Kloba    private BroadcastReceiver mPackageInstallationReceiver;
4241b4da0ad0351996f639b50f9f29b123a9b5c24fd0Grace Kloba
4242a7611811e0d744a7220b7bf80c8f795af5ea53edBjorn Bringert    private SystemAllowGeolocationOrigins mSystemAllowGeolocationOrigins;
4243a7611811e0d744a7220b7bf80c8f795af5ea53edBjorn Bringert
42440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // activity requestCode
424578a98e459323f938e97789a6131beddbebb459ceNicolas Roard    final static int COMBO_PAGE                 = 1;
424678a98e459323f938e97789a6131beddbebb459ceNicolas Roard    final static int DOWNLOAD_PAGE              = 2;
424778a98e459323f938e97789a6131beddbebb459ceNicolas Roard    final static int PREFERENCES_PAGE           = 3;
42488d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins    final static int FILE_SELECTED              = 4;
42490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
4250540035dfd1347c78eeec10ec0847e18fcc50ef36Andrei Popescu    // the default <video> poster
4251540035dfd1347c78eeec10ec0847e18fcc50ef36Andrei Popescu    private Bitmap mDefaultVideoPoster;
4252540035dfd1347c78eeec10ec0847e18fcc50ef36Andrei Popescu    // the video progress view
4253540035dfd1347c78eeec10ec0847e18fcc50ef36Andrei Popescu    private View mVideoProgressView;
4254540035dfd1347c78eeec10ec0847e18fcc50ef36Andrei Popescu
425530995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu    // The Google packages we monitor for the navigator.isApplicationInstalled()
425630995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu    // API. Add as needed.
425730995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu    private static Set<String> sGoogleApps;
425830995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu    static {
425930995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu        sGoogleApps = new HashSet<String>();
426030995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu        sGoogleApps.add("com.google.android.youtube");
426130995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu    }
426230995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu
426325ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima    /**
426425ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima     * A UrlData class to abstract how the content will be set to WebView.
426525ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima     * This base class uses loadUrl to show the content.
426625ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima     */
42676eac63e78d43d04e31c4d16830c44c4d9df82639Leon Scroggins    /* package */ static class UrlData {
4268068e48b469f5abca53ee3da38f933cf2c25c93b8Grace Kloba        final String mUrl;
4269068e48b469f5abca53ee3da38f933cf2c25c93b8Grace Kloba        final Map<String, String> mHeaders;
427058d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        final Intent mVoiceIntent;
427160e095c190496d42327f8ec2ef990c044d15a76fGrace Kloba
427225ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima        UrlData(String url) {
427325ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima            this.mUrl = url;
4274068e48b469f5abca53ee3da38f933cf2c25c93b8Grace Kloba            this.mHeaders = null;
427558d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins            this.mVoiceIntent = null;
427625ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima        }
427760e095c190496d42327f8ec2ef990c044d15a76fGrace Kloba
427858d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        UrlData(String url, Map<String, String> headers, Intent intent) {
4279068e48b469f5abca53ee3da38f933cf2c25c93b8Grace Kloba            this.mUrl = url;
4280068e48b469f5abca53ee3da38f933cf2c25c93b8Grace Kloba            this.mHeaders = headers;
4281a1cc3fdce19a336c251297c61cd83ac6cf767cd1Leon Scroggins            if (RecognizerResultsIntent.ACTION_VOICE_SEARCH_RESULTS
4282a1cc3fdce19a336c251297c61cd83ac6cf767cd1Leon Scroggins                    .equals(intent.getAction())) {
428358d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins                this.mVoiceIntent = intent;
428458d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins            } else {
428558d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins                this.mVoiceIntent = null;
428658d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins            }
428760e095c190496d42327f8ec2ef990c044d15a76fGrace Kloba        }
428860e095c190496d42327f8ec2ef990c044d15a76fGrace Kloba
428925ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima        boolean isEmpty() {
429058d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins            return mVoiceIntent == null && (mUrl == null || mUrl.length() == 0);
429125ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima        }
429225ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima
429392472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins        /**
429492472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins         * Load this UrlData into the given Tab.  Use loadUrlDataIn to update
429592472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins         * the title bar as well.
429692472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins         */
429758d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        public void loadIn(Tab t) {
429858d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins            if (mVoiceIntent != null) {
429958d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins                t.activateVoiceSearchMode(mVoiceIntent);
430058d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins            } else {
430158d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins                t.getWebView().loadUrl(mUrl, mHeaders);
430258d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins            }
430325ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima        }
430425ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima    };
430525ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima
43061f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins    /* package */ static final UrlData EMPTY_URL_DATA = new UrlData(null);
43070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project}
4308