BrowserActivity.java revision d746a94137a87ffcc1fcefdac9a3764c3bc3f5cd
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;
4196afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scrogginsimport android.database.DatabaseUtils;
420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.graphics.Bitmap;
43540035dfd1347c78eeec10ec0847e18fcc50ef36Andrei Popescuimport android.graphics.BitmapFactory;
440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.graphics.Canvas;
450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.graphics.Picture;
463bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scrogginsimport android.graphics.PixelFormat;
473bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scrogginsimport android.graphics.Rect;
480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.graphics.drawable.Drawable;
490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.net.ConnectivityManager;
5056199cc25e7ee0455ec2a8099098b66b8554f677Andrei Popescuimport android.net.NetworkInfo;
510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.net.Uri;
520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.net.WebAddress;
530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.net.http.SslCertificate;
540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.net.http.SslError;
550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.os.AsyncTask;
560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.os.Bundle;
570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.os.Debug;
580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.os.Environment;
590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.os.Handler;
600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.os.Message;
610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.os.PowerManager;
620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.os.Process;
630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.os.ServiceManager;
640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.os.SystemClock;
650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.provider.Browser;
665e335a381a0cd66e94117b202c1f34f5cb29c9b8Cary Clarkimport android.provider.ContactsContract;
675e335a381a0cd66e94117b202c1f34f5cb29c9b8Cary Clarkimport android.provider.ContactsContract.Intents.Insert;
680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.provider.Downloads;
690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.provider.MediaStore;
70a1cc3fdce19a336c251297c61cd83ac6cf767cd1Leon Scrogginsimport android.speech.RecognizerResultsIntent;
710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.text.IClipboard;
720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.text.TextUtils;
730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.text.format.DateFormat;
74b94bf27370329abb27e5e33b493d6edb5662b36eLeon Scrogginsimport android.util.AttributeSet;
750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.util.Log;
76385effd3192a16b737a7d4fbe4fc71c6cf467627Dianne Hackbornimport android.util.Patterns;
770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.view.ContextMenu;
780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.view.Gravity;
790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.view.KeyEvent;
800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.view.LayoutInflater;
810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.view.Menu;
820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.view.MenuInflater;
830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.view.MenuItem;
840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.view.View;
850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.view.ViewGroup;
860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.view.Window;
870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.view.WindowManager;
880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.view.ContextMenu.ContextMenuInfo;
890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.view.MenuItem.OnMenuItemClickListener;
902b34599c39d2c04c242d2a0ed755705fc414541dSvetoslav Ganovimport android.view.accessibility.AccessibilityManager;
910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.webkit.CookieManager;
920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.webkit.CookieSyncManager;
930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.webkit.DownloadListener;
940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.webkit.HttpAuthHandler;
95b4da0ad0351996f639b50f9f29b123a9b5c24fd0Grace Klobaimport android.webkit.PluginManager;
960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.webkit.SslErrorHandler;
970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.webkit.URLUtil;
98cb6cc864e53f7d916622daf3b2cec133b36d6a55Leon Clarkeimport android.webkit.ValueCallback;
990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.webkit.WebChromeClient;
1000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.webkit.WebHistoryItem;
1010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.webkit.WebIconDatabase;
1020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.webkit.WebView;
1030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.widget.EditText;
1040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.widget.FrameLayout;
1050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.widget.LinearLayout;
1060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.widget.TextView;
1070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.widget.Toast;
108752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintanaimport android.accounts.Account;
109752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintanaimport android.accounts.AccountManager;
110752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintanaimport android.accounts.AccountManagerFuture;
111752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintanaimport android.accounts.AuthenticatorException;
112752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintanaimport android.accounts.OperationCanceledException;
113752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintanaimport android.accounts.AccountManagerCallback;
1140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
11510d1cca0c208d1f9db23893a8515685e04cfe224Bjorn Bringertimport com.android.common.Search;
1161fe13a5230e319df42b21939a14d127bd9bf3856Leon Scrogginsimport com.android.common.speech.LoggingEvents;
1175ee906c089567bca705e18561357510d7b55cb5aDan Egnor
118b6b7f9ef3b4ed220063f555d8b7c205210a61a04Leon Scrogginsimport java.io.ByteArrayOutputStream;
1190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport java.io.File;
1204f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdochimport java.io.IOException;
1214f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdochimport java.io.InputStream;
1220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport java.net.MalformedURLException;
1230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport java.net.URI;
1249918943559193e3e047a1c18442e2cdb0fe22b15Dianne Hackbornimport java.net.URISyntaxException;
1250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport java.net.URL;
1260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport java.net.URLEncoder;
1270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport java.text.ParseException;
1280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport java.util.Date;
1290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport java.util.HashMap;
13030995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescuimport java.util.HashSet;
13100f54c589fd38431efd42ea2a551a49e64d595d5Grace Klobaimport java.util.Iterator;
13230995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescuimport java.util.List;
133068e48b469f5abca53ee3da38f933cf2c25c93b8Grace Klobaimport java.util.Map;
13430995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescuimport java.util.Set;
1350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport java.util.regex.Matcher;
1360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport java.util.regex.Pattern;
1370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
1380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectpublic class BrowserActivity extends Activity
13998d5fce7c687cfcc956b10d44946d31f39b6dc15Shimeng (Simon) Wang    implements View.OnCreateContextMenuListener, DownloadListener {
1400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
14131a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort    /* Define some aliases to make these debugging flags easier to refer to.
14231a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort     * This file imports android.provider.Browser, so we can't just refer to "Browser.DEBUG".
14331a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort     */
14431a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort    private final static boolean DEBUG = com.android.browser.Browser.DEBUG;
14531a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort    private final static boolean LOGV_ENABLED = com.android.browser.Browser.LOGV_ENABLED;
14631a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort    private final static boolean LOGD_ENABLED = com.android.browser.Browser.LOGD_ENABLED;
14731a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort
148565505b1a2c1d3099496af5910760087602e994aSatish Sampath    // These are single-character shortcuts for searching popular sources.
149565505b1a2c1d3099496af5910760087602e994aSatish Sampath    private static final int SHORTCUT_INVALID = 0;
150565505b1a2c1d3099496af5910760087602e994aSatish Sampath    private static final int SHORTCUT_GOOGLE_SEARCH = 1;
151565505b1a2c1d3099496af5910760087602e994aSatish Sampath    private static final int SHORTCUT_WIKIPEDIA_SEARCH = 2;
152565505b1a2c1d3099496af5910760087602e994aSatish Sampath    private static final int SHORTCUT_DICTIONARY_SEARCH = 3;
153565505b1a2c1d3099496af5910760087602e994aSatish Sampath    private static final int SHORTCUT_GOOGLE_MOBILE_LOCAL_SEARCH = 4;
154565505b1a2c1d3099496af5910760087602e994aSatish Sampath
155a977124eb29b195127fd161120ebbc58b255fb48Cary Clark    private static class ClearThumbnails extends AsyncTask<File, Void, Void> {
1560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        @Override
1570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public Void doInBackground(File... files) {
1580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (files != null) {
1590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                for (File f : files) {
160d6be1758b38d5b066ff10b6af906aa66c63670cdCary Clark                    if (!f.delete()) {
161d6be1758b38d5b066ff10b6af906aa66c63670cdCary Clark                      Log.e(LOGTAG, f.getPath() + " was not deleted");
162d6be1758b38d5b066ff10b6af906aa66c63670cdCary Clark                    }
1630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
1640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
1650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return null;
1660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
1670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
1680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
1693bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    /**
1703bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     * This layout holds everything you see below the status bar, including the
1713bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     * error console, the custom view container, and the webviews.
1723bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     */
1733bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    private FrameLayout mBrowserFrameLayout;
17481db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins
175d746a94137a87ffcc1fcefdac9a3764c3bc3f5cdLeon Scroggins    private boolean mXLargeScreenSize;
176d746a94137a87ffcc1fcefdac9a3764c3bc3f5cdLeon Scroggins
17722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    @Override
17822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    public void onCreate(Bundle icicle) {
17931a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort        if (LOGV_ENABLED) {
1800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Log.v(LOGTAG, this + " onStart");
1810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
1820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        super.onCreate(icicle);
1830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // test the browser in OpenGL
1840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // requestWindowFeature(Window.FEATURE_OPENGL);
1850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
186d334bf564b72416e77e707d25f8c55cfe1d85709Mike Reed        // enable this to test the browser in 32bit
187d334bf564b72416e77e707d25f8c55cfe1d85709Mike Reed        if (false) {
188d334bf564b72416e77e707d25f8c55cfe1d85709Mike Reed            getWindow().setFormat(PixelFormat.RGBX_8888);
189d334bf564b72416e77e707d25f8c55cfe1d85709Mike Reed            BitmapFactory.setDefaultConfig(Bitmap.Config.ARGB_8888);
190d334bf564b72416e77e707d25f8c55cfe1d85709Mike Reed        }
191d334bf564b72416e77e707d25f8c55cfe1d85709Mike Reed
1922b34599c39d2c04c242d2a0ed755705fc414541dSvetoslav Ganov        if (AccessibilityManager.getInstance(this).isEnabled()) {
1932b34599c39d2c04c242d2a0ed755705fc414541dSvetoslav Ganov            setDefaultKeyMode(DEFAULT_KEYS_DISABLE);
1942b34599c39d2c04c242d2a0ed755705fc414541dSvetoslav Ganov        } else {
1952b34599c39d2c04c242d2a0ed755705fc414541dSvetoslav Ganov            setDefaultKeyMode(DEFAULT_KEYS_SEARCH_LOCAL);
1962b34599c39d2c04c242d2a0ed755705fc414541dSvetoslav Ganov        }
1970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
1980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mResolver = getContentResolver();
1990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
2000923d69a8ca45222cabd82a80eaa88da9f132e9aGrace Kloba        // If this was a web search request, pass it on to the default web
2010923d69a8ca45222cabd82a80eaa88da9f132e9aGrace Kloba        // search provider and finish this activity.
2020923d69a8ca45222cabd82a80eaa88da9f132e9aGrace Kloba        if (handleWebSearchIntent(getIntent())) {
2030923d69a8ca45222cabd82a80eaa88da9f132e9aGrace Kloba            finish();
2040923d69a8ca45222cabd82a80eaa88da9f132e9aGrace Kloba            return;
2050923d69a8ca45222cabd82a80eaa88da9f132e9aGrace Kloba        }
2060923d69a8ca45222cabd82a80eaa88da9f132e9aGrace Kloba
2070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mSecLockIcon = Resources.getSystem().getDrawable(
2080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                android.R.drawable.ic_secure);
2090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mMixLockIcon = Resources.getSystem().getDrawable(
2100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                android.R.drawable.ic_partial_secure);
2110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
21281db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins        FrameLayout frameLayout = (FrameLayout) getWindow().getDecorView()
21381db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins                .findViewById(com.android.internal.R.id.content);
2143bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins        mBrowserFrameLayout = (FrameLayout) LayoutInflater.from(this)
2153bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                .inflate(R.layout.custom_screen, null);
2163bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins        mContentView = (FrameLayout) mBrowserFrameLayout.findViewById(
2173bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                R.id.main_content);
2183bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins        mErrorConsoleContainer = (LinearLayout) mBrowserFrameLayout
2193bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                .findViewById(R.id.error_console);
2203bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins        mCustomViewContainer = (FrameLayout) mBrowserFrameLayout
2213bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                .findViewById(R.id.fullscreen_custom_content);
2223bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins        frameLayout.addView(mBrowserFrameLayout, COVER_SCREEN_PARAMS);
22368579393973f745fc65a2781061af9bb8f2d7020Leon Scroggins        mTitleBar = new TitleBar(this);
224d746a94137a87ffcc1fcefdac9a3764c3bc3f5cdLeon Scroggins        mXLargeScreenSize = (getResources().getConfiguration().screenLayout
225d746a94137a87ffcc1fcefdac9a3764c3bc3f5cdLeon Scroggins                & Configuration.SCREENLAYOUT_SIZE_MASK)
226d746a94137a87ffcc1fcefdac9a3764c3bc3f5cdLeon Scroggins                == Configuration.SCREENLAYOUT_SIZE_XLARGE;
227d746a94137a87ffcc1fcefdac9a3764c3bc3f5cdLeon Scroggins        if (mXLargeScreenSize) {
228d746a94137a87ffcc1fcefdac9a3764c3bc3f5cdLeon Scroggins            LinearLayout layout = (LinearLayout) mBrowserFrameLayout.
229d746a94137a87ffcc1fcefdac9a3764c3bc3f5cdLeon Scroggins                    findViewById(R.id.vertical_layout);
230d746a94137a87ffcc1fcefdac9a3764c3bc3f5cdLeon Scroggins            layout.addView(mTitleBar, 0, new LinearLayout.LayoutParams(
231d746a94137a87ffcc1fcefdac9a3764c3bc3f5cdLeon Scroggins                    ViewGroup.LayoutParams.MATCH_PARENT,
232d746a94137a87ffcc1fcefdac9a3764c3bc3f5cdLeon Scroggins                    ViewGroup.LayoutParams.WRAP_CONTENT));
233d746a94137a87ffcc1fcefdac9a3764c3bc3f5cdLeon Scroggins        } else {
234d746a94137a87ffcc1fcefdac9a3764c3bc3f5cdLeon Scroggins            // mTitleBar will be always be shown in the fully loaded mode on
235d746a94137a87ffcc1fcefdac9a3764c3bc3f5cdLeon Scroggins            // phone
236d746a94137a87ffcc1fcefdac9a3764c3bc3f5cdLeon Scroggins            mTitleBar.setProgress(100);
237d746a94137a87ffcc1fcefdac9a3764c3bc3f5cdLeon Scroggins            // Fake title bar is not needed in xlarge layout
238d746a94137a87ffcc1fcefdac9a3764c3bc3f5cdLeon Scroggins            mFakeTitleBar = new TitleBar(this);
239d746a94137a87ffcc1fcefdac9a3764c3bc3f5cdLeon Scroggins        }
2400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
2410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Create the tab control and our initial tab
2420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mTabControl = new TabControl(this);
2430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
2440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Open the icon database and retain all the bookmark urls for favicons
2450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        retainIconsOnStartup();
2460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
2470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Keep a settings instance handy.
2480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mSettings = BrowserSettings.getInstance();
2490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mSettings.setTabControl(mTabControl);
2500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
2510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
2520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "Browser");
2530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
2546adacc90222a3293bc631ef88ee5613e23b2d4c0Patrick Scott        // Find out if the network is currently up.
2556adacc90222a3293bc631ef88ee5613e23b2d4c0Patrick Scott        ConnectivityManager cm = (ConnectivityManager) getSystemService(
2566adacc90222a3293bc631ef88ee5613e23b2d4c0Patrick Scott                Context.CONNECTIVITY_SERVICE);
2576adacc90222a3293bc631ef88ee5613e23b2d4c0Patrick Scott        NetworkInfo info = cm.getActiveNetworkInfo();
2586adacc90222a3293bc631ef88ee5613e23b2d4c0Patrick Scott        if (info != null) {
2596adacc90222a3293bc631ef88ee5613e23b2d4c0Patrick Scott            mIsNetworkUp = info.isAvailable();
2606adacc90222a3293bc631ef88ee5613e23b2d4c0Patrick Scott        }
2616adacc90222a3293bc631ef88ee5613e23b2d4c0Patrick Scott
262a34f686112fb4f9fbea00b8c2c47153d34e93e41Grace Kloba        /* enables registration for changes in network status from
263a34f686112fb4f9fbea00b8c2c47153d34e93e41Grace Kloba           http stack */
264a34f686112fb4f9fbea00b8c2c47153d34e93e41Grace Kloba        mNetworkStateChangedFilter = new IntentFilter();
265a34f686112fb4f9fbea00b8c2c47153d34e93e41Grace Kloba        mNetworkStateChangedFilter.addAction(
266a34f686112fb4f9fbea00b8c2c47153d34e93e41Grace Kloba                ConnectivityManager.CONNECTIVITY_ACTION);
267a34f686112fb4f9fbea00b8c2c47153d34e93e41Grace Kloba        mNetworkStateIntentReceiver = new BroadcastReceiver() {
268a34f686112fb4f9fbea00b8c2c47153d34e93e41Grace Kloba                @Override
269a34f686112fb4f9fbea00b8c2c47153d34e93e41Grace Kloba                public void onReceive(Context context, Intent intent) {
270a34f686112fb4f9fbea00b8c2c47153d34e93e41Grace Kloba                    if (intent.getAction().equals(
271a34f686112fb4f9fbea00b8c2c47153d34e93e41Grace Kloba                            ConnectivityManager.CONNECTIVITY_ACTION)) {
272e4c98469644d3fa2689cf6658b1999add13c7e0eAndrei Popescu
273e4c98469644d3fa2689cf6658b1999add13c7e0eAndrei Popescu                        NetworkInfo info = intent.getParcelableExtra(
274e4c98469644d3fa2689cf6658b1999add13c7e0eAndrei Popescu                                ConnectivityManager.EXTRA_NETWORK_INFO);
275e4c98469644d3fa2689cf6658b1999add13c7e0eAndrei Popescu                        String typeName = info.getTypeName();
276e4c98469644d3fa2689cf6658b1999add13c7e0eAndrei Popescu                        String subtypeName = info.getSubtypeName();
277e4c98469644d3fa2689cf6658b1999add13c7e0eAndrei Popescu                        sendNetworkType(typeName.toLowerCase(),
278e4c98469644d3fa2689cf6658b1999add13c7e0eAndrei Popescu                                (subtypeName != null ? subtypeName.toLowerCase() : ""));
279e4c98469644d3fa2689cf6658b1999add13c7e0eAndrei Popescu
280e4c98469644d3fa2689cf6658b1999add13c7e0eAndrei Popescu                        onNetworkToggle(info.isAvailable());
281a34f686112fb4f9fbea00b8c2c47153d34e93e41Grace Kloba                    }
282a34f686112fb4f9fbea00b8c2c47153d34e93e41Grace Kloba                }
283a34f686112fb4f9fbea00b8c2c47153d34e93e41Grace Kloba            };
284a34f686112fb4f9fbea00b8c2c47153d34e93e41Grace Kloba
285615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba        IntentFilter filter = new IntentFilter(Intent.ACTION_PACKAGE_ADDED);
286615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba        filter.addAction(Intent.ACTION_PACKAGE_REMOVED);
287615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba        filter.addDataScheme("package");
288615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba        mPackageInstallationReceiver = new BroadcastReceiver() {
289615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba            @Override
290615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba            public void onReceive(Context context, Intent intent) {
291615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                final String action = intent.getAction();
292615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                final String packageName = intent.getData()
293615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                        .getSchemeSpecificPart();
294615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                final boolean replacing = intent.getBooleanExtra(
295615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                        Intent.EXTRA_REPLACING, false);
296615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                if (Intent.ACTION_PACKAGE_REMOVED.equals(action) && replacing) {
297615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                    // if it is replacing, refreshPlugins() when adding
298615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                    return;
299615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                }
30030995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu
30130995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu                if (sGoogleApps.contains(packageName)) {
30230995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu                    BrowserActivity.this.packageChanged(packageName,
30330995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu                            Intent.ACTION_PACKAGE_ADDED.equals(action));
30430995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu                }
30530995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu
306615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                PackageManager pm = BrowserActivity.this.getPackageManager();
307615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                PackageInfo pkgInfo = null;
308615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                try {
309615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                    pkgInfo = pm.getPackageInfo(packageName,
310615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                            PackageManager.GET_PERMISSIONS);
311615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                } catch (PackageManager.NameNotFoundException e) {
312615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                    return;
313615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                }
314615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                if (pkgInfo != null) {
315615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                    String permissions[] = pkgInfo.requestedPermissions;
316615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                    if (permissions == null) {
317615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                        return;
318615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                    }
319615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                    boolean permissionOk = false;
320615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                    for (String permit : permissions) {
321615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                        if (PluginManager.PLUGIN_PERMISSION.equals(permit)) {
322615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                            permissionOk = true;
323615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                            break;
324615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                        }
325615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                    }
326615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                    if (permissionOk) {
327615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                        PluginManager.getInstance(BrowserActivity.this)
328615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                                .refreshPlugins(
329615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                                        Intent.ACTION_PACKAGE_ADDED
330615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                                                .equals(action));
331615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                    }
332615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                }
333615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba            }
334615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba        };
335615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba        registerReceiver(mPackageInstallationReceiver, filter);
336615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba
3370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (!mTabControl.restoreState(icicle)) {
3380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // clear up the thumbnail directory if we can't restore the state as
3390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // none of the files in the directory are referenced any more.
3400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            new ClearThumbnails().execute(
3410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    mTabControl.getThumbnailDir().listFiles());
342aab3f09b5c2d39b19067e57635614080b2403a46Grace Kloba            // there is no quit on Android. But if we can't restore the state,
343aab3f09b5c2d39b19067e57635614080b2403a46Grace Kloba            // we can treat it as a new Browser, remove the old session cookies.
344aab3f09b5c2d39b19067e57635614080b2403a46Grace Kloba            CookieManager.getInstance().removeSessionCookie();
3450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            final Intent intent = getIntent();
3460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            final Bundle extra = intent.getExtras();
3470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Create an initial tab.
3480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // If the intent is ACTION_VIEW and data is not null, the Browser is
3490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // invoked to view the content by another application. In this case,
3500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // the tab will be close when exit.
35125ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima            UrlData urlData = getUrlDataFromIntent(intent);
35225ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima
35358d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins            String action = intent.getAction();
35422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            final Tab t = mTabControl.createNewTab(
35558d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins                    (Intent.ACTION_VIEW.equals(action) &&
35658d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins                    intent.getData() != null)
357a1cc3fdce19a336c251297c61cd83ac6cf767cd1Leon Scroggins                    || RecognizerResultsIntent.ACTION_VOICE_SEARCH_RESULTS
358a1cc3fdce19a336c251297c61cd83ac6cf767cd1Leon Scroggins                    .equals(action),
35925ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima                    intent.getStringExtra(Browser.EXTRA_APPLICATION_ID), urlData.mUrl);
3600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mTabControl.setCurrentTab(t);
3610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            attachTabToContentView(t);
3620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            WebView webView = t.getWebView();
3630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (extra != null) {
3640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                int scale = extra.getInt(Browser.INITIAL_ZOOM_LEVEL, 0);
3650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (scale > 0 && scale <= 1000) {
3660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    webView.setInitialScale(scale);
3670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
3680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
3690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
37025ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima            if (urlData.isEmpty()) {
37198d5fce7c687cfcc956b10d44946d31f39b6dc15Shimeng (Simon) Wang                loadUrl(webView, mSettings.getHomePage());
3720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } else {
3739d53da05812f959745810a33bb4e06b273393c42Patrick Scott                loadUrlDataIn(t, urlData);
3740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
3750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
3760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // TabControl.restoreState() will create a new tab even if
3771f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins            // restoring the state fails.
3780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            attachTabToContentView(mTabControl.getCurrentTab());
3790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
380615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba
381b3c02da4553b1a629b16377970fdabae28394c94Feng Qian        // Read JavaScript flags if it exists.
382b3c02da4553b1a629b16377970fdabae28394c94Feng Qian        String jsFlags = mSettings.getJsFlags();
383b3c02da4553b1a629b16377970fdabae28394c94Feng Qian        if (jsFlags.trim().length() != 0) {
384b3c02da4553b1a629b16377970fdabae28394c94Feng Qian            mTabControl.getCurrentWebView().setJsFlags(jsFlags);
385b3c02da4553b1a629b16377970fdabae28394c94Feng Qian        }
38630995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu        // Work out which packages are installed on the system.
38730995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu        getInstalledPackages();
388a7611811e0d744a7220b7bf80c8f795af5ea53edBjorn Bringert
389a7611811e0d744a7220b7bf80c8f795af5ea53edBjorn Bringert        // Start watching the default geolocation permissions
390a7611811e0d744a7220b7bf80c8f795af5ea53edBjorn Bringert        mSystemAllowGeolocationOrigins
391a7611811e0d744a7220b7bf80c8f795af5ea53edBjorn Bringert                = new SystemAllowGeolocationOrigins(getApplicationContext());
392a7611811e0d744a7220b7bf80c8f795af5ea53edBjorn Bringert        mSystemAllowGeolocationOrigins.start();
3930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
3940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
39558d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    /**
39658d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins     * Feed the previously stored results strings to the BrowserProvider so that
39758d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins     * the SearchDialog will show them instead of the standard searches.
39858d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins     * @param result String to show on the editable line of the SearchDialog.
39958d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins     */
40058d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    /* package */ void showVoiceSearchResults(String result) {
40158d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        ContentProviderClient client = mResolver.acquireContentProviderClient(
40258d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins                Browser.BOOKMARKS_URI);
40358d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        ContentProvider prov = client.getLocalContentProvider();
40458d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        BrowserProvider bp = (BrowserProvider) prov;
40558d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        bp.setQueryResults(mTabControl.getCurrentTab().getVoiceSearchResults());
40658d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        client.release();
40758d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins
408fbb3f15f725e890837431f402b43e802045a4f3fLeon Scroggins        Bundle bundle = createGoogleSearchSourceBundle(
409fbb3f15f725e890837431f402b43e802045a4f3fLeon Scroggins                GOOGLE_SEARCH_SOURCE_SEARCHKEY);
410fbb3f15f725e890837431f402b43e802045a4f3fLeon Scroggins        bundle.putBoolean(SearchManager.CONTEXT_IS_VOICE, true);
411fbb3f15f725e890837431f402b43e802045a4f3fLeon Scroggins        startSearch(result, false, bundle, false);
41258d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    }
41358d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins
4140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    @Override
4150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    protected void onNewIntent(Intent intent) {
41622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        Tab current = mTabControl.getCurrentTab();
4170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // When a tab is closed on exit, the current tab index is set to -1.
4180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Reset before proceed as Browser requires the current tab to be set.
4190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (current == null) {
4200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Try to reset the tab in case the index was incorrect.
4210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            current = mTabControl.getTab(0);
4220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (current == null) {
4230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // No tabs at all so just ignore this intent.
4240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                return;
4250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
4260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mTabControl.setCurrentTab(current);
4270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            attachTabToContentView(current);
4280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            resetTitleAndIcon(current.getWebView());
4290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
4300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final String action = intent.getAction();
4310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final int flags = intent.getFlags();
4320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (Intent.ACTION_MAIN.equals(action) ||
4330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                (flags & Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY) != 0) {
4340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // just resume the browser
4350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
4360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
437b8a844da0049965b3cef5739dbab19c7ac766762Leon Scroggins        // In case the SearchDialog is open.
438b8a844da0049965b3cef5739dbab19c7ac766762Leon Scroggins        ((SearchManager) getSystemService(Context.SEARCH_SERVICE))
439b8a844da0049965b3cef5739dbab19c7ac766762Leon Scroggins                .stopSearch();
440a1cc3fdce19a336c251297c61cd83ac6cf767cd1Leon Scroggins        boolean activateVoiceSearch = RecognizerResultsIntent
441a1cc3fdce19a336c251297c61cd83ac6cf767cd1Leon Scroggins                .ACTION_VOICE_SEARCH_RESULTS.equals(action);
4420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (Intent.ACTION_VIEW.equals(action)
4430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                || Intent.ACTION_SEARCH.equals(action)
4440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                || MediaStore.INTENT_ACTION_MEDIA_SEARCH.equals(action)
44558d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins                || Intent.ACTION_WEB_SEARCH.equals(action)
44658d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins                || activateVoiceSearch) {
4473b18ce37c13fce7212948df90a012d7011924a6eLeon Scroggins            if (current.isInVoiceSearchMode()) {
4483b18ce37c13fce7212948df90a012d7011924a6eLeon Scroggins                String title = current.getVoiceDisplayTitle();
4493b18ce37c13fce7212948df90a012d7011924a6eLeon Scroggins                if (title != null && title.equals(intent.getStringExtra(
4503b18ce37c13fce7212948df90a012d7011924a6eLeon Scroggins                        SearchManager.QUERY))) {
4513b18ce37c13fce7212948df90a012d7011924a6eLeon Scroggins                    // The user submitted the same search as the last voice
4523b18ce37c13fce7212948df90a012d7011924a6eLeon Scroggins                    // search, so do nothing.
4533b18ce37c13fce7212948df90a012d7011924a6eLeon Scroggins                    return;
4543b18ce37c13fce7212948df90a012d7011924a6eLeon Scroggins                }
4551fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins                if (Intent.ACTION_SEARCH.equals(action)
4561fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins                        && current.voiceSearchSourceIsGoogle()) {
4571fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins                    Intent logIntent = new Intent(
4581fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins                            LoggingEvents.ACTION_LOG_EVENT);
4591fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins                    logIntent.putExtra(LoggingEvents.EXTRA_EVENT,
4601fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins                            LoggingEvents.VoiceSearch.QUERY_UPDATED);
4611fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins                    logIntent.putExtra(
4621fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins                            LoggingEvents.VoiceSearch.EXTRA_QUERY_UPDATED_VALUE,
4631fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins                            intent.getDataString());
4641fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins                    sendBroadcast(logIntent);
4651fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins                    // Note, onPageStarted will revert the voice title bar
4661fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins                    // When http://b/issue?id=2379215 is fixed, we should update
4671fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins                    // the title bar here.
4681fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins                }
4693b18ce37c13fce7212948df90a012d7011924a6eLeon Scroggins            }
470565505b1a2c1d3099496af5910760087602e994aSatish Sampath            // If this was a search request (e.g. search query directly typed into the address bar),
471565505b1a2c1d3099496af5910760087602e994aSatish Sampath            // pass it on to the default web search provider.
472565505b1a2c1d3099496af5910760087602e994aSatish Sampath            if (handleWebSearchIntent(intent)) {
473565505b1a2c1d3099496af5910760087602e994aSatish Sampath                return;
474565505b1a2c1d3099496af5910760087602e994aSatish Sampath            }
475565505b1a2c1d3099496af5910760087602e994aSatish Sampath
47625ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima            UrlData urlData = getUrlDataFromIntent(intent);
47725ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima            if (urlData.isEmpty()) {
47825ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima                urlData = new UrlData(mSettings.getHomePage());
4790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
48025ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima
481cc63403643786905262f505ab5266d8e80b9924cGrace Kloba            final String appId = intent
482cc63403643786905262f505ab5266d8e80b9924cGrace Kloba                    .getStringExtra(Browser.EXTRA_APPLICATION_ID);
4834720868afa09efffadd845019f2d8268ae3f2c78Leon Scroggins            if ((Intent.ACTION_VIEW.equals(action)
4844720868afa09efffadd845019f2d8268ae3f2c78Leon Scroggins                    // If a voice search has no appId, it means that it came
4854720868afa09efffadd845019f2d8268ae3f2c78Leon Scroggins                    // from the browser.  In that case, reuse the current tab.
4864720868afa09efffadd845019f2d8268ae3f2c78Leon Scroggins                    || (activateVoiceSearch && appId != null))
487cc63403643786905262f505ab5266d8e80b9924cGrace Kloba                    && !getPackageName().equals(appId)
488cc63403643786905262f505ab5266d8e80b9924cGrace Kloba                    && (flags & Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT) != 0) {
48922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                Tab appTab = mTabControl.getTabFromId(appId);
490f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                if (appTab != null) {
491f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    Log.i(LOGTAG, "Reusing tab for " + appId);
492f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    // Dismiss the subwindow if applicable.
493f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    dismissSubWindow(appTab);
494f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    // Since we might kill the WebView, remove it from the
495f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    // content view first.
496f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    removeTabFromContentView(appTab);
497f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    // Recreate the main WebView after destroying the old one.
498f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    // If the WebView has the same original url and is on that
499f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    // page, it can be reused.
500f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    boolean needsLoad =
5016eac63e78d43d04e31c4d16830c44c4d9df82639Leon Scroggins                            mTabControl.recreateWebView(appTab, urlData);
502bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch
503f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    if (current != appTab) {
5041f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                        switchToTab(mTabControl.getTabIndex(appTab));
5051f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                        if (needsLoad) {
5069d53da05812f959745810a33bb4e06b273393c42Patrick Scott                            loadUrlDataIn(appTab, urlData);
5071f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                        }
508f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    } else {
5091f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                        // If the tab was the current tab, we have to attach
5101f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                        // it to the view system again.
5111f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                        attachTabToContentView(appTab);
5121f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                        if (needsLoad) {
5139d53da05812f959745810a33bb4e06b273393c42Patrick Scott                            loadUrlDataIn(appTab, urlData);
514f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                        }
515f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    }
516f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    return;
517cd11589fc3930906d4b9b7dd18aa52a9f1eb0c8aPatrick Scott                } else {
518cd11589fc3930906d4b9b7dd18aa52a9f1eb0c8aPatrick Scott                    // No matching application tab, try to find a regular tab
519cd11589fc3930906d4b9b7dd18aa52a9f1eb0c8aPatrick Scott                    // with a matching url.
520cd11589fc3930906d4b9b7dd18aa52a9f1eb0c8aPatrick Scott                    appTab = mTabControl.findUnusedTabWithUrl(urlData.mUrl);
52125515f8bd458a2471d13d876cfb0e18d8ff2a00fLeon Scroggins                    if (appTab != null) {
52225515f8bd458a2471d13d876cfb0e18d8ff2a00fLeon Scroggins                        if (current != appTab) {
52325515f8bd458a2471d13d876cfb0e18d8ff2a00fLeon Scroggins                            switchToTab(mTabControl.getTabIndex(appTab));
52425515f8bd458a2471d13d876cfb0e18d8ff2a00fLeon Scroggins                        }
52525515f8bd458a2471d13d876cfb0e18d8ff2a00fLeon Scroggins                        // Otherwise, we are already viewing the correct tab.
526cd11589fc3930906d4b9b7dd18aa52a9f1eb0c8aPatrick Scott                    } else {
527cd11589fc3930906d4b9b7dd18aa52a9f1eb0c8aPatrick Scott                        // if FLAG_ACTIVITY_BROUGHT_TO_FRONT flag is on, the url
528cd11589fc3930906d4b9b7dd18aa52a9f1eb0c8aPatrick Scott                        // will be opened in a new tab unless we have reached
529cd11589fc3930906d4b9b7dd18aa52a9f1eb0c8aPatrick Scott                        // MAX_TABS. Then the url will be opened in the current
530cd11589fc3930906d4b9b7dd18aa52a9f1eb0c8aPatrick Scott                        // tab. If a new tab is created, it will have "true" for
531cd11589fc3930906d4b9b7dd18aa52a9f1eb0c8aPatrick Scott                        // exit on close.
5321f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                        openTabAndShow(urlData, true, appId);
533cd11589fc3930906d4b9b7dd18aa52a9f1eb0c8aPatrick Scott                    }
534f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                }
5350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } else {
536638d3f45791a31d0b290e180b93bad49576eb6d3Grace Kloba                if (!urlData.isEmpty()
537638d3f45791a31d0b290e180b93bad49576eb6d3Grace Kloba                        && urlData.mUrl.startsWith("about:debug")) {
538638d3f45791a31d0b290e180b93bad49576eb6d3Grace Kloba                    if ("about:debug.dom".equals(urlData.mUrl)) {
539638d3f45791a31d0b290e180b93bad49576eb6d3Grace Kloba                        current.getWebView().dumpDomTree(false);
540638d3f45791a31d0b290e180b93bad49576eb6d3Grace Kloba                    } else if ("about:debug.dom.file".equals(urlData.mUrl)) {
541638d3f45791a31d0b290e180b93bad49576eb6d3Grace Kloba                        current.getWebView().dumpDomTree(true);
542638d3f45791a31d0b290e180b93bad49576eb6d3Grace Kloba                    } else if ("about:debug.render".equals(urlData.mUrl)) {
543638d3f45791a31d0b290e180b93bad49576eb6d3Grace Kloba                        current.getWebView().dumpRenderTree(false);
544638d3f45791a31d0b290e180b93bad49576eb6d3Grace Kloba                    } else if ("about:debug.render.file".equals(urlData.mUrl)) {
545638d3f45791a31d0b290e180b93bad49576eb6d3Grace Kloba                        current.getWebView().dumpRenderTree(true);
546638d3f45791a31d0b290e180b93bad49576eb6d3Grace Kloba                    } else if ("about:debug.display".equals(urlData.mUrl)) {
547638d3f45791a31d0b290e180b93bad49576eb6d3Grace Kloba                        current.getWebView().dumpDisplayTree();
5489b78e1d1e0bd819ae03df5594d4a56519e5d87c7Mike Reed                    } else if (urlData.mUrl.startsWith("about:debug.drag")) {
5499b78e1d1e0bd819ae03df5594d4a56519e5d87c7Mike Reed                        int index = urlData.mUrl.codePointAt(16) - '0';
5509b78e1d1e0bd819ae03df5594d4a56519e5d87c7Mike Reed                        if (index <= 0 || index > 9) {
5519b78e1d1e0bd819ae03df5594d4a56519e5d87c7Mike Reed                            current.getWebView().setDragTracker(null);
5529b78e1d1e0bd819ae03df5594d4a56519e5d87c7Mike Reed                        } else {
5539b78e1d1e0bd819ae03df5594d4a56519e5d87c7Mike Reed                            current.getWebView().setDragTracker(new MeshTracker(index));
5549b78e1d1e0bd819ae03df5594d4a56519e5d87c7Mike Reed                        }
555638d3f45791a31d0b290e180b93bad49576eb6d3Grace Kloba                    } else {
556638d3f45791a31d0b290e180b93bad49576eb6d3Grace Kloba                        mSettings.toggleDebugSettings();
557638d3f45791a31d0b290e180b93bad49576eb6d3Grace Kloba                    }
5580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    return;
5590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
5601f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                // Get rid of the subwindow if it exists
5611f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                dismissSubWindow(current);
5628588d15a7c0b87049469fd80f9c53eb274cd837bLeon Scroggins                // If the current Tab is being used as an application tab,
5638588d15a7c0b87049469fd80f9c53eb274cd837bLeon Scroggins                // remove the association, since the new Intent means that it is
5648588d15a7c0b87049469fd80f9c53eb274cd837bLeon Scroggins                // no longer associated with that application.
5658588d15a7c0b87049469fd80f9c53eb274cd837bLeon Scroggins                current.setAppId(null);
5669d53da05812f959745810a33bb4e06b273393c42Patrick Scott                loadUrlDataIn(current, urlData);
5670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
5680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
5690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
5700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
571565505b1a2c1d3099496af5910760087602e994aSatish Sampath    private int parseUrlShortcut(String url) {
572565505b1a2c1d3099496af5910760087602e994aSatish Sampath        if (url == null) return SHORTCUT_INVALID;
573565505b1a2c1d3099496af5910760087602e994aSatish Sampath
574565505b1a2c1d3099496af5910760087602e994aSatish Sampath        // FIXME: quick search, need to be customized by setting
575565505b1a2c1d3099496af5910760087602e994aSatish Sampath        if (url.length() > 2 && url.charAt(1) == ' ') {
576565505b1a2c1d3099496af5910760087602e994aSatish Sampath            switch (url.charAt(0)) {
577565505b1a2c1d3099496af5910760087602e994aSatish Sampath            case 'g': return SHORTCUT_GOOGLE_SEARCH;
578565505b1a2c1d3099496af5910760087602e994aSatish Sampath            case 'w': return SHORTCUT_WIKIPEDIA_SEARCH;
579565505b1a2c1d3099496af5910760087602e994aSatish Sampath            case 'd': return SHORTCUT_DICTIONARY_SEARCH;
580565505b1a2c1d3099496af5910760087602e994aSatish Sampath            case 'l': return SHORTCUT_GOOGLE_MOBILE_LOCAL_SEARCH;
581565505b1a2c1d3099496af5910760087602e994aSatish Sampath            }
582565505b1a2c1d3099496af5910760087602e994aSatish Sampath        }
583565505b1a2c1d3099496af5910760087602e994aSatish Sampath        return SHORTCUT_INVALID;
584565505b1a2c1d3099496af5910760087602e994aSatish Sampath    }
585565505b1a2c1d3099496af5910760087602e994aSatish Sampath
586565505b1a2c1d3099496af5910760087602e994aSatish Sampath    /**
587565505b1a2c1d3099496af5910760087602e994aSatish Sampath     * Launches the default web search activity with the query parameters if the given intent's data
588565505b1a2c1d3099496af5910760087602e994aSatish Sampath     * are identified as plain search terms and not URLs/shortcuts.
589565505b1a2c1d3099496af5910760087602e994aSatish Sampath     * @return true if the intent was handled and web search activity was launched, false if not.
590565505b1a2c1d3099496af5910760087602e994aSatish Sampath     */
591565505b1a2c1d3099496af5910760087602e994aSatish Sampath    private boolean handleWebSearchIntent(Intent intent) {
592565505b1a2c1d3099496af5910760087602e994aSatish Sampath        if (intent == null) return false;
593565505b1a2c1d3099496af5910760087602e994aSatish Sampath
594565505b1a2c1d3099496af5910760087602e994aSatish Sampath        String url = null;
595565505b1a2c1d3099496af5910760087602e994aSatish Sampath        final String action = intent.getAction();
596a1cc3fdce19a336c251297c61cd83ac6cf767cd1Leon Scroggins        if (RecognizerResultsIntent.ACTION_VOICE_SEARCH_RESULTS.equals(
597a1cc3fdce19a336c251297c61cd83ac6cf767cd1Leon Scroggins                action)) {
59858d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins            return false;
59958d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        }
600565505b1a2c1d3099496af5910760087602e994aSatish Sampath        if (Intent.ACTION_VIEW.equals(action)) {
6011e70505659dd9bf0f7e03bce787ba880f9b7a8aaGrace Kloba            Uri data = intent.getData();
6021e70505659dd9bf0f7e03bce787ba880f9b7a8aaGrace Kloba            if (data != null) url = data.toString();
603565505b1a2c1d3099496af5910760087602e994aSatish Sampath        } else if (Intent.ACTION_SEARCH.equals(action)
604565505b1a2c1d3099496af5910760087602e994aSatish Sampath                || MediaStore.INTENT_ACTION_MEDIA_SEARCH.equals(action)
605565505b1a2c1d3099496af5910760087602e994aSatish Sampath                || Intent.ACTION_WEB_SEARCH.equals(action)) {
606565505b1a2c1d3099496af5910760087602e994aSatish Sampath            url = intent.getStringExtra(SearchManager.QUERY);
607565505b1a2c1d3099496af5910760087602e994aSatish Sampath        }
6080485170e03e079eb61b9dd52fc2c98da02fa7b2cBjorn Bringert        return handleWebSearchRequest(url, intent.getBundleExtra(SearchManager.APP_DATA),
6090485170e03e079eb61b9dd52fc2c98da02fa7b2cBjorn Bringert                intent.getStringExtra(SearchManager.EXTRA_DATA_KEY));
610565505b1a2c1d3099496af5910760087602e994aSatish Sampath    }
611565505b1a2c1d3099496af5910760087602e994aSatish Sampath
612565505b1a2c1d3099496af5910760087602e994aSatish Sampath    /**
613565505b1a2c1d3099496af5910760087602e994aSatish Sampath     * Launches the default web search activity with the query parameters if the given url string
614565505b1a2c1d3099496af5910760087602e994aSatish Sampath     * was identified as plain search terms and not URL/shortcut.
615565505b1a2c1d3099496af5910760087602e994aSatish Sampath     * @return true if the request was handled and web search activity was launched, false if not.
616565505b1a2c1d3099496af5910760087602e994aSatish Sampath     */
6170485170e03e079eb61b9dd52fc2c98da02fa7b2cBjorn Bringert    private boolean handleWebSearchRequest(String inUrl, Bundle appData, String extraData) {
618565505b1a2c1d3099496af5910760087602e994aSatish Sampath        if (inUrl == null) return false;
619565505b1a2c1d3099496af5910760087602e994aSatish Sampath
620565505b1a2c1d3099496af5910760087602e994aSatish Sampath        // In general, we shouldn't modify URL from Intent.
621565505b1a2c1d3099496af5910760087602e994aSatish Sampath        // But currently, we get the user-typed URL from search box as well.
622565505b1a2c1d3099496af5910760087602e994aSatish Sampath        String url = fixUrl(inUrl).trim();
623565505b1a2c1d3099496af5910760087602e994aSatish Sampath
624565505b1a2c1d3099496af5910760087602e994aSatish Sampath        // URLs and site specific search shortcuts are handled by the regular flow of control, so
625565505b1a2c1d3099496af5910760087602e994aSatish Sampath        // return early.
6265ee906c089567bca705e18561357510d7b55cb5aDan Egnor        if (Patterns.WEB_URL.matcher(url).matches()
627bc5b9f358a2b75bf3a104b9f5cd477ad2f6f740fSatish Sampath                || ACCEPTED_URI_SCHEMA.matcher(url).matches()
628565505b1a2c1d3099496af5910760087602e994aSatish Sampath                || parseUrlShortcut(url) != SHORTCUT_INVALID) {
629565505b1a2c1d3099496af5910760087602e994aSatish Sampath            return false;
630565505b1a2c1d3099496af5910760087602e994aSatish Sampath        }
631565505b1a2c1d3099496af5910760087602e994aSatish Sampath
6328d06e36fe80f516e04ad33ff8b446720e36cabfdLeon Scroggins        final ContentResolver cr = mResolver;
6338d06e36fe80f516e04ad33ff8b446720e36cabfdLeon Scroggins        final String newUrl = url;
6348d06e36fe80f516e04ad33ff8b446720e36cabfdLeon Scroggins        new AsyncTask<Void, Void, Void>() {
6358d06e36fe80f516e04ad33ff8b446720e36cabfdLeon Scroggins            protected Void doInBackground(Void... unused) {
6368d06e36fe80f516e04ad33ff8b446720e36cabfdLeon Scroggins                Browser.updateVisitedHistory(cr, newUrl, false);
6378d06e36fe80f516e04ad33ff8b446720e36cabfdLeon Scroggins                Browser.addSearchUrl(cr, newUrl);
6388d06e36fe80f516e04ad33ff8b446720e36cabfdLeon Scroggins                return null;
6398d06e36fe80f516e04ad33ff8b446720e36cabfdLeon Scroggins            }
6408d06e36fe80f516e04ad33ff8b446720e36cabfdLeon Scroggins        }.execute();
641565505b1a2c1d3099496af5910760087602e994aSatish Sampath
642565505b1a2c1d3099496af5910760087602e994aSatish Sampath        Intent intent = new Intent(Intent.ACTION_WEB_SEARCH);
643565505b1a2c1d3099496af5910760087602e994aSatish Sampath        intent.addCategory(Intent.CATEGORY_DEFAULT);
644565505b1a2c1d3099496af5910760087602e994aSatish Sampath        intent.putExtra(SearchManager.QUERY, url);
64515e9f2dc92cf1621f95071b3c740f46079aa0f3bSatish Sampath        if (appData != null) {
64615e9f2dc92cf1621f95071b3c740f46079aa0f3bSatish Sampath            intent.putExtra(SearchManager.APP_DATA, appData);
64715e9f2dc92cf1621f95071b3c740f46079aa0f3bSatish Sampath        }
6480485170e03e079eb61b9dd52fc2c98da02fa7b2cBjorn Bringert        if (extraData != null) {
6490485170e03e079eb61b9dd52fc2c98da02fa7b2cBjorn Bringert            intent.putExtra(SearchManager.EXTRA_DATA_KEY, extraData);
6500485170e03e079eb61b9dd52fc2c98da02fa7b2cBjorn Bringert        }
651cc63403643786905262f505ab5266d8e80b9924cGrace Kloba        intent.putExtra(Browser.EXTRA_APPLICATION_ID, getPackageName());
652565505b1a2c1d3099496af5910760087602e994aSatish Sampath        startActivity(intent);
653565505b1a2c1d3099496af5910760087602e994aSatish Sampath
654565505b1a2c1d3099496af5910760087602e994aSatish Sampath        return true;
655565505b1a2c1d3099496af5910760087602e994aSatish Sampath    }
656565505b1a2c1d3099496af5910760087602e994aSatish Sampath
65725ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima    private UrlData getUrlDataFromIntent(Intent intent) {
65858d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        String url = "";
659068e48b469f5abca53ee3da38f933cf2c25c93b8Grace Kloba        Map<String, String> headers = null;
6600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (intent != null) {
6610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            final String action = intent.getAction();
6620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (Intent.ACTION_VIEW.equals(action)) {
6630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                url = smartUrlFilter(intent.getData());
6640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (url != null && url.startsWith("content:")) {
6650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    /* Append mimetype so webview knows how to display */
6660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    String mimeType = intent.resolveType(getContentResolver());
6670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    if (mimeType != null) {
6680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        url += "?" + mimeType;
6690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
6700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
671068e48b469f5abca53ee3da38f933cf2c25c93b8Grace Kloba                if (url != null && url.startsWith("http")) {
67200f54c589fd38431efd42ea2a551a49e64d595d5Grace Kloba                    final Bundle pairs = intent
67300f54c589fd38431efd42ea2a551a49e64d595d5Grace Kloba                            .getBundleExtra(Browser.EXTRA_HEADERS);
6742d508edbf54ea74cd4e89be8b622b1cbd587464aGrace Kloba                    if (pairs != null && !pairs.isEmpty()) {
67500f54c589fd38431efd42ea2a551a49e64d595d5Grace Kloba                        Iterator<String> iter = pairs.keySet().iterator();
676068e48b469f5abca53ee3da38f933cf2c25c93b8Grace Kloba                        headers = new HashMap<String, String>();
67700f54c589fd38431efd42ea2a551a49e64d595d5Grace Kloba                        while (iter.hasNext()) {
67800f54c589fd38431efd42ea2a551a49e64d595d5Grace Kloba                            String key = iter.next();
67900f54c589fd38431efd42ea2a551a49e64d595d5Grace Kloba                            headers.put(key, pairs.getString(key));
680068e48b469f5abca53ee3da38f933cf2c25c93b8Grace Kloba                        }
681068e48b469f5abca53ee3da38f933cf2c25c93b8Grace Kloba                    }
68225ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima                }
6830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } else if (Intent.ACTION_SEARCH.equals(action)
6840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    || MediaStore.INTENT_ACTION_MEDIA_SEARCH.equals(action)
6850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    || Intent.ACTION_WEB_SEARCH.equals(action)) {
6860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                url = intent.getStringExtra(SearchManager.QUERY);
6870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (url != null) {
6880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    mLastEnteredUrl = url;
6890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // In general, we shouldn't modify URL from Intent.
6900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // But currently, we get the user-typed URL from search box as well.
6910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    url = fixUrl(url);
6920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    url = smartUrlFilter(url);
6938d06e36fe80f516e04ad33ff8b446720e36cabfdLeon Scroggins                    final ContentResolver cr = mResolver;
6948d06e36fe80f516e04ad33ff8b446720e36cabfdLeon Scroggins                    final String newUrl = url;
6958d06e36fe80f516e04ad33ff8b446720e36cabfdLeon Scroggins                    new AsyncTask<Void, Void, Void>() {
6968d06e36fe80f516e04ad33ff8b446720e36cabfdLeon Scroggins                        protected Void doInBackground(Void... unused) {
6978d06e36fe80f516e04ad33ff8b446720e36cabfdLeon Scroggins                            Browser.updateVisitedHistory(cr, newUrl, false);
6988d06e36fe80f516e04ad33ff8b446720e36cabfdLeon Scroggins                            return null;
6998d06e36fe80f516e04ad33ff8b446720e36cabfdLeon Scroggins                        }
7008d06e36fe80f516e04ad33ff8b446720e36cabfdLeon Scroggins                    }.execute();
7010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    String searchSource = "&source=android-" + GOOGLE_SEARCH_SOURCE_SUGGEST + "&";
7020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    if (url.contains(searchSource)) {
7030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        String source = null;
7040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        final Bundle appData = intent.getBundleExtra(SearchManager.APP_DATA);
7050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        if (appData != null) {
70610d1cca0c208d1f9db23893a8515685e04cfe224Bjorn Bringert                            source = appData.getString(Search.SOURCE);
7070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }
7080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        if (TextUtils.isEmpty(source)) {
7090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            source = GOOGLE_SEARCH_SOURCE_UNKNOWN;
7100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }
7110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        url = url.replace(searchSource, "&source=android-"+source+"&");
7120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
7130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
7140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
7150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
71658d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        return new UrlData(url, headers, intent);
7170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
71858d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    /* package */ void showVoiceTitleBar(String title) {
71958d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        mTitleBar.setInVoiceMode(true);
72058d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        mTitleBar.setDisplayTitle(title);
721d746a94137a87ffcc1fcefdac9a3764c3bc3f5cdLeon Scroggins
722d746a94137a87ffcc1fcefdac9a3764c3bc3f5cdLeon Scroggins        if (!mXLargeScreenSize) {
723d746a94137a87ffcc1fcefdac9a3764c3bc3f5cdLeon Scroggins            mFakeTitleBar.setInVoiceMode(true);
724d746a94137a87ffcc1fcefdac9a3764c3bc3f5cdLeon Scroggins            mFakeTitleBar.setDisplayTitle(title);
725d746a94137a87ffcc1fcefdac9a3764c3bc3f5cdLeon Scroggins        }
72658d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    }
72758d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    /* package */ void revertVoiceTitleBar() {
72858d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        mTitleBar.setInVoiceMode(false);
729003a5ddf3a7ff1b30bfd82cddc8da49cb9fedf15Leon Scroggins        mTitleBar.setDisplayTitle(mUrl);
730d746a94137a87ffcc1fcefdac9a3764c3bc3f5cdLeon Scroggins
731d746a94137a87ffcc1fcefdac9a3764c3bc3f5cdLeon Scroggins        if (!mXLargeScreenSize) {
732d746a94137a87ffcc1fcefdac9a3764c3bc3f5cdLeon Scroggins            mFakeTitleBar.setInVoiceMode(false);
733d746a94137a87ffcc1fcefdac9a3764c3bc3f5cdLeon Scroggins            mFakeTitleBar.setDisplayTitle(mUrl);
734d746a94137a87ffcc1fcefdac9a3764c3bc3f5cdLeon Scroggins        }
73558d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    }
7360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /* package */ static String fixUrl(String inUrl) {
737652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark        // FIXME: Converting the url to lower case
738652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark        // duplicates functionality in smartUrlFilter().
739652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark        // However, changing all current callers of fixUrl to
740652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark        // call smartUrlFilter in addition may have unwanted
741652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark        // consequences, and is deferred for now.
742652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark        int colon = inUrl.indexOf(':');
743652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark        boolean allLower = true;
744652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark        for (int index = 0; index < colon; index++) {
745652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark            char ch = inUrl.charAt(index);
746652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark            if (!Character.isLetter(ch)) {
747652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark                break;
748652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark            }
749652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark            allLower &= Character.isLowerCase(ch);
750652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark            if (index == colon - 1 && !allLower) {
751652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark                inUrl = inUrl.substring(0, colon).toLowerCase()
752652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark                        + inUrl.substring(colon);
753652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark            }
754652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark        }
7550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (inUrl.startsWith("http://") || inUrl.startsWith("https://"))
7560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return inUrl;
7570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (inUrl.startsWith("http:") ||
7580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                inUrl.startsWith("https:")) {
7590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (inUrl.startsWith("http:/") || inUrl.startsWith("https:/")) {
7600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                inUrl = inUrl.replaceFirst("/", "//");
7610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } else inUrl = inUrl.replaceFirst(":", "://");
7620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
7630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return inUrl;
7640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
7650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
76622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    @Override
76722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    protected void onResume() {
7680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        super.onResume();
76931a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort        if (LOGV_ENABLED) {
7700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Log.v(LOGTAG, "BrowserActivity.onResume: this=" + this);
7710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
7720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
7730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (!mActivityInPause) {
7740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Log.e(LOGTAG, "BrowserActivity is already resumed.");
7750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
7760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
7770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
7787bfa63b55644fbf2da1fe6a24b3be0267529202cMike Reed        mTabControl.resumeCurrentTab();
7790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mActivityInPause = false;
7807bfa63b55644fbf2da1fe6a24b3be0267529202cMike Reed        resumeWebViewTimers();
7810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
7820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mWakeLock.isHeld()) {
7830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mHandler.removeMessages(RELEASE_WAKELOCK);
7840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mWakeLock.release();
7850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
7860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
7870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        registerReceiver(mNetworkStateIntentReceiver,
7880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                         mNetworkStateChangedFilter);
7890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebView.enablePlatformNotifications();
7900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
7910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
7923bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    /**
7933bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     * Since the actual title bar is embedded in the WebView, and removing it
794fe87bd3a3897e4bad65bb3d284659ae2f4e57570Leon Scroggins     * would change its appearance, use a different TitleBar to show overlayed
795fe87bd3a3897e4bad65bb3d284659ae2f4e57570Leon Scroggins     * at the top of the screen, when the menu is open or the page is loading.
7963bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     */
7973bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    private TitleBar mFakeTitleBar;
7983bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins
7993bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    /**
8003bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     * Keeps track of whether the options menu is open.  This is important in
8013bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     * determining whether to show or hide the title bar overlay.
8023bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     */
8033bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    private boolean mOptionsMenuOpen;
8043bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins
8053bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    /**
8063bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     * Only meaningful when mOptionsMenuOpen is true.  This variable keeps track
8073bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     * of whether the configuration has changed.  The first onMenuOpened call
8083bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     * after a configuration change is simply a reopening of the same menu
8093bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     * (i.e. mIconView did not change).
8103bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     */
8113bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    private boolean mConfigChanged;
8123bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins
8133bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    /**
8143bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     * Whether or not the options menu is in its smaller, icon menu form.  When
8153bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     * true, we want the title bar overlay to be up.  When false, we do not.
8163bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     * Only meaningful if mOptionsMenuOpen is true.
8173bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     */
8183bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    private boolean mIconView;
8193bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins
820a81a764063d2f849fba0cbc3039f86e67c2960ddLeon Scroggins    @Override
821a81a764063d2f849fba0cbc3039f86e67c2960ddLeon Scroggins    public boolean onMenuOpened(int featureId, Menu menu) {
8223bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins        if (Window.FEATURE_OPTIONS_PANEL == featureId) {
8233bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins            if (mOptionsMenuOpen) {
8243bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                if (mConfigChanged) {
8253bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                    // We do not need to make any changes to the state of the
8263bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                    // title bar, since the only thing that happened was a
8273bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                    // change in orientation
8283bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                    mConfigChanged = false;
8293bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                } else {
8303bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                    if (mIconView) {
8313bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                        // Switching the menu to expanded view, so hide the
8323bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                        // title bar.
8333bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                        hideFakeTitleBar();
8343bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                        mIconView = false;
8353bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                    } else {
8363bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                        // Switching the menu back to icon view, so show the
8373bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                        // title bar once again.
8383bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                        showFakeTitleBar();
8393bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                        mIconView = true;
8403bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                    }
8413bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                }
8423bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins            } else {
8433bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                // The options menu is closed, so open it, and show the title
8443bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                showFakeTitleBar();
8453bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                mOptionsMenuOpen = true;
8463bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                mConfigChanged = false;
8473bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                mIconView = true;
8483bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins            }
8493bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins        }
850a81a764063d2f849fba0cbc3039f86e67c2960ddLeon Scroggins        return true;
851a81a764063d2f849fba0cbc3039f86e67c2960ddLeon Scroggins    }
852a81a764063d2f849fba0cbc3039f86e67c2960ddLeon Scroggins
8533bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    private void showFakeTitleBar() {
854d746a94137a87ffcc1fcefdac9a3764c3bc3f5cdLeon Scroggins        if (mXLargeScreenSize) return;
855fe87bd3a3897e4bad65bb3d284659ae2f4e57570Leon Scroggins        if (mFakeTitleBar.getParent() == null && mActiveTabsPage == null
856847c25b877f1c912fe54ba7d3890df7ed3798e47Grace Kloba                && !mActivityInPause) {
857847c25b877f1c912fe54ba7d3890df7ed3798e47Grace Kloba            WebView mainView = mTabControl.getCurrentWebView();
858847c25b877f1c912fe54ba7d3890df7ed3798e47Grace Kloba            // if there is no current WebView, don't show the faked title bar;
85965190702c53f2d3ceb8e3c88d707bd6ff874034cGrace Kloba            if (mainView == null) {
860a04645545690d9f637ccae4d043a5a1b8478a832Cary Clark                return;
861a04645545690d9f637ccae4d043a5a1b8478a832Cary Clark            }
86279e36d97b67bf06b1e0c0edf773882e93a3293e4Leon Scroggins            // Do not need to check for null, since the current tab will have
86379e36d97b67bf06b1e0c0edf773882e93a3293e4Leon Scroggins            // at least a main WebView, or we would have returned above.
86479e36d97b67bf06b1e0c0edf773882e93a3293e4Leon Scroggins            if (getTopWindow().getFindIsUp()) {
86579e36d97b67bf06b1e0c0edf773882e93a3293e4Leon Scroggins                // Do not show the fake title bar, which would cover up the
86679e36d97b67bf06b1e0c0edf773882e93a3293e4Leon Scroggins                // FindDialog.
86779e36d97b67bf06b1e0c0edf773882e93a3293e4Leon Scroggins                return;
86879e36d97b67bf06b1e0c0edf773882e93a3293e4Leon Scroggins            }
8693bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins
8703bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins            WindowManager manager
8713bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                    = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
8723bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins
8733bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins            // Add the title bar to the window manager so it can receive touches
8743bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins            // while the menu is up
8753bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins            WindowManager.LayoutParams params
8763bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                    = new WindowManager.LayoutParams(
87715b8ec6b226f4d57307716e1f495e10a91f8cbf4Romain Guy                    ViewGroup.LayoutParams.MATCH_PARENT,
8783bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                    ViewGroup.LayoutParams.WRAP_CONTENT,
879847c25b877f1c912fe54ba7d3890df7ed3798e47Grace Kloba                    WindowManager.LayoutParams.TYPE_APPLICATION,
8803bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                    WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
881685498685d8424f48d77d26d8d5790da34645f44Leon Scroggins                    PixelFormat.TRANSLUCENT);
8823bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins            params.gravity = Gravity.TOP;
883847c25b877f1c912fe54ba7d3890df7ed3798e47Grace Kloba            boolean atTop = mainView.getScrollY() == 0;
88483932c74ba031eb2f581f1557c1a90f4b5bbb423Leon Scroggins            params.windowAnimations = atTop ? 0 : R.style.TitleBar;
88513f9aced9c949d452a5cb44ffc55c82f97871c89Grace Kloba            manager.addView(mFakeTitleBar, params);
8863bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins        }
8873bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    }
8883bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins
8893bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    @Override
8903bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    public void onOptionsMenuClosed(Menu menu) {
8913bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins        mOptionsMenuOpen = false;
892a27ff19e24cb1c9fef5624dbc4554548349b5b31Leon Scroggins        if (!mInLoad) {
893a27ff19e24cb1c9fef5624dbc4554548349b5b31Leon Scroggins            hideFakeTitleBar();
894a27ff19e24cb1c9fef5624dbc4554548349b5b31Leon Scroggins        } else if (!mIconView) {
895a27ff19e24cb1c9fef5624dbc4554548349b5b31Leon Scroggins            // The page is currently loading, and we are in expanded mode, so
896a27ff19e24cb1c9fef5624dbc4554548349b5b31Leon Scroggins            // we were not showing the menu.  Show it once again.  It will be
897a27ff19e24cb1c9fef5624dbc4554548349b5b31Leon Scroggins            // removed when the page finishes.
898a27ff19e24cb1c9fef5624dbc4554548349b5b31Leon Scroggins            showFakeTitleBar();
899a27ff19e24cb1c9fef5624dbc4554548349b5b31Leon Scroggins        }
9003bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    }
90122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
9023bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    private void hideFakeTitleBar() {
903d746a94137a87ffcc1fcefdac9a3764c3bc3f5cdLeon Scroggins        if (mXLargeScreenSize || mFakeTitleBar.getParent() == null) return;
90420329570ba9409637298da90b83f25801d7a3d55Leon Scroggins        WindowManager.LayoutParams params = (WindowManager.LayoutParams)
90513f9aced9c949d452a5cb44ffc55c82f97871c89Grace Kloba                mFakeTitleBar.getLayoutParams();
90620329570ba9409637298da90b83f25801d7a3d55Leon Scroggins        WebView mainView = mTabControl.getCurrentWebView();
90720329570ba9409637298da90b83f25801d7a3d55Leon Scroggins        // Although we decided whether or not to animate based on the current
90820329570ba9409637298da90b83f25801d7a3d55Leon Scroggins        // scroll position, the scroll position may have changed since the
90920329570ba9409637298da90b83f25801d7a3d55Leon Scroggins        // fake title bar was displayed.  Make sure it has the appropriate
91020329570ba9409637298da90b83f25801d7a3d55Leon Scroggins        // animation/lack thereof before removing.
91120329570ba9409637298da90b83f25801d7a3d55Leon Scroggins        params.windowAnimations = mainView != null && mainView.getScrollY() == 0
91283932c74ba031eb2f581f1557c1a90f4b5bbb423Leon Scroggins                ? 0 : R.style.TitleBar;
9133bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins        WindowManager manager
9143bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                    = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
91513f9aced9c949d452a5cb44ffc55c82f97871c89Grace Kloba        manager.updateViewLayout(mFakeTitleBar, params);
91613f9aced9c949d452a5cb44ffc55c82f97871c89Grace Kloba        manager.removeView(mFakeTitleBar);
9173bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    }
9183bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins
9190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
920c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins     * Special method for the fake title bar to call when displaying its context
921c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins     * menu, since it is in its own Window, and its parent does not show a
922c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins     * context menu.
923c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins     */
924c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins    /* package */ void showTitleBarContextMenu() {
92565f4a3ce9e5c4a5227bbcbb995e5e15f1f85d3d7Cary Clark        if (null == mTitleBar.getParent()) {
92665f4a3ce9e5c4a5227bbcbb995e5e15f1f85d3d7Cary Clark            return;
92765f4a3ce9e5c4a5227bbcbb995e5e15f1f85d3d7Cary Clark        }
928c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins        openContextMenu(mTitleBar);
929c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins    }
930c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins
931b2b19f501ee05448ca81bddaaca70e9b2f51cb54Leon Scroggins    @Override
932b2b19f501ee05448ca81bddaaca70e9b2f51cb54Leon Scroggins    public void onContextMenuClosed(Menu menu) {
933b2b19f501ee05448ca81bddaaca70e9b2f51cb54Leon Scroggins        super.onContextMenuClosed(menu);
934b2b19f501ee05448ca81bddaaca70e9b2f51cb54Leon Scroggins        if (mInLoad) {
935b2b19f501ee05448ca81bddaaca70e9b2f51cb54Leon Scroggins            showFakeTitleBar();
936b2b19f501ee05448ca81bddaaca70e9b2f51cb54Leon Scroggins        }
937b2b19f501ee05448ca81bddaaca70e9b2f51cb54Leon Scroggins    }
938b2b19f501ee05448ca81bddaaca70e9b2f51cb54Leon Scroggins
939c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins    /**
9400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *  onSaveInstanceState(Bundle map)
9410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *  onSaveInstanceState is called right before onStop(). The map contains
9420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *  the saved state.
9430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
94422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    @Override
94522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    protected void onSaveInstanceState(Bundle outState) {
94631a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort        if (LOGV_ENABLED) {
9470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Log.v(LOGTAG, "BrowserActivity.onSaveInstanceState: this=" + this);
9480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
9490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // the default implementation requires each view to have an id. As the
9500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // browser handles the state itself and it doesn't use id for the views,
9510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // don't call the default implementation. Otherwise it will trigger the
9520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // warning like this, "couldn't save which view has focus because the
9530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // focused view XXX has no id".
9540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
9550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Save all the tabs
9560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mTabControl.saveState(outState);
9570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
9580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
95922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    @Override
96022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    protected void onPause() {
9610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        super.onPause();
9620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
9630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mActivityInPause) {
9640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Log.e(LOGTAG, "BrowserActivity is already paused.");
9650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
9660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
9670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
9687bfa63b55644fbf2da1fe6a24b3be0267529202cMike Reed        mTabControl.pauseCurrentTab();
9690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mActivityInPause = true;
9707bfa63b55644fbf2da1fe6a24b3be0267529202cMike Reed        if (mTabControl.getCurrentIndex() >= 0 && !pauseWebViewTimers()) {
9710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mWakeLock.acquire();
9720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mHandler.sendMessageDelayed(mHandler
9730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    .obtainMessage(RELEASE_WAKELOCK), WAKELOCK_TIMEOUT);
9740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
9750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
976a2ab6a7dc0f7023c1d7ebb1cbad397c5dc3d6453Leon Scroggins        // FIXME: This removes the active tabs page and resets the menu to
977a2ab6a7dc0f7023c1d7ebb1cbad397c5dc3d6453Leon Scroggins        // MAIN_MENU.  A better solution might be to do this work in onNewIntent
978a2ab6a7dc0f7023c1d7ebb1cbad397c5dc3d6453Leon Scroggins        // but then we would need to save it in onSaveInstanceState and restore
979a2ab6a7dc0f7023c1d7ebb1cbad397c5dc3d6453Leon Scroggins        // it in onCreate/onRestoreInstanceState
980a2ab6a7dc0f7023c1d7ebb1cbad397c5dc3d6453Leon Scroggins        if (mActiveTabsPage != null) {
981a2ab6a7dc0f7023c1d7ebb1cbad397c5dc3d6453Leon Scroggins            removeActiveTabPage(true);
982a2ab6a7dc0f7023c1d7ebb1cbad397c5dc3d6453Leon Scroggins        }
983a2ab6a7dc0f7023c1d7ebb1cbad397c5dc3d6453Leon Scroggins
9840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        cancelStopToast();
9850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
9860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // unregister network state listener
9870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        unregisterReceiver(mNetworkStateIntentReceiver);
9880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebView.disablePlatformNotifications();
9890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
9900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
99122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    @Override
99222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    protected void onDestroy() {
99331a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort        if (LOGV_ENABLED) {
9940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Log.v(LOGTAG, "BrowserActivity.onDestroy: this=" + this);
9950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
9960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        super.onDestroy();
9970923d69a8ca45222cabd82a80eaa88da9f132e9aGrace Kloba
9988d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins        if (mUploadMessage != null) {
9998d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins            mUploadMessage.onReceiveValue(null);
10008d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins            mUploadMessage = null;
10018d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins        }
10028d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins
10030923d69a8ca45222cabd82a80eaa88da9f132e9aGrace Kloba        if (mTabControl == null) return;
10040923d69a8ca45222cabd82a80eaa88da9f132e9aGrace Kloba
10051fc98a322e9df6b0e797c26de6b2cb23d69ad5d3Grace Kloba        // Remove the fake title bar if it is there
10061fc98a322e9df6b0e797c26de6b2cb23d69ad5d3Grace Kloba        hideFakeTitleBar();
10071fc98a322e9df6b0e797c26de6b2cb23d69ad5d3Grace Kloba
10080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Remove the current tab and sub window
100922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        Tab t = mTabControl.getCurrentTab();
1010fb5e77fac7b8b311fe72827183f8988f5ee92a5fPatrick Scott        if (t != null) {
1011fb5e77fac7b8b311fe72827183f8988f5ee92a5fPatrick Scott            dismissSubWindow(t);
1012fb5e77fac7b8b311fe72827183f8988f5ee92a5fPatrick Scott            removeTabFromContentView(t);
1013fb5e77fac7b8b311fe72827183f8988f5ee92a5fPatrick Scott        }
10140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Destroy all the tabs
10150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mTabControl.destroy();
10160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebIconDatabase.getInstance().close();
10170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
1018b4da0ad0351996f639b50f9f29b123a9b5c24fd0Grace Kloba        unregisterReceiver(mPackageInstallationReceiver);
1019a7611811e0d744a7220b7bf80c8f795af5ea53edBjorn Bringert
1020a7611811e0d744a7220b7bf80c8f795af5ea53edBjorn Bringert        // Stop watching the default geolocation permissions
1021a7611811e0d744a7220b7bf80c8f795af5ea53edBjorn Bringert        mSystemAllowGeolocationOrigins.stop();
1022a7611811e0d744a7220b7bf80c8f795af5ea53edBjorn Bringert        mSystemAllowGeolocationOrigins = null;
10230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
10240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
10250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    @Override
10260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public void onConfigurationChanged(Configuration newConfig) {
10273bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins        mConfigChanged = true;
10280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        super.onConfigurationChanged(newConfig);
10290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
10300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mPageInfoDialog != null) {
10310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mPageInfoDialog.dismiss();
10320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            showPageInfo(
10330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mPageInfoView,
1034c7b92f811dfa3572578ddc6714c98a03936d9ce5Leon Scroggins                mPageInfoFromShowSSLCertificateOnError);
10350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
10360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mSSLCertificateDialog != null) {
10370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mSSLCertificateDialog.dismiss();
10380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            showSSLCertificate(
10390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mSSLCertificateView);
10400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
10410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mSSLCertificateOnErrorDialog != null) {
10420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mSSLCertificateOnErrorDialog.dismiss();
10430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            showSSLCertificateOnError(
10440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mSSLCertificateOnErrorView,
10450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mSSLCertificateOnErrorHandler,
10460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mSSLCertificateOnErrorError);
10470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
10480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mHttpAuthenticationDialog != null) {
10490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            String title = ((TextView) mHttpAuthenticationDialog
10500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    .findViewById(com.android.internal.R.id.alertTitle)).getText()
10510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    .toString();
10520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            String name = ((TextView) mHttpAuthenticationDialog
10530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    .findViewById(R.id.username_edit)).getText().toString();
10540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            String password = ((TextView) mHttpAuthenticationDialog
10550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    .findViewById(R.id.password_edit)).getText().toString();
10560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            int focusId = mHttpAuthenticationDialog.getCurrentFocus()
10570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    .getId();
10580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mHttpAuthenticationDialog.dismiss();
10590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            showHttpAuthentication(mHttpAuthHandler, null, null, title,
10600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    name, password, focusId);
10610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
10620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
10630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
106422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    @Override
106522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    public void onLowMemory() {
10660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        super.onLowMemory();
10670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mTabControl.freeMemory();
10680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
10690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
1070ff4d92ca529f8b77db67d0aea5d9988d5e390211Cary Clark    private void resumeWebViewTimers() {
107122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        Tab tab = mTabControl.getCurrentTab();
1072ff4d92ca529f8b77db67d0aea5d9988d5e390211Cary Clark        if (tab == null) return; // monkey can trigger this
107322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        boolean inLoad = tab.inLoad();
107422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if ((!mActivityInPause && !inLoad) || (mActivityInPause && inLoad)) {
10750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            CookieSyncManager.getInstance().startSync();
107622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            WebView w = tab.getWebView();
10770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (w != null) {
10780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                w.resumeTimers();
10790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
10800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
10810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
10820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
10837bfa63b55644fbf2da1fe6a24b3be0267529202cMike Reed    private boolean pauseWebViewTimers() {
108422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        Tab tab = mTabControl.getCurrentTab();
108522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        boolean inLoad = tab.inLoad();
108622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mActivityInPause && !inLoad) {
10870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            CookieSyncManager.getInstance().stopSync();
10880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            WebView w = mTabControl.getCurrentWebView();
10890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (w != null) {
10900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                w.pauseTimers();
10910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
10920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return true;
10930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
10940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return false;
10950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
10960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
10970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
10980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Open the icon database and retain all the icons for visited sites.
10990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void retainIconsOnStartup() {
11000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final WebIconDatabase db = WebIconDatabase.getInstance();
11010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        db.open(getDir("icons", 0).getPath());
11022c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins        Cursor c = null;
11030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        try {
11042c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins            c = Browser.getAllBookmarks(mResolver);
11052c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins            if (c.moveToFirst()) {
11062c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins                int urlIndex = c.getColumnIndex(Browser.BookmarkColumns.URL);
11072c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins                do {
11082c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins                    String url = c.getString(urlIndex);
11092c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins                    db.retainIconForPageUrl(url);
11102c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins                } while (c.moveToNext());
11110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
11120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } catch (IllegalStateException e) {
11130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Log.e(LOGTAG, "retainIconsOnStartup", e);
11142c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins        } finally {
11152c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins            if (c!= null) c.close();
11160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
11170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
11180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
11190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Helper method for getting the top window.
11200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    WebView getTopWindow() {
11210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return mTabControl.getCurrentTopWebView();
11220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
11230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
112422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    TabControl getTabControl() {
112522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return mTabControl;
112622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
112722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
11280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    @Override
11290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public boolean onCreateOptionsMenu(Menu menu) {
11300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        super.onCreateOptionsMenu(menu);
11310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
11320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        MenuInflater inflater = getMenuInflater();
11330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        inflater.inflate(R.menu.browser, menu);
11340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mMenu = menu;
11350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        updateInLoadMenuItems();
11360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return true;
11370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
11380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
11390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
11400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * As the menu can be open when loading state changes
11410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * we must manually update the state of the stop/reload menu
11420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * item
11430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
11440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void updateInLoadMenuItems() {
11450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mMenu == null) {
11460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
11470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
11480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        MenuItem src = mInLoad ?
11490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mMenu.findItem(R.id.stop_menu_id):
11500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    mMenu.findItem(R.id.reload_menu_id);
11510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        MenuItem dest = mMenu.findItem(R.id.stop_reload_menu_id);
11520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        dest.setIcon(src.getIcon());
11530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        dest.setTitle(src.getTitle());
11540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
11550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
11560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    @Override
11570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public boolean onContextItemSelected(MenuItem item) {
11580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // chording is not an issue with context menus, but we use the same
11590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // options selector, so set mCanChord to true so we can access them.
11600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mCanChord = true;
11610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        int id = item.getItemId();
116296afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins        boolean result = true;
11630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        switch (id) {
1164c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins            // For the context menu from the title bar
1165c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins            case R.id.title_bar_copy_page_url:
116696afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                Tab currentTab = mTabControl.getCurrentTab();
116796afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                if (null == currentTab) {
116896afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                    result = false;
116996afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                    break;
1170c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins                }
117196afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                WebView mainView = currentTab.getWebView();
117296afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                if (null == mainView) {
117396afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                    result = false;
117496afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                    break;
1175c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins                }
117696afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                copy(mainView.getUrl());
1177c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins                break;
11780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // -- Browser context menu
11790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.open_context_menu_id:
11800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.open_newtab_context_menu_id:
11810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.bookmark_context_menu_id:
11820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.save_link_context_menu_id:
11830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.share_link_context_menu_id:
11840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.copy_link_context_menu_id:
1185c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins                final WebView webView = getTopWindow();
1186c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins                if (null == webView) {
118796afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                    result = false;
118896afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                    break;
1189c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins                }
1190c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins                final HashMap hrefMap = new HashMap();
1191c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins                hrefMap.put("webview", webView);
1192c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins                final Message msg = mHandler.obtainMessage(
1193c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins                        FOCUS_NODE_HREF, id, 0, hrefMap);
11940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                webView.requestFocusNodeHref(msg);
11950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
11960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
11970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            default:
11980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // For other context menus
119996afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                result = onOptionsItemSelected(item);
12000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
12010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mCanChord = false;
120296afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins        return result;
12030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
12040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
12050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private Bundle createGoogleSearchSourceBundle(String source) {
12060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        Bundle bundle = new Bundle();
120710d1cca0c208d1f9db23893a8515685e04cfe224Bjorn Bringert        bundle.putString(Search.SOURCE, source);
12080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return bundle;
12090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
12100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
12118ad299270a97dfa3f9bcb956096bc152498fb727Leon Scroggins    /* package */ void editUrl() {
121268579393973f745fc65a2781061af9bb8f2d7020Leon Scroggins        if (mOptionsMenuOpen) closeOptionsMenu();
12135bbe98025a2c606a35c91b826760020890daadb1Leon Scroggins        String url = (getTopWindow() == null) ? null : getTopWindow().getUrl();
121483f473462fcd7869031a423c02b957c6e938a2f6Grace Kloba        startSearch(mSettings.getHomePage().equals(url) ? null : url, true,
12158ad299270a97dfa3f9bcb956096bc152498fb727Leon Scroggins                null, false);
12160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
12170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
12188ad299270a97dfa3f9bcb956096bc152498fb727Leon Scroggins    /**
12198ad299270a97dfa3f9bcb956096bc152498fb727Leon Scroggins     * Overriding this to insert a local information bundle
12208ad299270a97dfa3f9bcb956096bc152498fb727Leon Scroggins     */
12210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    @Override
12220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public void startSearch(String initialQuery, boolean selectInitialQuery,
12230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Bundle appSearchData, boolean globalSearch) {
12240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (appSearchData == null) {
12250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            appSearchData = createGoogleSearchSourceBundle(GOOGLE_SEARCH_SOURCE_TYPE);
12260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
12270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        super.startSearch(initialQuery, selectInitialQuery, appSearchData, globalSearch);
12280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
12290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
12301f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins    /**
12311f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins     * Switch tabs.  Called by the TitleBarSet when sliding the title bar
12321f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins     * results in changing tabs.
1233160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins     * @param index Index of the tab to change to, as defined by
1234160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins     *              mTabControl.getTabIndex(Tab t).
1235160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins     * @return boolean True if we successfully switched to a different tab.  If
1236160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins     *                 the indexth tab is null, or if that tab is the same as
1237160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins     *                 the current one, return false.
12381f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins     */
1239160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins    /* package */ boolean switchToTab(int index) {
124022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        Tab tab = mTabControl.getTab(index);
124122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        Tab currentTab = mTabControl.getCurrentTab();
12421f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins        if (tab == null || tab == currentTab) {
1243160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins            return false;
12441f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins        }
12451f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins        if (currentTab != null) {
12461f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins            // currentTab may be null if it was just removed.  In that case,
12471f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins            // we do not need to remove it
12481f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins            removeTabFromContentView(currentTab);
12491f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins        }
12501f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins        mTabControl.setCurrentTab(tab);
12511f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins        attachTabToContentView(tab);
1252eb6eef4c45df2d65c3e70660493a147a2be405e3Grace Kloba        resetTitleIconAndProgress();
1253eb6eef4c45df2d65c3e70660493a147a2be405e3Grace Kloba        updateLockIconToLatest();
1254160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins        return true;
12551f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins    }
12561f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins
125722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /* package */ Tab openTabToHomePage() {
12580a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins        return openTabAndShow(mSettings.getHomePage(), false, null);
12590a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins    }
12600a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins
12611f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins    /* package */ void closeCurrentWindow() {
126222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        final Tab current = mTabControl.getCurrentTab();
1263160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins        if (mTabControl.getTabCount() == 1) {
1264304442375719effd41dbd53ae62de7a8d0cec7d9Leon Scroggins            // This is the last tab.  Open a new one, with the home
1265304442375719effd41dbd53ae62de7a8d0cec7d9Leon Scroggins            // page and close the current one.
126622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            openTabToHomePage();
1267160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins            closeTab(current);
1268160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins            return;
1269160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins        }
127022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        final Tab parent = current.getParentTab();
12711f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins        int indexToShow = -1;
12721f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins        if (parent != null) {
12731f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins            indexToShow = mTabControl.getTabIndex(parent);
12741f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins        } else {
1275160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins            final int currentIndex = mTabControl.getCurrentIndex();
1276160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins            // Try to move to the tab to the right
1277160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins            indexToShow = currentIndex + 1;
1278160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins            if (indexToShow > mTabControl.getTabCount() - 1) {
1279160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins                // Try to move to the tab to the left
1280160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins                indexToShow = currentIndex - 1;
12811f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins            }
12821f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins        }
1283160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins        if (switchToTab(indexToShow)) {
1284160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins            // Close window
1285160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins            closeTab(current);
1286160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins        }
12871f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins    }
12881f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins
12890a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins    private ActiveTabsPage mActiveTabsPage;
12900a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins
12910a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins    /**
12920a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins     * Remove the active tabs page.
12930a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins     * @param needToAttach If true, the active tabs page did not attach a tab
12940a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins     *                     to the content view, so we need to do that here.
12950a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins     */
12960a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins    /* package */ void removeActiveTabPage(boolean needToAttach) {
12970a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins        mContentView.removeView(mActiveTabsPage);
1298d746a94137a87ffcc1fcefdac9a3764c3bc3f5cdLeon Scroggins        mTitleBar.setVisibility(View.VISIBLE);
12990a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins        mActiveTabsPage = null;
13000a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins        mMenuState = R.id.MAIN_MENU;
13010a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins        if (needToAttach) {
13020a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins            attachTabToContentView(mTabControl.getCurrentTab());
13030a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins        }
13040a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins        getTopWindow().requestFocus();
13050a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins    }
13060a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins
13070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    @Override
13080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public boolean onOptionsItemSelected(MenuItem item) {
13090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (!mCanChord) {
13100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // The user has already fired a shortcut with this hold down of the
13110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // menu key.
13120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return false;
13130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
13141f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins        if (null == getTopWindow()) {
13150d7ae0ed82e21d472cde8cf92b5657d8ee8ca0d8Leon Scroggins            return false;
13160d7ae0ed82e21d472cde8cf92b5657d8ee8ca0d8Leon Scroggins        }
13176ee9c498b8cf648f1507281ed5a1834ba3390907Grace Kloba        if (mMenuIsDown) {
13186ee9c498b8cf648f1507281ed5a1834ba3390907Grace Kloba            // The shortcut action consumes the MENU. Even if it is still down,
13196ee9c498b8cf648f1507281ed5a1834ba3390907Grace Kloba            // it won't trigger the next shortcut action. In the case of the
13206ee9c498b8cf648f1507281ed5a1834ba3390907Grace Kloba            // shortcut action triggering a new activity, like Bookmarks, we
13216ee9c498b8cf648f1507281ed5a1834ba3390907Grace Kloba            // won't get onKeyUp for MENU. So it is important to reset it here.
13226ee9c498b8cf648f1507281ed5a1834ba3390907Grace Kloba            mMenuIsDown = false;
13236ee9c498b8cf648f1507281ed5a1834ba3390907Grace Kloba        }
13240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        switch (item.getItemId()) {
13250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // -- Main menu
1326a81a764063d2f849fba0cbc3039f86e67c2960ddLeon Scroggins            case R.id.new_tab_menu_id:
13270a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins                openTabToHomePage();
1328a81a764063d2f849fba0cbc3039f86e67c2960ddLeon Scroggins                break;
1329a81a764063d2f849fba0cbc3039f86e67c2960ddLeon Scroggins
133064b80f3efd95d7b5192731e995ccde79c4c6c11fLeon Scroggins            case R.id.goto_menu_id:
13318ad299270a97dfa3f9bcb956096bc152498fb727Leon Scroggins                editUrl();
1332b3a5bedeede968b53363a6c517f92bc2484bb42dLeon Scroggins                break;
1333b3a5bedeede968b53363a6c517f92bc2484bb42dLeon Scroggins
1334b3a5bedeede968b53363a6c517f92bc2484bb42dLeon Scroggins            case R.id.bookmarks_menu_id:
1335304442375719effd41dbd53ae62de7a8d0cec7d9Leon Scroggins                bookmarksOrHistoryPicker(false);
13360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
13370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
13380a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins            case R.id.active_tabs_menu_id:
13390a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins                mActiveTabsPage = new ActiveTabsPage(this, mTabControl);
13400a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins                removeTabFromContentView(mTabControl.getCurrentTab());
1341d746a94137a87ffcc1fcefdac9a3764c3bc3f5cdLeon Scroggins                mTitleBar.setVisibility(View.GONE);
134243de61666cfc98a3acc41c7161a1a8b0bdb2b72bLeon Scroggins                hideFakeTitleBar();
13430a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins                mContentView.addView(mActiveTabsPage, COVER_SCREEN_PARAMS);
13440a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins                mActiveTabsPage.requestFocus();
13450a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins                mMenuState = EMPTY_MENU;
13460a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins                break;
13470a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins
13481f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins            case R.id.add_bookmark_menu_id:
13491f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                Intent i = new Intent(BrowserActivity.this,
13501f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                        AddBookmarkPage.class);
13511f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                WebView w = getTopWindow();
13521f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                i.putExtra("url", w.getUrl());
13531f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                i.putExtra("title", w.getTitle());
135483cdb2c40f2dbcbdf522a2af0ec8224c7195c6c1Grace Kloba                i.putExtra("touch_icon_url", w.getTouchIconUrl());
1355dcc2b6f08dd5677bc6ba761a9ba6f1c655113051Ben Murdoch                i.putExtra("thumbnail", createScreenshot(w));
13561f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                startActivity(i);
13570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
13580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
13590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.stop_reload_menu_id:
13600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (mInLoad) {
13610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    stopLoading();
13620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                } else {
13630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    getTopWindow().reload();
13640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
13650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
13660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
13670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.back_menu_id:
13680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                getTopWindow().goBack();
13690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
13700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
13710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.forward_menu_id:
13720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                getTopWindow().goForward();
13730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
13740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
13750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.close_menu_id:
13760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // Close the subwindow if it exists.
13770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (mTabControl.getCurrentSubWindow() != null) {
13780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    dismissSubWindow(mTabControl.getCurrentTab());
13790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    break;
13800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
13811f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                closeCurrentWindow();
13820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
13830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
13840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.homepage_menu_id:
138522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                Tab current = mTabControl.getCurrentTab();
13860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (current != null) {
13870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    dismissSubWindow(current);
138892472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins                    loadUrl(current.getWebView(), mSettings.getHomePage());
13890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
13900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
13910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
13920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.preferences_menu_id:
13930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                Intent intent = new Intent(this,
13940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        BrowserPreferencesPage.class);
1395d530494de9c182af4aff97ddd46343b32594da51Leon Scroggins                intent.putExtra(BrowserPreferencesPage.CURRENT_PAGE,
1396d530494de9c182af4aff97ddd46343b32594da51Leon Scroggins                        getTopWindow().getUrl());
13970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                startActivityForResult(intent, PREFERENCES_PAGE);
13980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
13990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
14000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.find_menu_id:
14010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (null == mFindDialog) {
14020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    mFindDialog = new FindDialog(this);
14030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
1404211ba54a3052f7e68bf8af035ea1ef4e9445130cLeon Scroggins III                // Need to do something special for Tablet
140579e36d97b67bf06b1e0c0edf773882e93a3293e4Leon Scroggins                Tab tab = mTabControl.getCurrentTab();
140679e36d97b67bf06b1e0c0edf773882e93a3293e4Leon Scroggins                if (tab.getSubWebView() == null) {
140779e36d97b67bf06b1e0c0edf773882e93a3293e4Leon Scroggins                    // If the Find is being performed on the main webview,
140879e36d97b67bf06b1e0c0edf773882e93a3293e4Leon Scroggins                    // remove the embedded title bar.
140979e36d97b67bf06b1e0c0edf773882e93a3293e4Leon Scroggins                    WebView mainView = tab.getWebView();
141079e36d97b67bf06b1e0c0edf773882e93a3293e4Leon Scroggins                    if (mainView != null) {
141179e36d97b67bf06b1e0c0edf773882e93a3293e4Leon Scroggins                        mainView.setEmbeddedTitleBar(null);
141279e36d97b67bf06b1e0c0edf773882e93a3293e4Leon Scroggins                    }
141379e36d97b67bf06b1e0c0edf773882e93a3293e4Leon Scroggins                }
141479e36d97b67bf06b1e0c0edf773882e93a3293e4Leon Scroggins                hideFakeTitleBar();
141579e36d97b67bf06b1e0c0edf773882e93a3293e4Leon Scroggins                tab.showFind(mFindDialog);
14160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mMenuState = EMPTY_MENU;
14170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
14180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
14190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.select_text_id:
14200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                getTopWindow().emulateShiftHeld();
14210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
14220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.page_info_menu_id:
14230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                showPageInfo(mTabControl.getCurrentTab(), false);
14240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
14250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
14260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.classic_history_menu_id:
1427304442375719effd41dbd53ae62de7a8d0cec7d9Leon Scroggins                bookmarksOrHistoryPicker(true);
14280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
14290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
143096afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins            case R.id.title_bar_share_page_url:
14310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.share_page_menu_id:
143296afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                Tab currentTab = mTabControl.getCurrentTab();
143396afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                if (null == currentTab) {
143496afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                    mCanChord = false;
143596afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                    return false;
143696afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                }
143796afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                currentTab.populatePickerData();
143896afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                sharePage(this, currentTab.getTitle(),
143996afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                        currentTab.getUrl(), currentTab.getFavicon(),
144096afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                        createScreenshot(currentTab.getWebView()));
14410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
14420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
14430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.dump_nav_menu_id:
14440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                getTopWindow().debugDump();
14450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
14460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
14477a8b88b0e0f20544df5ee34b798398603261b733Andrei Popescu            case R.id.dump_counters_menu_id:
14487a8b88b0e0f20544df5ee34b798398603261b733Andrei Popescu                getTopWindow().dumpV8Counters();
14497a8b88b0e0f20544df5ee34b798398603261b733Andrei Popescu                break;
14507a8b88b0e0f20544df5ee34b798398603261b733Andrei Popescu
14510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.zoom_in_menu_id:
14520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                getTopWindow().zoomIn();
14530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
14540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
14550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.zoom_out_menu_id:
14560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                getTopWindow().zoomOut();
14570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
14580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
14590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.view_downloads_menu_id:
14600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                viewDownloads(null);
14610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
14620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
14630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.window_one_menu_id:
14640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.window_two_menu_id:
14650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.window_three_menu_id:
14660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.window_four_menu_id:
14670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.window_five_menu_id:
14680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.window_six_menu_id:
14690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.window_seven_menu_id:
14700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.window_eight_menu_id:
14710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                {
14720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    int menuid = item.getItemId();
14730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    for (int id = 0; id < WINDOW_SHORTCUT_ID_ARRAY.length; id++) {
14740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        if (WINDOW_SHORTCUT_ID_ARRAY[id] == menuid) {
147522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            Tab desiredTab = mTabControl.getTab(id);
14760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            if (desiredTab != null &&
14770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    desiredTab != mTabControl.getCurrentTab()) {
14781f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                                switchToTab(id);
14790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            }
14800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            break;
14810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }
14820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
14830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
14840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
14850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
14860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            default:
14870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (!super.onOptionsItemSelected(item)) {
14880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    return false;
14890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
14900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // Otherwise fall through.
14910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
14920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mCanChord = false;
14930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return true;
14940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
14950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
1496211ba54a3052f7e68bf8af035ea1ef4e9445130cLeon Scroggins III    /*
1497211ba54a3052f7e68bf8af035ea1ef4e9445130cLeon Scroggins III     * Remove the FindDialog.
1498211ba54a3052f7e68bf8af035ea1ef4e9445130cLeon Scroggins III     */
14990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public void closeFind() {
150079e36d97b67bf06b1e0c0edf773882e93a3293e4Leon Scroggins        Tab currentTab = mTabControl.getCurrentTab();
1501211ba54a3052f7e68bf8af035ea1ef4e9445130cLeon Scroggins III        if (mFindDialog != null) {
150279e36d97b67bf06b1e0c0edf773882e93a3293e4Leon Scroggins            currentTab.closeFind(mFindDialog);
1503211ba54a3052f7e68bf8af035ea1ef4e9445130cLeon Scroggins III            mFindDialog.dismiss();
1504211ba54a3052f7e68bf8af035ea1ef4e9445130cLeon Scroggins III        }
1505d746a94137a87ffcc1fcefdac9a3764c3bc3f5cdLeon Scroggins        if (!mXLargeScreenSize) {
1506d746a94137a87ffcc1fcefdac9a3764c3bc3f5cdLeon Scroggins            // If the Find was being performed in the main WebView, replace the
1507d746a94137a87ffcc1fcefdac9a3764c3bc3f5cdLeon Scroggins            // embedded title bar.
1508d746a94137a87ffcc1fcefdac9a3764c3bc3f5cdLeon Scroggins            if (currentTab.getSubWebView() == null) {
1509d746a94137a87ffcc1fcefdac9a3764c3bc3f5cdLeon Scroggins                WebView mainView = currentTab.getWebView();
1510d746a94137a87ffcc1fcefdac9a3764c3bc3f5cdLeon Scroggins                if (mainView != null) {
1511d746a94137a87ffcc1fcefdac9a3764c3bc3f5cdLeon Scroggins                    mainView.setEmbeddedTitleBar(mTitleBar);
1512d746a94137a87ffcc1fcefdac9a3764c3bc3f5cdLeon Scroggins                }
151379e36d97b67bf06b1e0c0edf773882e93a3293e4Leon Scroggins            }
151479e36d97b67bf06b1e0c0edf773882e93a3293e4Leon Scroggins        }
15150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mMenuState = R.id.MAIN_MENU;
151679e36d97b67bf06b1e0c0edf773882e93a3293e4Leon Scroggins        if (mInLoad) {
151779e36d97b67bf06b1e0c0edf773882e93a3293e4Leon Scroggins            // The title bar was hidden, because otherwise it would cover up the
151879e36d97b67bf06b1e0c0edf773882e93a3293e4Leon Scroggins            // find dialog.  Now that the dialog has been removed, show the fake
151979e36d97b67bf06b1e0c0edf773882e93a3293e4Leon Scroggins            // title bar once again.
152079e36d97b67bf06b1e0c0edf773882e93a3293e4Leon Scroggins            showFakeTitleBar();
152179e36d97b67bf06b1e0c0edf773882e93a3293e4Leon Scroggins        }
15220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
15230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
152422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    @Override
152522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    public boolean onPrepareOptionsMenu(Menu menu) {
15260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // This happens when the user begins to hold down the menu key, so
15270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // allow them to chord to get a shortcut.
15280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mCanChord = true;
15290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Note: setVisible will decide whether an item is visible; while
15300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // setEnabled() will decide whether an item is enabled, which also means
15310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // whether the matching shortcut key will function.
15320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        super.onPrepareOptionsMenu(menu);
15330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        switch (mMenuState) {
15340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case EMPTY_MENU:
15350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (mCurrentMenuState != mMenuState) {
15360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    menu.setGroupVisible(R.id.MAIN_MENU, false);
15370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    menu.setGroupEnabled(R.id.MAIN_MENU, false);
15380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    menu.setGroupEnabled(R.id.MAIN_SHORTCUT_MENU, false);
15390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
15400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
15410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            default:
15420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (mCurrentMenuState != mMenuState) {
15430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    menu.setGroupVisible(R.id.MAIN_MENU, true);
15440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    menu.setGroupEnabled(R.id.MAIN_MENU, true);
15450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    menu.setGroupEnabled(R.id.MAIN_SHORTCUT_MENU, true);
15460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
15470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                final WebView w = getTopWindow();
15480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                boolean canGoBack = false;
15490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                boolean canGoForward = false;
15500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                boolean isHome = false;
15510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (w != null) {
15520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    canGoBack = w.canGoBack();
15530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    canGoForward = w.canGoForward();
15540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    isHome = mSettings.getHomePage().equals(w.getUrl());
15550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
15560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                final MenuItem back = menu.findItem(R.id.back_menu_id);
15570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                back.setEnabled(canGoBack);
15580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
15590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                final MenuItem home = menu.findItem(R.id.homepage_menu_id);
15600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                home.setEnabled(!isHome);
15610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
15620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.forward_menu_id)
15630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        .setEnabled(canGoForward);
15640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
1565a81a764063d2f849fba0cbc3039f86e67c2960ddLeon Scroggins                menu.findItem(R.id.new_tab_menu_id).setEnabled(
156622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        mTabControl.canCreateNewTab());
1567a81a764063d2f849fba0cbc3039f86e67c2960ddLeon Scroggins
15680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // decide whether to show the share link option
15690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                PackageManager pm = getPackageManager();
15700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                Intent send = new Intent(Intent.ACTION_SEND);
15710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                send.setType("text/plain");
15720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                ResolveInfo ri = pm.resolveActivity(send, PackageManager.MATCH_DEFAULT_ONLY);
15730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.share_page_menu_id).setVisible(ri != null);
15740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
15750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                boolean isNavDump = mSettings.isNavDump();
15760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                final MenuItem nav = menu.findItem(R.id.dump_nav_menu_id);
15770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                nav.setVisible(isNavDump);
15780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                nav.setEnabled(isNavDump);
15797a8b88b0e0f20544df5ee34b798398603261b733Andrei Popescu
15807a8b88b0e0f20544df5ee34b798398603261b733Andrei Popescu                boolean showDebugSettings = mSettings.showDebugSettings();
15817a8b88b0e0f20544df5ee34b798398603261b733Andrei Popescu                final MenuItem counter = menu.findItem(R.id.dump_counters_menu_id);
15827a8b88b0e0f20544df5ee34b798398603261b733Andrei Popescu                counter.setVisible(showDebugSettings);
15837a8b88b0e0f20544df5ee34b798398603261b733Andrei Popescu                counter.setEnabled(showDebugSettings);
15847a8b88b0e0f20544df5ee34b798398603261b733Andrei Popescu
15850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
15860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
15870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mCurrentMenuState = mMenuState;
15880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return true;
15890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
15900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
15910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    @Override
15920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public void onCreateContextMenu(ContextMenu menu, View v,
15930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ContextMenuInfo menuInfo) {
15944e9f89b0a64395133b9160dcb4533d2dc62a424fLeon Scroggins        if (v instanceof TitleBar) {
15954e9f89b0a64395133b9160dcb4533d2dc62a424fLeon Scroggins            return;
15964e9f89b0a64395133b9160dcb4533d2dc62a424fLeon Scroggins        }
15970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebView webview = (WebView) v;
15980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebView.HitTestResult result = webview.getHitTestResult();
15990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (result == null) {
16000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
16010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
16020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
16030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        int type = result.getType();
16040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (type == WebView.HitTestResult.UNKNOWN_TYPE) {
16050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Log.w(LOGTAG,
16060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    "We should not show context menu when nothing is touched");
16070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
16080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
16090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (type == WebView.HitTestResult.EDIT_TEXT_TYPE) {
16100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // let TextView handles context menu
16110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
16120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
16130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
16140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Note, http://b/issue?id=1106666 is requesting that
16150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // an inflated menu can be used again. This is not available
16160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // yet, so inflate each time (yuk!)
16170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        MenuInflater inflater = getMenuInflater();
16180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        inflater.inflate(R.menu.browsercontext, menu);
16190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
16200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Show the correct menu group
16210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String extra = result.getExtra();
16220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        menu.setGroupVisible(R.id.PHONE_MENU,
16230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                type == WebView.HitTestResult.PHONE_TYPE);
16240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        menu.setGroupVisible(R.id.EMAIL_MENU,
16250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                type == WebView.HitTestResult.EMAIL_TYPE);
16260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        menu.setGroupVisible(R.id.GEO_MENU,
16270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                type == WebView.HitTestResult.GEO_TYPE);
16280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        menu.setGroupVisible(R.id.IMAGE_MENU,
16290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                type == WebView.HitTestResult.IMAGE_TYPE
16300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                || type == WebView.HitTestResult.SRC_IMAGE_ANCHOR_TYPE);
16310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        menu.setGroupVisible(R.id.ANCHOR_MENU,
16320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                type == WebView.HitTestResult.SRC_ANCHOR_TYPE
16330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                || type == WebView.HitTestResult.SRC_IMAGE_ANCHOR_TYPE);
16340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
16350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Setup custom handling depending on the type
16360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        switch (type) {
16370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case WebView.HitTestResult.PHONE_TYPE:
16380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.setHeaderTitle(Uri.decode(extra));
16390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.dial_context_menu_id).setIntent(
16400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new Intent(Intent.ACTION_VIEW, Uri
16410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                .parse(WebView.SCHEME_TEL + extra)));
16420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                Intent addIntent = new Intent(Intent.ACTION_INSERT_OR_EDIT);
16430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                addIntent.putExtra(Insert.PHONE, Uri.decode(extra));
16445e335a381a0cd66e94117b202c1f34f5cb29c9b8Cary Clark                addIntent.setType(ContactsContract.Contacts.CONTENT_ITEM_TYPE);
16450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.add_contact_context_menu_id).setIntent(
16460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        addIntent);
16470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.copy_phone_context_menu_id).setOnMenuItemClickListener(
16480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new Copy(extra));
16490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
16500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
16510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case WebView.HitTestResult.EMAIL_TYPE:
16520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.setHeaderTitle(extra);
16530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.email_context_menu_id).setIntent(
16540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new Intent(Intent.ACTION_VIEW, Uri
16550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                .parse(WebView.SCHEME_MAILTO + extra)));
16560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.copy_mail_context_menu_id).setOnMenuItemClickListener(
16570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new Copy(extra));
16580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
16590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
16600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case WebView.HitTestResult.GEO_TYPE:
16610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.setHeaderTitle(extra);
16620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.map_context_menu_id).setIntent(
16630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new Intent(Intent.ACTION_VIEW, Uri
16640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                .parse(WebView.SCHEME_GEO
16650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        + URLEncoder.encode(extra))));
16660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.copy_geo_context_menu_id).setOnMenuItemClickListener(
16670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new Copy(extra));
16680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
16690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
16700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case WebView.HitTestResult.SRC_ANCHOR_TYPE:
16710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case WebView.HitTestResult.SRC_IMAGE_ANCHOR_TYPE:
16720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                TextView titleView = (TextView) LayoutInflater.from(this)
16730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        .inflate(android.R.layout.browser_link_context_header,
16740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        null);
16750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                titleView.setText(extra);
16760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.setHeaderView(titleView);
16770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // decide whether to show the open link in new tab option
16780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.open_newtab_context_menu_id).setVisible(
167922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        mTabControl.canCreateNewTab());
1680de353621650d17a412b6ffe2cbf0366db5f11c40Ben Murdoch                menu.findItem(R.id.bookmark_context_menu_id).setVisible(
1681de353621650d17a412b6ffe2cbf0366db5f11c40Ben Murdoch                        Bookmarks.urlHasAcceptableScheme(extra));
16820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                PackageManager pm = getPackageManager();
16830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                Intent send = new Intent(Intent.ACTION_SEND);
16840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                send.setType("text/plain");
16850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                ResolveInfo ri = pm.resolveActivity(send, PackageManager.MATCH_DEFAULT_ONLY);
16860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.share_link_context_menu_id).setVisible(ri != null);
16870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (type == WebView.HitTestResult.SRC_ANCHOR_TYPE) {
16880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    break;
16890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
16900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // otherwise fall through to handle image part
16910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case WebView.HitTestResult.IMAGE_TYPE:
16920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (type == WebView.HitTestResult.IMAGE_TYPE) {
16930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    menu.setHeaderTitle(extra);
16940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
16950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.view_image_context_menu_id).setIntent(
16960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new Intent(Intent.ACTION_VIEW, Uri.parse(extra)));
16970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.download_context_menu_id).
16980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        setOnMenuItemClickListener(new Download(extra));
16994f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                menu.findItem(R.id.set_wallpaper_context_menu_id).
17004f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                        setOnMenuItemClickListener(new SetAsWallpaper(extra));
17010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
17020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
17030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            default:
17040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                Log.w(LOGTAG, "We should not get here.");
17050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
17060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
1707b2b19f501ee05448ca81bddaaca70e9b2f51cb54Leon Scroggins        hideFakeTitleBar();
17080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
17090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
17100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Attach the given tab to the content view.
1711c928c30a51eee84b40cb7045842c288c1cfafff0Grace Kloba    // this should only be called for the current tab.
171222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private void attachTabToContentView(Tab t) {
17132bc69918d97a767a02132090e58718077381ba1aSteve Block        // Attach the container that contains the main WebView and any other UI
17142bc69918d97a767a02132090e58718077381ba1aSteve Block        // associated with the tab.
1715d0119535d0c490e087be114ae8fd1639bb1945dcPatrick Scott        t.attachTabToContentView(mContentView);
1716bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch
1717bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch        if (mShouldShowErrorConsole) {
171822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            ErrorConsoleView errorConsole = t.getErrorConsole(true);
1719bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch            if (errorConsole.numberOfErrors() == 0) {
1720bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch                errorConsole.showConsole(ErrorConsoleView.SHOW_NONE);
1721bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch            } else {
1722bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch                errorConsole.showConsole(ErrorConsoleView.SHOW_MINIMIZED);
1723bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch            }
1724bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch
1725bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch            mErrorConsoleContainer.addView(errorConsole,
172615b8ec6b226f4d57307716e1f495e10a91f8cbf4Romain Guy                    new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
1727bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch                                                  ViewGroup.LayoutParams.WRAP_CONTENT));
1728bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch        }
1729bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch
1730d746a94137a87ffcc1fcefdac9a3764c3bc3f5cdLeon Scroggins        if (!mXLargeScreenSize){
1731d746a94137a87ffcc1fcefdac9a3764c3bc3f5cdLeon Scroggins            WebView view = t.getWebView();
1732d746a94137a87ffcc1fcefdac9a3764c3bc3f5cdLeon Scroggins            view.setEmbeddedTitleBar(mTitleBar);
1733d746a94137a87ffcc1fcefdac9a3764c3bc3f5cdLeon Scroggins        }
173458d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        if (t.isInVoiceSearchMode()) {
173558d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins            showVoiceTitleBar(t.getVoiceDisplayTitle());
173658d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        } else {
173758d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins            revertVoiceTitleBar();
173858d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        }
17390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Request focus on the top window.
17400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        t.getTopWindow().requestFocus();
17410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
17420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
17430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Attach a sub window to the main WebView of the given tab.
174422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void attachSubWindow(Tab t) {
1745d0119535d0c490e087be114ae8fd1639bb1945dcPatrick Scott        t.attachSubWindow(mContentView);
1746d0119535d0c490e087be114ae8fd1639bb1945dcPatrick Scott        getTopWindow().requestFocus();
17470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
17480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
17490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Remove the given tab from the content view.
175022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private void removeTabFromContentView(Tab t) {
17512bc69918d97a767a02132090e58718077381ba1aSteve Block        // Remove the container that contains the main WebView.
1752d0119535d0c490e087be114ae8fd1639bb1945dcPatrick Scott        t.removeTabFromContentView(mContentView);
1753bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch
175422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        ErrorConsoleView errorConsole = t.getErrorConsole(false);
175522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (errorConsole != null) {
175622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mErrorConsoleContainer.removeView(errorConsole);
1757bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch        }
1758bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch
1759d746a94137a87ffcc1fcefdac9a3764c3bc3f5cdLeon Scroggins        if (!mXLargeScreenSize) {
1760d746a94137a87ffcc1fcefdac9a3764c3bc3f5cdLeon Scroggins            WebView view = t.getWebView();
1761d746a94137a87ffcc1fcefdac9a3764c3bc3f5cdLeon Scroggins            if (view != null) {
1762d746a94137a87ffcc1fcefdac9a3764c3bc3f5cdLeon Scroggins                view.setEmbeddedTitleBar(null);
1763d746a94137a87ffcc1fcefdac9a3764c3bc3f5cdLeon Scroggins            }
1764bb85b9016201d45ea939d7cb7edd0ba6616a111cLeon Scroggins        }
17650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
17660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
17670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Remove the sub window if it exists. Also called by TabControl when the
17680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // user clicks the 'X' to dismiss a sub window.
176922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /* package */ void dismissSubWindow(Tab t) {
1770d0119535d0c490e087be114ae8fd1639bb1945dcPatrick Scott        t.removeSubWindow(mContentView);
177122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // dismiss the subwindow. This will destroy the WebView.
177222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        t.dismissSubWindow();
1773d0119535d0c490e087be114ae8fd1639bb1945dcPatrick Scott        getTopWindow().requestFocus();
17740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
17750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
17761f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins    // A wrapper function of {@link #openTabAndShow(UrlData, boolean, String)}
177725ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima    // that accepts url as string.
177822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private Tab openTabAndShow(String url, boolean closeOnExit, String appId) {
17791f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins        return openTabAndShow(new UrlData(url), closeOnExit, appId);
17800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
17810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
17820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // This method does a ton of stuff. It will attempt to create a new tab
17830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // if we haven't reached MAX_TABS. Otherwise it uses the current tab. If
17841f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins    // url isn't null, it will load the given url.
178522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /* package */Tab openTabAndShow(UrlData urlData, boolean closeOnExit,
178622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            String appId) {
178722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        final Tab currentTab = mTabControl.getCurrentTab();
178822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mTabControl.canCreateNewTab()) {
178922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            final Tab tab = mTabControl.createNewTab(closeOnExit, appId,
179022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    urlData.mUrl);
17911f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins            WebView webview = tab.getWebView();
17920a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins            // If the last tab was removed from the active tabs page, currentTab
17930a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins            // will be null.
17940a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins            if (currentTab != null) {
17950a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins                removeTabFromContentView(currentTab);
17960a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins            }
17978bbd69f50abd537bfe7eb314b3a3e20241ac22bdPatrick Scott            // We must set the new tab as the current tab to reflect the old
17988bbd69f50abd537bfe7eb314b3a3e20241ac22bdPatrick Scott            // animation behavior.
17998bbd69f50abd537bfe7eb314b3a3e20241ac22bdPatrick Scott            mTabControl.setCurrentTab(tab);
1800eb6eef4c45df2d65c3e70660493a147a2be405e3Grace Kloba            attachTabToContentView(tab);
1801160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins            if (!urlData.isEmpty()) {
18029d53da05812f959745810a33bb4e06b273393c42Patrick Scott                loadUrlDataIn(tab, urlData);
18030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
18041f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins            return tab;
180564b80f3efd95d7b5192731e995ccde79c4c6c11fLeon Scroggins        } else {
18061f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins            // Get rid of the subwindow if it exists
18071f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins            dismissSubWindow(currentTab);
18081f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins            if (!urlData.isEmpty()) {
18091f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                // Load the given url.
18109d53da05812f959745810a33bb4e06b273393c42Patrick Scott                loadUrlDataIn(currentTab, urlData);
18110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
181258d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins            return currentTab;
18130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
18140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
18150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
181622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private Tab openTab(String url) {
18170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mSettings.openInBackground()) {
181822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            Tab t = mTabControl.createNewTab();
18190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (t != null) {
18201f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                WebView view = t.getWebView();
182192472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins                loadUrl(view, url);
18220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
1823c9181841c7ed6b9f7dfc953eab8dc7ba1047022cGrace Kloba            return t;
18240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
18251f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins            return openTabAndShow(url, false, null);
18260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
18270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
18280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
18290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private class Copy implements OnMenuItemClickListener {
18300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        private CharSequence mText;
18310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
18320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public boolean onMenuItemClick(MenuItem item) {
18330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            copy(mText);
18340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return true;
18350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
18360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
18370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public Copy(CharSequence toCopy) {
18380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mText = toCopy;
18390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
18400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
18410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
18420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private class Download implements OnMenuItemClickListener {
18430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        private String mText;
18440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
18450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public boolean onMenuItemClick(MenuItem item) {
18460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            onDownloadStartNoStream(mText, null, null, null, -1);
18470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return true;
18480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
18490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
18500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public Download(String toDownload) {
18510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mText = toDownload;
18520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
18530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
18540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
18554f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch    private class SetAsWallpaper extends Thread implements
18564f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch            OnMenuItemClickListener, DialogInterface.OnCancelListener {
18574f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch        private URL mUrl;
18584f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch        private ProgressDialog mWallpaperProgress;
18594f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch        private boolean mCanceled = false;
18604f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch
18614f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch        public SetAsWallpaper(String url) {
18624f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch            try {
18634f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                mUrl = new URL(url);
18644f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch            } catch (MalformedURLException e) {
18654f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                mUrl = null;
18664f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch            }
18674f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch        }
18684f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch
18694f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch        public void onCancel(DialogInterface dialog) {
18704f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch            mCanceled = true;
18714f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch        }
18724f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch
18734f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch        public boolean onMenuItemClick(MenuItem item) {
18744f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch            if (mUrl != null) {
18754f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                // The user may have tried to set a image with a large file size as their
18764f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                // background so it may take a few moments to perform the operation. Display
18774f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                // a progress spinner while it is working.
18784f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                mWallpaperProgress = new ProgressDialog(BrowserActivity.this);
18794f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                mWallpaperProgress.setIndeterminate(true);
18804f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                mWallpaperProgress.setMessage(getText(R.string.progress_dialog_setting_wallpaper));
18814f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                mWallpaperProgress.setCancelable(true);
18824f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                mWallpaperProgress.setOnCancelListener(this);
18834f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                mWallpaperProgress.show();
18844f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                start();
18854f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch            }
18864f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch            return true;
18874f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch        }
18884f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch
18894f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch        public void run() {
18904f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch            Drawable oldWallpaper = BrowserActivity.this.getWallpaper();
18914f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch            try {
18924f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                // TODO: This will cause the resource to be downloaded again, when we
18934f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                // should in most cases be able to grab it from the cache. To fix this
18944f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                // we should query WebCore to see if we can access a cached version and
18954f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                // instead open an input stream on that. This pattern could also be used
18964f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                // in the download manager where the same problem exists.
18974f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                InputStream inputstream = mUrl.openStream();
18984f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                if (inputstream != null) {
18994f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                    setWallpaper(inputstream);
19004f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                }
19014f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch            } catch (IOException e) {
19024f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                Log.e(LOGTAG, "Unable to set new wallpaper");
19034f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                // Act as though the user canceled the operation so we try to
19044f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                // restore the old wallpaper.
19054f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                mCanceled = true;
19064f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch            }
19074f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch
19084f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch            if (mCanceled) {
19094f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                // Restore the old wallpaper if the user cancelled whilst we were setting
19104f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                // the new wallpaper.
19114f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                int width = oldWallpaper.getIntrinsicWidth();
19124f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                int height = oldWallpaper.getIntrinsicHeight();
19134f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                Bitmap bm = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);
19144f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                Canvas canvas = new Canvas(bm);
19154f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                oldWallpaper.setBounds(0, 0, width, height);
19164f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                oldWallpaper.draw(canvas);
19174f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                try {
19184f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                    setWallpaper(bm);
19194f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                } catch (IOException e) {
19204f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                    Log.e(LOGTAG, "Unable to restore old wallpaper.");
19214f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                }
19224f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                mCanceled = false;
19234f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch            }
19244f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch
19254f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch            if (mWallpaperProgress.isShowing()) {
19264f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                mWallpaperProgress.dismiss();
19274f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch            }
19284f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch        }
19294f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch    }
19304f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch
19310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void copy(CharSequence text) {
19320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        try {
19330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            IClipboard clip = IClipboard.Stub.asInterface(ServiceManager.getService("clipboard"));
19340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (clip != null) {
19350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                clip.setClipboardText(text);
19360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
19370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } catch (android.os.RemoteException e) {
19380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Log.e(LOGTAG, "Copy failed", e);
19390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
19400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
19410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
19420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
19430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Resets the browser title-view to whatever it must be
19440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * (for example, if we had a loading error)
19450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * When we have a new page, we call resetTitle, when we
19460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * have to reset the titlebar to whatever it used to be
19470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * (for example, if the user chose to stop loading), we
19480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * call resetTitleAndRevertLockIcon.
19490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
19500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /* package */ void resetTitleAndRevertLockIcon() {
195122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mTabControl.getCurrentTab().revertLockIcon();
195222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        updateLockIconToLatest();
19530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        resetTitleIconAndProgress();
19540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
19550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
19560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
19570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Reset the title, favicon, and progress.
19580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
19590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void resetTitleIconAndProgress() {
19600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebView current = mTabControl.getCurrentWebView();
19610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (current == null) {
19620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
19630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
19640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        resetTitleAndIcon(current);
19650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        int progress = current.getProgress();
196622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        current.getWebChromeClient().onProgressChanged(current, progress);
19670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
19680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
19690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Reset the title and the icon based on the given item.
19700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void resetTitleAndIcon(WebView view) {
19710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebHistoryItem item = view.copyBackForwardList().getCurrentItem();
19720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (item != null) {
197368579393973f745fc65a2781061af9bb8f2d7020Leon Scroggins            setUrlTitle(item.getUrl(), item.getTitle());
19740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            setFavicon(item.getFavicon());
19750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
197668579393973f745fc65a2781061af9bb8f2d7020Leon Scroggins            setUrlTitle(null, null);
19770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            setFavicon(null);
19780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
19790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
19800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
19810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
19820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Sets a title composed of the URL and the title string.
19830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param url The URL of the site being loaded.
19840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param title The title of the site being loaded.
19850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
198622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void setUrlTitle(String url, String title) {
19870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mUrl = url;
19880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mTitle = title;
19890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
199058d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        // If we are in voice search mode, the title has already been set.
199158d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        if (mTabControl.getCurrentTab().isInVoiceSearchMode()) return;
199258d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        mTitleBar.setDisplayTitle(url);
1993d746a94137a87ffcc1fcefdac9a3764c3bc3f5cdLeon Scroggins        if (!mXLargeScreenSize) {
1994d746a94137a87ffcc1fcefdac9a3764c3bc3f5cdLeon Scroggins            mFakeTitleBar.setDisplayTitle(url);
1995d746a94137a87ffcc1fcefdac9a3764c3bc3f5cdLeon Scroggins        }
19960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
19970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
19980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
19990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param url The URL to build a title version of the URL from.
20000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @return The title version of the URL or null if fails.
20010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * The title version of the URL can be either the URL hostname,
20020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * or the hostname with an "https://" prefix (for secure URLs),
20030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * or an empty string if, for example, the URL in question is a
20040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * file:// URL with no hostname.
20050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
200632e14a6deccfa75490b3032bb4ddd5ae90f89de8Leon Scroggins    /* package */ static String buildTitleUrl(String url) {
20070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String titleUrl = null;
20080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
20090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (url != null) {
20100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            try {
20110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // parse the url string
20120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                URL urlObj = new URL(url);
20130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (urlObj != null) {
20140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    titleUrl = "";
20150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
20160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    String protocol = urlObj.getProtocol();
20170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    String host = urlObj.getHost();
20180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
20190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    if (host != null && 0 < host.length()) {
20200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        titleUrl = host;
20210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        if (protocol != null) {
20220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            // if a secure site, add an "https://" prefix!
20230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            if (protocol.equalsIgnoreCase("https")) {
20240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                titleUrl = protocol + "://" + host;
20250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            }
20260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }
20270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
20280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
20290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } catch (MalformedURLException e) {}
20300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
20310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
20320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return titleUrl;
20330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
20340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
20350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Set the favicon in the title bar.
203622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void setFavicon(Bitmap icon) {
203768579393973f745fc65a2781061af9bb8f2d7020Leon Scroggins        mTitleBar.setFavicon(icon);
2038d746a94137a87ffcc1fcefdac9a3764c3bc3f5cdLeon Scroggins        if (!mXLargeScreenSize) {
2039d746a94137a87ffcc1fcefdac9a3764c3bc3f5cdLeon Scroggins            mFakeTitleBar.setFavicon(icon);
2040d746a94137a87ffcc1fcefdac9a3764c3bc3f5cdLeon Scroggins        }
20410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
20420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
20430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
20440a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins     * Close the tab, remove its associated title bar, and adjust mTabControl's
20450a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins     * current tab to a valid value.
20461f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins     */
204722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /* package */ void closeTab(Tab t) {
20480a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins        int currentIndex = mTabControl.getCurrentIndex();
20490a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins        int removeIndex = mTabControl.getTabIndex(t);
20501f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins        mTabControl.removeTab(t);
20510a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins        if (currentIndex >= removeIndex && currentIndex != 0) {
20520a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins            currentIndex--;
20530a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins        }
20540a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins        mTabControl.setCurrentTab(mTabControl.getTab(currentIndex));
2055a5bf1deca120315a2643ea5b010f94d853461b15Andrei Popescu        resetTitleIconAndProgress();
20560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
20570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
2058dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins    /* package */ void goBackOnePageOrQuit() {
205922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        Tab current = mTabControl.getCurrentTab();
20600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (current == null) {
20610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            /*
20620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project             * Instead of finishing the activity, simply push this to the back
20630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project             * of the stack and let ActivityManager to choose the foreground
20640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project             * activity. As BrowserActivity is singleTask, it will be always the
20650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project             * root of the task. So we can use either true or false for
20660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project             * moveTaskToBack().
20670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project             */
20680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            moveTaskToBack(true);
206900d85e74921459b34e70eb93368245b4c0a9bf5fGrace Kloba            return;
20700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
20710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebView w = current.getWebView();
20720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (w.canGoBack()) {
20730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            w.goBack();
20740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
20750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Check to see if we are closing a window that was created by
20760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // another window. If so, we switch back to that window.
207722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            Tab parent = current.getParentTab();
20780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (parent != null) {
20791f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                switchToTab(mTabControl.getTabIndex(parent));
20801f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                // Now we close the other tab
20811f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                closeTab(current);
20820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } else {
20830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (current.closeOnExit()) {
208422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    // force the tab's inLoad() to be false as we are going to
208522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    // either finish the activity or remove the tab. This will
208622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    // ensure pauseWebViewTimers() taking action.
208722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    mTabControl.getCurrentTab().clearInLoad();
20880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    if (mTabControl.getTabCount() == 1) {
20890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        finish();
20900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        return;
20910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
20927bfa63b55644fbf2da1fe6a24b3be0267529202cMike Reed                    // call pauseWebViewTimers() now, we won't be able to call
20937bfa63b55644fbf2da1fe6a24b3be0267529202cMike Reed                    // it in onPause() as the WebView won't be valid.
2094ec1b5ad8d8283b1fbbc5d7fa1cd50ef95b9e594dGrace Kloba                    // Temporarily change mActivityInPause to be true as
2095ec1b5ad8d8283b1fbbc5d7fa1cd50ef95b9e594dGrace Kloba                    // pauseWebViewTimers() will do nothing if mActivityInPause
2096ec1b5ad8d8283b1fbbc5d7fa1cd50ef95b9e594dGrace Kloba                    // is false.
2097918e1d78b2db6ef21c71a07868572d9cda498476Grace Kloba                    boolean savedState = mActivityInPause;
2098918e1d78b2db6ef21c71a07868572d9cda498476Grace Kloba                    if (savedState) {
2099ec1b5ad8d8283b1fbbc5d7fa1cd50ef95b9e594dGrace Kloba                        Log.e(LOGTAG, "BrowserActivity is already paused "
2100ec1b5ad8d8283b1fbbc5d7fa1cd50ef95b9e594dGrace Kloba                                + "while handing goBackOnePageOrQuit.");
2101918e1d78b2db6ef21c71a07868572d9cda498476Grace Kloba                    }
2102918e1d78b2db6ef21c71a07868572d9cda498476Grace Kloba                    mActivityInPause = true;
21037bfa63b55644fbf2da1fe6a24b3be0267529202cMike Reed                    pauseWebViewTimers();
2104918e1d78b2db6ef21c71a07868572d9cda498476Grace Kloba                    mActivityInPause = savedState;
21050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    removeTabFromContentView(current);
21060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    mTabControl.removeTab(current);
21070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
21080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                /*
21090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                 * Instead of finishing the activity, simply push this to the back
21100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                 * of the stack and let ActivityManager to choose the foreground
21110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                 * activity. As BrowserActivity is singleTask, it will be always the
21120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                 * root of the task. So we can use either true or false for
21130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                 * moveTaskToBack().
21140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                 */
21150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                moveTaskToBack(true);
21160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
21170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
21180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
21190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
212022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    boolean isMenuDown() {
212122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return mMenuIsDown;
212222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
212322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
21245942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba    @Override
21255942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba    public boolean onKeyDown(int keyCode, KeyEvent event) {
2126f65b50ddd2f7ed1205002d74082fff1ac2336d5cLeon Scroggins        // Even if MENU is already held down, we need to call to super to open
2127f65b50ddd2f7ed1205002d74082fff1ac2336d5cLeon Scroggins        // the IME on long press.
2128f65b50ddd2f7ed1205002d74082fff1ac2336d5cLeon Scroggins        if (KeyEvent.KEYCODE_MENU == keyCode) {
2129f65b50ddd2f7ed1205002d74082fff1ac2336d5cLeon Scroggins            mMenuIsDown = true;
2130f65b50ddd2f7ed1205002d74082fff1ac2336d5cLeon Scroggins            return super.onKeyDown(keyCode, event);
2131f65b50ddd2f7ed1205002d74082fff1ac2336d5cLeon Scroggins        }
21325942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba        // The default key mode is DEFAULT_KEYS_SEARCH_LOCAL. As the MENU is
21335942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba        // still down, we don't want to trigger the search. Pretend to consume
21345942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba        // the key and do nothing.
21355942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba        if (mMenuIsDown) return true;
21365942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba
21375942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba        switch(keyCode) {
21385942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba            case KeyEvent.KEYCODE_SPACE:
2139da0fe556a00773ce2af25eb6dcc5442bd08c7addGrace Kloba                // WebView/WebTextView handle the keys in the KeyDown. As
2140da0fe556a00773ce2af25eb6dcc5442bd08c7addGrace Kloba                // the Activity's shortcut keys are only handled when WebView
2141da0fe556a00773ce2af25eb6dcc5442bd08c7addGrace Kloba                // doesn't, have to do it in onKeyDown instead of onKeyUp.
2142da0fe556a00773ce2af25eb6dcc5442bd08c7addGrace Kloba                if (event.isShiftPressed()) {
2143da0fe556a00773ce2af25eb6dcc5442bd08c7addGrace Kloba                    getTopWindow().pageUp(false);
2144da0fe556a00773ce2af25eb6dcc5442bd08c7addGrace Kloba                } else {
2145da0fe556a00773ce2af25eb6dcc5442bd08c7addGrace Kloba                    getTopWindow().pageDown(false);
2146da0fe556a00773ce2af25eb6dcc5442bd08c7addGrace Kloba                }
21475942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                return true;
21485942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba            case KeyEvent.KEYCODE_BACK:
21495942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                if (event.getRepeatCount() == 0) {
21505942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                    event.startTracking();
21515942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                    return true;
21525942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                } else if (mCustomView == null && mActiveTabsPage == null
21535942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                        && event.isLongPress()) {
21545942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                    bookmarksOrHistoryPicker(true);
21555942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                    return true;
21560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
21575942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                break;
21580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
21595942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba        return super.onKeyDown(keyCode, event);
21600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
21610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
21625942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba    @Override
21635942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba    public boolean onKeyUp(int keyCode, KeyEvent event) {
21645942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba        switch(keyCode) {
21655942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba            case KeyEvent.KEYCODE_MENU:
21665942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                mMenuIsDown = false;
21675942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                break;
21685942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba            case KeyEvent.KEYCODE_BACK:
21695942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                if (event.isTracking() && !event.isCanceled()) {
21705942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                    if (mCustomView != null) {
21715942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                        // if a custom view is showing, hide it
217222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        mTabControl.getCurrentWebView().getWebChromeClient()
217322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                .onHideCustomView();
21745942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                    } else if (mActiveTabsPage != null) {
21755942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                        // if tab page is showing, hide it
21765942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                        removeActiveTabPage(true);
21770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    } else {
21785942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                        WebView subwindow = mTabControl.getCurrentSubWindow();
21795942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                        if (subwindow != null) {
21805942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                            if (subwindow.canGoBack()) {
21815942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                                subwindow.goBack();
21825942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                            } else {
21835942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                                dismissSubWindow(mTabControl.getCurrentTab());
21845942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                            }
21855942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                        } else {
21865942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                            goBackOnePageOrQuit();
21875942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                        }
21880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
21895942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                    return true;
21905942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                }
21915942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                break;
21920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
21935942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba        return super.onKeyUp(keyCode, event);
21940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
21950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
219668579393973f745fc65a2781061af9bb8f2d7020Leon Scroggins    /* package */ void stopLoading() {
2197b7cc8b439dc595dc48e1c2183b35d23ad72dfbe5Ben Murdoch        mDidStopLoad = true;
21980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        resetTitleAndRevertLockIcon();
21990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebView w = getTopWindow();
22000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        w.stopLoading();
220122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // FIXME: before refactor, it is using mWebViewClient. So I keep the
220222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // same logic here. But for subwindow case, should we call into the main
220322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // WebView's onPageFinished as we never call its onPageStarted and if
220422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // the page finishes itself, we don't call onPageFinished.
220522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mTabControl.getCurrentWebView().getWebViewClient().onPageFinished(w,
220622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                w.getUrl());
22070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
22080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        cancelStopToast();
22090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mStopToast = Toast
22100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .makeText(this, R.string.stopping, Toast.LENGTH_SHORT);
22110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mStopToast.show();
22120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
22130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
221422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    boolean didUserStopLoading() {
221522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return mDidStopLoad;
221622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
221722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
22180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void cancelStopToast() {
22190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mStopToast != null) {
22200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mStopToast.cancel();
22210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mStopToast = null;
22220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
22230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
22240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
222522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // called by a UI or non-UI thread to post the message
222622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    public void postMessage(int what, int arg1, int arg2, Object obj,
222722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            long delayMillis) {
222822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mHandler.sendMessageDelayed(mHandler.obtainMessage(what, arg1, arg2,
222922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                obj), delayMillis);
223022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
223122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
223222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // called by a UI or non-UI thread to remove the message
223322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void removeMessages(int what, Object object) {
223422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mHandler.removeMessages(what, object);
22350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
22360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
22370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // public message ids
22380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public final static int LOAD_URL                = 1001;
22390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public final static int STOP_LOAD               = 1002;
22400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
22410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Message Ids
22420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private static final int FOCUS_NODE_HREF         = 102;
224392c18a52ca7a79c114028b5ba22c3dfe443bd1a4Grace Kloba    private static final int RELEASE_WAKELOCK        = 107;
22440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
224522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    static final int UPDATE_BOOKMARK_THUMBNAIL       = 108;
22462694e23a55d5ca526fc29534a80a200e2c58698bBen Murdoch
22470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Private handler for handling javascript and saving passwords
22480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private Handler mHandler = new Handler() {
22490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
22500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public void handleMessage(Message msg) {
22510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            switch (msg.what) {
22520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                case FOCUS_NODE_HREF:
22532694e23a55d5ca526fc29534a80a200e2c58698bBen Murdoch                {
22540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    String url = (String) msg.getData().get("url");
225590d088caeee718f89755ee9c25249ba6da15ab97Ben Murdoch                    String title = (String) msg.getData().get("title");
22560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    if (url == null || url.length() == 0) {
22570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        break;
22580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
22590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    HashMap focusNodeMap = (HashMap) msg.obj;
22600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    WebView view = (WebView) focusNodeMap.get("webview");
22610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // Only apply the action if the top window did not change.
22620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    if (getTopWindow() != view) {
22630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        break;
22640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
22650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    switch (msg.arg1) {
22660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        case R.id.open_context_menu_id:
22670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        case R.id.view_image_context_menu_id:
226892472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins                            loadUrlFromContext(getTopWindow(), url);
22690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            break;
22700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        case R.id.open_newtab_context_menu_id:
227122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            final Tab parent = mTabControl.getCurrentTab();
227222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            final Tab newTab = openTab(url);
2273c9181841c7ed6b9f7dfc953eab8dc7ba1047022cGrace Kloba                            if (newTab != parent) {
2274c9181841c7ed6b9f7dfc953eab8dc7ba1047022cGrace Kloba                                parent.addChildTab(newTab);
2275c9181841c7ed6b9f7dfc953eab8dc7ba1047022cGrace Kloba                            }
22760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            break;
22770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        case R.id.bookmark_context_menu_id:
22780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            Intent intent = new Intent(BrowserActivity.this,
22790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    AddBookmarkPage.class);
22800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            intent.putExtra("url", url);
228190d088caeee718f89755ee9c25249ba6da15ab97Ben Murdoch                            intent.putExtra("title", title);
22820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            startActivity(intent);
22830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            break;
22840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        case R.id.share_link_context_menu_id:
22853e20445506307d2c8d699e1d17fb82a0cedde1d0Leon Scroggins                            sharePage(BrowserActivity.this, title, url, null,
228696afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                                    null);
22870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            break;
22880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        case R.id.copy_link_context_menu_id:
22890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            copy(url);
22900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            break;
22910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        case R.id.save_link_context_menu_id:
22920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        case R.id.download_context_menu_id:
22930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            onDownloadStartNoStream(url, null, null, null, -1);
22940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            break;
22950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
22960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    break;
22972694e23a55d5ca526fc29534a80a200e2c58698bBen Murdoch                }
22980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
22990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                case LOAD_URL:
230092472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins                    loadUrlFromContext(getTopWindow(), (String) msg.obj);
23010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    break;
23020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
23030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                case STOP_LOAD:
23040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    stopLoading();
23050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    break;
23060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
23070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                case RELEASE_WAKELOCK:
23080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    if (mWakeLock.isHeld()) {
23090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        mWakeLock.release();
23105d0e02e646e46b14289168f75c2a8f6ed43cac54Grace Kloba                        // if we reach here, Browser should be still in the
23115d0e02e646e46b14289168f75c2a8f6ed43cac54Grace Kloba                        // background loading after WAKELOCK_TIMEOUT (5-min).
23125d0e02e646e46b14289168f75c2a8f6ed43cac54Grace Kloba                        // To avoid burning the battery, stop loading.
23135d0e02e646e46b14289168f75c2a8f6ed43cac54Grace Kloba                        mTabControl.stopAllLoading();
23140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
23150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    break;
23162694e23a55d5ca526fc29534a80a200e2c58698bBen Murdoch
23172694e23a55d5ca526fc29534a80a200e2c58698bBen Murdoch                case UPDATE_BOOKMARK_THUMBNAIL:
23182694e23a55d5ca526fc29534a80a200e2c58698bBen Murdoch                    WebView view = (WebView) msg.obj;
23192694e23a55d5ca526fc29534a80a200e2c58698bBen Murdoch                    if (view != null) {
23202694e23a55d5ca526fc29534a80a200e2c58698bBen Murdoch                        updateScreenshot(view);
23212694e23a55d5ca526fc29534a80a200e2c58698bBen Murdoch                    }
23222694e23a55d5ca526fc29534a80a200e2c58698bBen Murdoch                    break;
23230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
23240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
23250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    };
23260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
232796afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins    /**
232896afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins     * Share a page, providing the title, url, favicon, and a screenshot.  Uses
232996afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins     * an {@link Intent} to launch the Activity chooser.
233096afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins     * @param c Context used to launch a new Activity.
233196afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins     * @param title Title of the page.  Stored in the Intent with
233203e6d39560d7de359782485d4c863d600b34fb51Paul Westbrook     *          {@link Intent#EXTRA_SUBJECT}
233396afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins     * @param url URL of the page.  Stored in the Intent with
233496afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins     *          {@link Intent#EXTRA_TEXT}
233596afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins     * @param favicon Bitmap of the favicon for the page.  Stored in the Intent
233696afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins     *          with {@link Browser#EXTRA_SHARE_FAVICON}
233796afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins     * @param screenshot Bitmap of a screenshot of the page.  Stored in the
233896afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins     *          Intent with {@link Browser#EXTRA_SHARE_SCREENSHOT}
233996afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins     */
234096afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins    public static final void sharePage(Context c, String title, String url,
234196afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins            Bitmap favicon, Bitmap screenshot) {
234296afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins        Intent send = new Intent(Intent.ACTION_SEND);
234396afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins        send.setType("text/plain");
234496afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins        send.putExtra(Intent.EXTRA_TEXT, url);
234503e6d39560d7de359782485d4c863d600b34fb51Paul Westbrook        send.putExtra(Intent.EXTRA_SUBJECT, title);
234696afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins        send.putExtra(Browser.EXTRA_SHARE_FAVICON, favicon);
234796afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins        send.putExtra(Browser.EXTRA_SHARE_SCREENSHOT, screenshot);
234896afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins        try {
234996afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins            c.startActivity(Intent.createChooser(send, c.getString(
235096afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                    R.string.choosertitle_sharevia)));
235196afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins        } catch(android.content.ActivityNotFoundException ex) {
235296afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins            // if no app handles it, do nothing
235396afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins        }
235496afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins    }
235596afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins
235689c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins    private void updateScreenshot(WebView view) {
235789c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins        // If this is a bookmarked site, add a screenshot to the database.
235889c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins        // FIXME: When should we update?  Every time?
235989c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins        // FIXME: Would like to make sure there is actually something to
236089c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins        // draw, but the API for that (WebViewCore.pictureReady()) is not
236189c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins        // currently accessible here.
2362aac7aa6fcfcb519755987ec126be066323f589c8Ben Murdoch
2363cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott        final Bitmap bm = createScreenshot(view);
2364cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott        if (bm == null) {
2365cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott            return;
2366cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott        }
2367cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott
2368cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott        final ContentResolver cr = getContentResolver();
2369cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott        final String url = view.getUrl();
2370cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott        final String originalUrl = view.getOriginalUrl();
2371cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott
2372cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott        new AsyncTask<Void, Void, Void>() {
2373cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott            @Override
2374cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott            protected Void doInBackground(Void... unused) {
2375cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott                Cursor c = null;
2376cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott                try {
2377cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott                    c = BrowserBookmarksAdapter.queryBookmarksForUrl(
2378cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott                            cr, originalUrl, url, true);
2379cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott                    if (c != null) {
2380cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott                        if (c.moveToFirst()) {
2381cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott                            ContentValues values = new ContentValues();
2382cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott                            final ByteArrayOutputStream os
2383cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott                                    = new ByteArrayOutputStream();
2384cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott                            bm.compress(Bitmap.CompressFormat.PNG, 100, os);
2385cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott                            values.put(Browser.BookmarkColumns.THUMBNAIL,
2386cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott                                    os.toByteArray());
2387cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott                            do {
2388cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott                                cr.update(ContentUris.withAppendedId(
2389cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott                                        Browser.BOOKMARKS_URI, c.getInt(0)),
2390cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott                                        values, null, null);
2391cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott                            } while (c.moveToNext());
2392cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott                        }
23934580057e772b60433272af5cd691825748892693Leon Scroggins                    }
2394cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott                } catch (IllegalStateException e) {
2395cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott                    // Ignore
2396cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott                } finally {
2397cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott                    if (c != null) c.close();
239889c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins                }
2399cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott                return null;
240089c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins            }
2401cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott        }.execute();
240289c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins    }
240389c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins
240406ec5f2d8735d1ba17b779deb0f8da032e0a62eaLeon Scroggins    /**
2405f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins     * Values for the size of the thumbnail created when taking a screenshot.
2406f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins     * Lazily initialized.  Instead of using these directly, use
2407f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins     * getDesiredThumbnailWidth() or getDesiredThumbnailHeight().
240806ec5f2d8735d1ba17b779deb0f8da032e0a62eaLeon Scroggins     */
2409f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins    private static int THUMBNAIL_WIDTH = 0;
2410f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins    private static int THUMBNAIL_HEIGHT = 0;
2411f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins
2412f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins    /**
2413f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins     * Return the desired width for thumbnail screenshots, which are stored in
2414f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins     * the database, and used on the bookmarks screen.
2415f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins     * @param context Context for finding out the density of the screen.
2416f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins     * @return int desired width for thumbnail screenshot.
2417f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins     */
2418f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins    /* package */ static int getDesiredThumbnailWidth(Context context) {
2419f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins        if (THUMBNAIL_WIDTH == 0) {
2420f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins            float density = context.getResources().getDisplayMetrics().density;
2421f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins            THUMBNAIL_WIDTH = (int) (90 * density);
2422f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins            THUMBNAIL_HEIGHT = (int) (80 * density);
2423f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins        }
2424f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins        return THUMBNAIL_WIDTH;
2425f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins    }
2426f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins
2427f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins    /**
2428f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins     * Return the desired height for thumbnail screenshots, which are stored in
2429f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins     * the database, and used on the bookmarks screen.
2430f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins     * @param context Context for finding out the density of the screen.
2431f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins     * @return int desired height for thumbnail screenshot.
2432f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins     */
2433f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins    /* package */ static int getDesiredThumbnailHeight(Context context) {
2434f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins        // To ensure that they are both initialized.
2435f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins        getDesiredThumbnailWidth(context);
2436f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins        return THUMBNAIL_HEIGHT;
2437f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins    }
243806ec5f2d8735d1ba17b779deb0f8da032e0a62eaLeon Scroggins
2439dcc2b6f08dd5677bc6ba761a9ba6f1c655113051Ben Murdoch    private Bitmap createScreenshot(WebView view) {
2440dcc2b6f08dd5677bc6ba761a9ba6f1c655113051Ben Murdoch        Picture thumbnail = view.capturePicture();
24414580057e772b60433272af5cd691825748892693Leon Scroggins        if (thumbnail == null) {
24424580057e772b60433272af5cd691825748892693Leon Scroggins            return null;
24434580057e772b60433272af5cd691825748892693Leon Scroggins        }
2444f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins        Bitmap bm = Bitmap.createBitmap(getDesiredThumbnailWidth(this),
2445ab168ba86162b4e89e74d0a077b9c618437cbce4Cary Clark                getDesiredThumbnailHeight(this), Bitmap.Config.RGB_565);
2446dcc2b6f08dd5677bc6ba761a9ba6f1c655113051Ben Murdoch        Canvas canvas = new Canvas(bm);
2447dcc2b6f08dd5677bc6ba761a9ba6f1c655113051Ben Murdoch        // May need to tweak these values to determine what is the
2448dcc2b6f08dd5677bc6ba761a9ba6f1c655113051Ben Murdoch        // best scale factor
24492694e23a55d5ca526fc29534a80a200e2c58698bBen Murdoch        int thumbnailWidth = thumbnail.getWidth();
2450ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch        int thumbnailHeight = thumbnail.getHeight();
2451ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch        float scaleFactorX = 1.0f;
2452ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch        float scaleFactorY = 1.0f;
24532694e23a55d5ca526fc29534a80a200e2c58698bBen Murdoch        if (thumbnailWidth > 0) {
2454ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch            scaleFactorX = (float) getDesiredThumbnailWidth(this) /
24552694e23a55d5ca526fc29534a80a200e2c58698bBen Murdoch                    (float)thumbnailWidth;
2456ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch        } else {
2457ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch            return null;
245806ec5f2d8735d1ba17b779deb0f8da032e0a62eaLeon Scroggins        }
2459ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch
2460ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch        if (view.getWidth() > view.getHeight() &&
2461ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch                thumbnailHeight < view.getHeight() && thumbnailHeight > 0) {
2462ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch            // If the device is in landscape and the page is shorter
2463ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch            // than the height of the view, stretch the thumbnail to fill the
2464ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch            // space.
2465ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch            scaleFactorY = (float) getDesiredThumbnailHeight(this) /
2466ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch                    (float)thumbnailHeight;
2467ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch        } else {
2468ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch            // In the portrait case, this looks nice.
2469ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch            scaleFactorY = scaleFactorX;
2470ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch        }
2471ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch
2472ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch        canvas.scale(scaleFactorX, scaleFactorY);
2473ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch
2474dcc2b6f08dd5677bc6ba761a9ba6f1c655113051Ben Murdoch        thumbnail.draw(canvas);
2475dcc2b6f08dd5677bc6ba761a9ba6f1c655113051Ben Murdoch        return bm;
2476dcc2b6f08dd5677bc6ba761a9ba6f1c655113051Ben Murdoch    }
2477dcc2b6f08dd5677bc6ba761a9ba6f1c655113051Ben Murdoch
24780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // -------------------------------------------------------------------------
247922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // Helper function for WebViewClient.
24800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    //-------------------------------------------------------------------------
24810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
24820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Use in overrideUrlLoading
24830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /* package */ final static String SCHEME_WTAI = "wtai://wp/";
24840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /* package */ final static String SCHEME_WTAI_MC = "wtai://wp/mc;";
24850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /* package */ final static String SCHEME_WTAI_SD = "wtai://wp/sd;";
24860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /* package */ final static String SCHEME_WTAI_AP = "wtai://wp/ap;";
24870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
248892472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins    // Keep this initial progress in sync with initialProgressValue (* 100)
248992472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins    // in ProgressTracker.cpp
249092472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins    private final static int INITIAL_PROGRESS = 10;
249192472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins
249222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void onPageStarted(WebView view, String url, Bitmap favicon) {
249322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // when BrowserActivity just starts, onPageStarted may be called before
249422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // onResume as it is triggered from onCreate. Call resumeWebViewTimers
249522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // to start the timer. As we won't switch tabs while an activity is in
249622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // pause state, we can ensure calling resume and pause in pair.
249722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mActivityInPause) resumeWebViewTimers();
249822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
249922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        resetLockIcon(url);
250022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        setUrlTitle(url, null);
250122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        setFavicon(favicon);
25028cf8f682e90f004d4b8028d2f5b74f72c0cf4e19Leon Scroggins        // Show some progress so that the user knows the page is beginning to
25038cf8f682e90f004d4b8028d2f5b74f72c0cf4e19Leon Scroggins        // load
250492472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins        onProgressChanged(view, INITIAL_PROGRESS);
250522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mDidStopLoad = false;
250622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (!mIsNetworkUp) createAndShowNetworkDialog();
2507211ba54a3052f7e68bf8af035ea1ef4e9445130cLeon Scroggins III        if (view.getFindIsUp()) {
2508211ba54a3052f7e68bf8af035ea1ef4e9445130cLeon Scroggins III            closeFind();
2509211ba54a3052f7e68bf8af035ea1ef4e9445130cLeon Scroggins III        }
251022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mSettings.isTracing()) {
251122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            String host;
251222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            try {
251322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                WebAddress uri = new WebAddress(url);
251422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                host = uri.mHost;
251522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            } catch (android.net.ParseException ex) {
251622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                host = "browser";
251722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
251822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            host = host.replace('.', '_');
251922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            host += ".trace";
252022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mInTrace = true;
252122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            Debug.startMethodTracing(host, 20 * 1024 * 1024);
252215525d48024d325c8a52766d8ca727191251a8d4Patrick Scott        }
252315525d48024d325c8a52766d8ca727191251a8d4Patrick Scott
252422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Performance probe
252522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (false) {
252622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mStart = SystemClock.uptimeMillis();
252722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mProcessStart = Process.getElapsedCpuTime();
252822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            long[] sysCpu = new long[7];
252922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (Process.readProcFile("/proc/stat", SYSTEM_CPU_FORMAT, null,
253022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    sysCpu, null)) {
253122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                mUserStart = sysCpu[0] + sysCpu[1];
253222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                mSystemStart = sysCpu[2];
253322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                mIdleStart = sysCpu[3];
253422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                mIrqStart = sysCpu[4] + sysCpu[5] + sysCpu[6];
253522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
253622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mUiStart = SystemClock.currentThreadTimeMillis();
25370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
25380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
25390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
254022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void onPageFinished(WebView view, String url) {
254122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Reset the title and icon in case we stopped a provisional load.
254222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        resetTitleAndIcon(view);
254322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Update the lock icon image only once we are done loading
254422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        updateLockIconToLatest();
254522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // pause the WebView timer and release the wake lock if it is finished
254622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // while BrowserActivity is in pause state.
254722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mActivityInPause && pauseWebViewTimers()) {
254822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (mWakeLock.isHeld()) {
254922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                mHandler.removeMessages(RELEASE_WAKELOCK);
255022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                mWakeLock.release();
255122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
255222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
255322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
255422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Performance probe
255522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (false) {
255622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            long[] sysCpu = new long[7];
255722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (Process.readProcFile("/proc/stat", SYSTEM_CPU_FORMAT, null,
255822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    sysCpu, null)) {
255922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                String uiInfo = "UI thread used "
256022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        + (SystemClock.currentThreadTimeMillis() - mUiStart)
256122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        + " ms";
256222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                if (LOGD_ENABLED) {
256322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    Log.d(LOGTAG, uiInfo);
256422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                }
256522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                //The string that gets written to the log
256622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                String performanceString = "It took total "
256722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        + (SystemClock.uptimeMillis() - mStart)
256822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        + " ms clock time to load the page."
256922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        + "\nbrowser process used "
257022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        + (Process.getElapsedCpuTime() - mProcessStart)
257122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        + " ms, user processes used "
257222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        + (sysCpu[0] + sysCpu[1] - mUserStart) * 10
257322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        + " ms, kernel used "
257422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        + (sysCpu[2] - mSystemStart) * 10
257522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        + " ms, idle took " + (sysCpu[3] - mIdleStart) * 10
257622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        + " ms and irq took "
257722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        + (sysCpu[4] + sysCpu[5] + sysCpu[6] - mIrqStart)
257822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        * 10 + " ms, " + uiInfo;
257922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                if (LOGD_ENABLED) {
258022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    Log.d(LOGTAG, performanceString + "\nWebpage: " + url);
25810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
258222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                if (url != null) {
258322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    // strip the url to maintain consistency
258422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    String newUrl = new String(url);
258522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    if (newUrl.startsWith("http://www.")) {
258622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        newUrl = newUrl.substring(11);
258722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    } else if (newUrl.startsWith("http://")) {
258822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        newUrl = newUrl.substring(7);
258922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    } else if (newUrl.startsWith("https://www.")) {
259022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        newUrl = newUrl.substring(12);
259122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    } else if (newUrl.startsWith("https://")) {
259222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        newUrl = newUrl.substring(8);
25930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
259431a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort                    if (LOGD_ENABLED) {
259522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        Log.d(LOGTAG, newUrl + " loaded");
25960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
25970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
25980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
259922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         }
26000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
260122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mInTrace) {
260222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mInTrace = false;
260322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            Debug.stopMethodTracing();
26040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
260522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
26060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
260722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    boolean shouldOverrideUrlLoading(WebView view, String url) {
260822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (url.startsWith(SCHEME_WTAI)) {
260922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // wtai://wp/mc;number
261022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // number=string(phone-number)
261122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (url.startsWith(SCHEME_WTAI_MC)) {
261222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                Intent intent = new Intent(Intent.ACTION_VIEW,
261322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        Uri.parse(WebView.SCHEME_TEL +
261422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        url.substring(SCHEME_WTAI_MC.length())));
261522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                startActivity(intent);
261622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                return true;
26170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
261822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // wtai://wp/sd;dtmf
261922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // dtmf=string(dialstring)
262022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (url.startsWith(SCHEME_WTAI_SD)) {
262122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                // TODO: only send when there is active voice connection
26229918943559193e3e047a1c18442e2cdb0fe22b15Dianne Hackborn                return false;
26239918943559193e3e047a1c18442e2cdb0fe22b15Dianne Hackborn            }
262422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // wtai://wp/ap;number;name
262522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // number=string(phone-number)
262622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // name=string
262722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (url.startsWith(SCHEME_WTAI_AP)) {
262822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                // TODO
26290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                return false;
26300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
26310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
26320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
263322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // The "about:" schemes are internal to the browser; don't want these to
263422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // be dispatched to other apps.
263522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (url.startsWith("about:")) {
263622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            return false;
26370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
26380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
263922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        Intent intent;
264022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // perform generic parsing of the URI to turn it into an Intent.
264122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        try {
264222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            intent = Intent.parseUri(url, Intent.URI_INTENT_SCHEME);
264322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        } catch (URISyntaxException ex) {
264422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            Log.w("Browser", "Bad URI " + url + ": " + ex.getMessage());
264522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            return false;
26460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
26470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
264822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // check whether the intent can be resolved. If not, we will see
264922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // whether we can download it from the Market.
265022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (getPackageManager().resolveActivity(intent, 0) == null) {
265122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            String packagename = intent.getPackage();
265222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (packagename != null) {
265322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                intent = new Intent(Intent.ACTION_VIEW, Uri
265422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        .parse("market://search?q=pname:" + packagename));
265522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                intent.addCategory(Intent.CATEGORY_BROWSABLE);
265622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                startActivity(intent);
265722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                return true;
26580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } else {
26590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                return false;
26600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
26610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
26620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
266322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // sanitize the Intent, ensuring web pages can not bypass browser
266422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // security (only access to BROWSABLE activities).
266522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        intent.addCategory(Intent.CATEGORY_BROWSABLE);
266622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        intent.setComponent(null);
266722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        try {
266822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (startActivityIfNeeded(intent, -1)) {
26690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                return true;
26700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
267122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        } catch (ActivityNotFoundException ex) {
267222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // ignore the error. If no application can handle the URL,
267322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // eg about:blank, assume the browser can handle it.
267422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
26750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
267622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mMenuIsDown) {
267722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            openTab(url);
267822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            closeOptionsMenu();
26790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return true;
26800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
268122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return false;
268222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
26830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
268422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // -------------------------------------------------------------------------
268522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // Helper function for WebChromeClient
268622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // -------------------------------------------------------------------------
26870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
268822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void onProgressChanged(WebView view, int newProgress) {
2689d746a94137a87ffcc1fcefdac9a3764c3bc3f5cdLeon Scroggins        if (mXLargeScreenSize) {
2690d746a94137a87ffcc1fcefdac9a3764c3bc3f5cdLeon Scroggins            mTitleBar.setProgress(newProgress);
2691d746a94137a87ffcc1fcefdac9a3764c3bc3f5cdLeon Scroggins        } else {
2692d746a94137a87ffcc1fcefdac9a3764c3bc3f5cdLeon Scroggins            // On the phone, the fake title bar will always cover up the
2693d746a94137a87ffcc1fcefdac9a3764c3bc3f5cdLeon Scroggins            // regular title bar (or the regular one is offscreen), so only the
2694d746a94137a87ffcc1fcefdac9a3764c3bc3f5cdLeon Scroggins            // fake title bar needs to change its progress
2695d746a94137a87ffcc1fcefdac9a3764c3bc3f5cdLeon Scroggins            mFakeTitleBar.setProgress(newProgress);
2696d746a94137a87ffcc1fcefdac9a3764c3bc3f5cdLeon Scroggins        }
269722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
269822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (newProgress == 100) {
269922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // onProgressChanged() may continue to be called after the main
270022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // frame has finished loading, as any remaining sub frames continue
270122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // to load. We'll only get called once though with newProgress as
270222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // 100 when everything is loaded. (onPageFinished is called once
270322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // when the main frame completes loading regardless of the state of
270422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // any sub frames so calls to onProgressChanges may continue after
270522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // onPageFinished has executed)
270622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (mInLoad) {
270722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                mInLoad = false;
2708a27ff19e24cb1c9fef5624dbc4554548349b5b31Leon Scroggins                updateInLoadMenuItems();
270922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                // If the options menu is open, leave the title bar
271022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                if (!mOptionsMenuOpen || !mIconView) {
271122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    hideFakeTitleBar();
27120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
27130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
2714aa37e7fdb52d0180b8eea25d53950c5c0791f968Leon Scroggins        } else {
2715aa37e7fdb52d0180b8eea25d53950c5c0791f968Leon Scroggins            if (!mInLoad) {
2716aa37e7fdb52d0180b8eea25d53950c5c0791f968Leon Scroggins                // onPageFinished may have already been called but a subframe is
2717aa37e7fdb52d0180b8eea25d53950c5c0791f968Leon Scroggins                // still loading and updating the progress. Reset mInLoad and
2718aa37e7fdb52d0180b8eea25d53950c5c0791f968Leon Scroggins                // update the menu items.
2719aa37e7fdb52d0180b8eea25d53950c5c0791f968Leon Scroggins                mInLoad = true;
2720aa37e7fdb52d0180b8eea25d53950c5c0791f968Leon Scroggins                updateInLoadMenuItems();
2721aa37e7fdb52d0180b8eea25d53950c5c0791f968Leon Scroggins            }
2722aa37e7fdb52d0180b8eea25d53950c5c0791f968Leon Scroggins            // When the page first begins to load, the Activity may still be
2723aa37e7fdb52d0180b8eea25d53950c5c0791f968Leon Scroggins            // paused, in which case showFakeTitleBar will do nothing.  Call
2724aa37e7fdb52d0180b8eea25d53950c5c0791f968Leon Scroggins            // again as the page continues to load so that it will be shown.
2725aa37e7fdb52d0180b8eea25d53950c5c0791f968Leon Scroggins            // (Calling it will the fake title bar is already showing will also
2726aa37e7fdb52d0180b8eea25d53950c5c0791f968Leon Scroggins            // do nothing.
272722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (!mOptionsMenuOpen || mIconView) {
272822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                // This page has begun to load, so show the title bar
272922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                showFakeTitleBar();
27303918d4443ff38ef1870e02aa51a8b29f8352bb1aPatrick Scott            }
27310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
273222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
2733092dd5d22d7f2ee0efcc68bd6e5a3afd1ea98953Ben Murdoch
273422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void onShowCustomView(View view, WebChromeClient.CustomViewCallback callback) {
27358ff57db0a8dc8eb659fbcdcd4a856208609e6070Derek Sollenberger        // if a view already exists then immediately terminate the new one
27368ff57db0a8dc8eb659fbcdcd4a856208609e6070Derek Sollenberger        if (mCustomView != null) {
27378ff57db0a8dc8eb659fbcdcd4a856208609e6070Derek Sollenberger            callback.onCustomViewHidden();
273822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            return;
27398ff57db0a8dc8eb659fbcdcd4a856208609e6070Derek Sollenberger        }
27402bc69918d97a767a02132090e58718077381ba1aSteve Block
274122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Add the custom view to its container.
274222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mCustomViewContainer.addView(view, COVER_SCREEN_GRAVITY_CENTER);
274322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mCustomView = view;
274422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mCustomViewCallback = callback;
274522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Save the menu state and set it to empty while the custom
274622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // view is showing.
274722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mOldMenuState = mMenuState;
274822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mMenuState = EMPTY_MENU;
274922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Hide the content view.
275022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mContentView.setVisibility(View.GONE);
275122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Finally show the custom view container.
2752163ab74e2f85b53a1a374c49677073fb64d35f28Andrei Popescu        setStatusBarVisibility(false);
275322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mCustomViewContainer.setVisibility(View.VISIBLE);
275422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mCustomViewContainer.bringToFront();
275522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
275622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
275722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void onHideCustomView() {
275822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mCustomView == null)
275922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            return;
27602bc69918d97a767a02132090e58718077381ba1aSteve Block
276122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Hide the custom view.
276222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mCustomView.setVisibility(View.GONE);
276322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Remove the custom view from its container.
276422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mCustomViewContainer.removeView(mCustomView);
276522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mCustomView = null;
276622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Reset the old menu state.
276722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mMenuState = mOldMenuState;
276822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mOldMenuState = EMPTY_MENU;
276922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mCustomViewContainer.setVisibility(View.GONE);
277022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mCustomViewCallback.onCustomViewHidden();
277122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Show the content view.
2772163ab74e2f85b53a1a374c49677073fb64d35f28Andrei Popescu        setStatusBarVisibility(true);
277322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mContentView.setVisibility(View.VISIBLE);
277422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
2775540035dfd1347c78eeec10ec0847e18fcc50ef36Andrei Popescu
277622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    Bitmap getDefaultVideoPoster() {
277722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mDefaultVideoPoster == null) {
277822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mDefaultVideoPoster = BitmapFactory.decodeResource(
277922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    getResources(), R.drawable.default_video_poster);
2780540035dfd1347c78eeec10ec0847e18fcc50ef36Andrei Popescu        }
278122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return mDefaultVideoPoster;
278222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
2783540035dfd1347c78eeec10ec0847e18fcc50ef36Andrei Popescu
278422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    View getVideoLoadingProgressView() {
278522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mVideoProgressView == null) {
278622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            LayoutInflater inflater = LayoutInflater.from(BrowserActivity.this);
278722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mVideoProgressView = inflater.inflate(
278822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    R.layout.video_loading_progress, null);
2789540035dfd1347c78eeec10ec0847e18fcc50ef36Andrei Popescu        }
279022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return mVideoProgressView;
279122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
27920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
27938d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins    /*
27948d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins     * The Object used to inform the WebView of the file to upload.
27958d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins     */
27968d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins    private ValueCallback<Uri> mUploadMessage;
27978d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins
279822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void openFileChooser(ValueCallback<Uri> uploadMsg) {
279922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mUploadMessage != null) return;
280022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mUploadMessage = uploadMsg;
280122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        Intent i = new Intent(Intent.ACTION_GET_CONTENT);
280222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        i.addCategory(Intent.CATEGORY_OPENABLE);
280322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        i.setType("*/*");
280422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        BrowserActivity.this.startActivityForResult(Intent.createChooser(i,
280522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                getString(R.string.choose_upload)), FILE_SELECTED);
280622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
280722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
280822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // -------------------------------------------------------------------------
280922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // Implement functions for DownloadListener
281022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // -------------------------------------------------------------------------
281122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
28120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
28130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Notify the host application a download should be done, or that
28140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * the data should be streamed if a streaming viewer is available.
28150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param url The full url to the content that should be downloaded
28160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param contentDisposition Content-disposition http header, if
28170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *                           present.
28180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param mimetype The mimetype of the content reported by the server
28190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param contentLength The file size reported by the server
28200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
28210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public void onDownloadStart(String url, String userAgent,
28220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            String contentDisposition, String mimetype, long contentLength) {
28230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // if we're dealing wih A/V content that's not explicitly marked
28240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        //     for download, check if it's streamable.
28250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (contentDisposition == null
2826e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                || !contentDisposition.regionMatches(
2827e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                        true, 0, "attachment", 0, 10)) {
28280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // query the package manager to see if there's a registered handler
28290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            //     that matches.
28300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Intent intent = new Intent(Intent.ACTION_VIEW);
28310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            intent.setDataAndType(Uri.parse(url), mimetype);
2832e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott            ResolveInfo info = getPackageManager().resolveActivity(intent,
2833e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                    PackageManager.MATCH_DEFAULT_ONLY);
2834e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott            if (info != null) {
2835e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                ComponentName myName = getComponentName();
2836e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                // If we resolved to ourselves, we don't want to attempt to
2837e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                // load the url only to try and download it again.
2838e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                if (!myName.getPackageName().equals(
2839e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                        info.activityInfo.packageName)
2840e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                        || !myName.getClassName().equals(
2841e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                                info.activityInfo.name)) {
2842e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                    // someone (other than us) knows how to handle this mime
2843e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                    // type with this scheme, don't download.
2844e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                    try {
2845e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                        startActivity(intent);
2846e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                        return;
2847e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                    } catch (ActivityNotFoundException ex) {
2848e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                        if (LOGD_ENABLED) {
2849e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                            Log.d(LOGTAG, "activity not found for " + mimetype
2850e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                                    + " over " + Uri.parse(url).getScheme(),
2851e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                                    ex);
2852e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                        }
2853e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                        // Best behavior is to fall back to a download in this
2854e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                        // case
28550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
28560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
28570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
28580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
28590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        onDownloadStartNoStream(url, userAgent, contentDisposition, mimetype, contentLength);
28600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
28610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
2862fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen    // This is to work around the fact that java.net.URI throws Exceptions
2863fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen    // instead of just encoding URL's properly
2864fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen    // Helper method for onDownloadStartNoStream
2865fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen    private static String encodePath(String path) {
2866fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen        char[] chars = path.toCharArray();
2867fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen
2868fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen        boolean needed = false;
2869fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen        for (char c : chars) {
2870fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen            if (c == '[' || c == ']') {
2871fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen                needed = true;
2872fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen                break;
2873fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen            }
2874fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen        }
2875fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen        if (needed == false) {
2876fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen            return path;
2877fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen        }
2878fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen
2879fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen        StringBuilder sb = new StringBuilder("");
2880fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen        for (char c : chars) {
2881fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen            if (c == '[' || c == ']') {
2882fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen                sb.append('%');
2883fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen                sb.append(Integer.toHexString(c));
2884fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen            } else {
2885fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen                sb.append(c);
2886fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen            }
2887fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen        }
2888fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen
2889fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen        return sb.toString();
2890fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen    }
2891fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen
28920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
28930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Notify the host application a download should be done, even if there
28940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * is a streaming viewer available for thise type.
28950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param url The full url to the content that should be downloaded
28960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param contentDisposition Content-disposition http header, if
28970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *                           present.
28980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param mimetype The mimetype of the content reported by the server
28990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param contentLength The file size reported by the server
29000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
29010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /*package */ void onDownloadStartNoStream(String url, String userAgent,
29020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            String contentDisposition, String mimetype, long contentLength) {
29030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
29040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String filename = URLUtil.guessFileName(url,
29050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                contentDisposition, mimetype);
29060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
29070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Check to see if we have an SDCard
29080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String status = Environment.getExternalStorageState();
29090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (!status.equals(Environment.MEDIA_MOUNTED)) {
29100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            int title;
29110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            String msg;
29120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
29130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Check to see if the SDCard is busy, same as the music app
29140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (status.equals(Environment.MEDIA_SHARED)) {
29150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                msg = getString(R.string.download_sdcard_busy_dlg_msg);
29160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                title = R.string.download_sdcard_busy_dlg_title;
29170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } else {
29180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                msg = getString(R.string.download_no_sdcard_dlg_msg, filename);
29190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                title = R.string.download_no_sdcard_dlg_title;
29200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
29210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
29220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            new AlertDialog.Builder(this)
29230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setTitle(title)
29240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setIcon(android.R.drawable.ic_dialog_alert)
29250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setMessage(msg)
29260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setPositiveButton(R.string.ok, null)
29270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .show();
29280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
29290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
29300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
2931fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen        // java.net.URI is a lot stricter than KURL so we have to encode some
2932fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen        // extra characters. Fix for b 2538060 and b 1634719
2933fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen        WebAddress webAddress;
29340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        try {
2935fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen            webAddress = new WebAddress(url);
2936fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen            webAddress.mPath = encodePath(webAddress.mPath);
29370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } catch (Exception e) {
2938fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen            // This only happens for very bad urls, we want to chatch the
2939fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen            // exception here
2940fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen            Log.e(LOGTAG, "Exception trying to parse url:" + url);
29410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
29420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
29430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
29440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // XXX: Have to use the old url since the cookies were stored using the
29450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // old percent-encoded url.
29460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String cookies = CookieManager.getInstance().getCookie(url);
29470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
29480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        ContentValues values = new ContentValues();
2949fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen        values.put(Downloads.Impl.COLUMN_URI, webAddress.toString());
29501e5bad97ca8fb9b12501f4f747941d02f03e1362Jean-Baptiste Queru        values.put(Downloads.Impl.COLUMN_COOKIE_DATA, cookies);
29511e5bad97ca8fb9b12501f4f747941d02f03e1362Jean-Baptiste Queru        values.put(Downloads.Impl.COLUMN_USER_AGENT, userAgent);
29521e5bad97ca8fb9b12501f4f747941d02f03e1362Jean-Baptiste Queru        values.put(Downloads.Impl.COLUMN_NOTIFICATION_PACKAGE,
29530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                getPackageName());
29541e5bad97ca8fb9b12501f4f747941d02f03e1362Jean-Baptiste Queru        values.put(Downloads.Impl.COLUMN_NOTIFICATION_CLASS,
2955a563d09392905140893d7a017dd63721577e1953Leon Scroggins                OpenDownloadReceiver.class.getCanonicalName());
29561e5bad97ca8fb9b12501f4f747941d02f03e1362Jean-Baptiste Queru        values.put(Downloads.Impl.COLUMN_VISIBILITY,
29571e5bad97ca8fb9b12501f4f747941d02f03e1362Jean-Baptiste Queru                Downloads.Impl.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
29581e5bad97ca8fb9b12501f4f747941d02f03e1362Jean-Baptiste Queru        values.put(Downloads.Impl.COLUMN_MIME_TYPE, mimetype);
29591e5bad97ca8fb9b12501f4f747941d02f03e1362Jean-Baptiste Queru        values.put(Downloads.Impl.COLUMN_FILE_NAME_HINT, filename);
2960fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen        values.put(Downloads.Impl.COLUMN_DESCRIPTION, webAddress.mHost);
29610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (contentLength > 0) {
29621e5bad97ca8fb9b12501f4f747941d02f03e1362Jean-Baptiste Queru            values.put(Downloads.Impl.COLUMN_TOTAL_BYTES, contentLength);
29630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
29640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mimetype == null) {
29650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // We must have long pressed on a link or image to download it. We
29660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // are not sure of the mimetype in this case, so do a head request
29670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            new FetchUrlMimeType(this).execute(values);
29680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
29690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            final Uri contentUri =
29701e5bad97ca8fb9b12501f4f747941d02f03e1362Jean-Baptiste Queru                    getContentResolver().insert(Downloads.Impl.CONTENT_URI, values);
29710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
29729191a7f745c965cf57df94d0628890b413c710c9Leon Scroggins        Toast.makeText(this, R.string.download_pending, Toast.LENGTH_SHORT)
29739191a7f745c965cf57df94d0628890b413c710c9Leon Scroggins                .show();
29740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
29750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
297622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // -------------------------------------------------------------------------
297722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
29780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
29790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Resets the lock icon. This method is called when we start a new load and
29800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * know the url to be loaded.
29810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
29820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void resetLockIcon(String url) {
29830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Save the lock-icon state (we revert to it if the load gets cancelled)
298422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mTabControl.getCurrentTab().resetLockIcon(url);
29850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        updateLockIconImage(LOCK_ICON_UNSECURE);
29860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
29870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
29880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
29893bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     * Update the lock icon to correspond to our latest state.
29903bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     */
299122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private void updateLockIconToLatest() {
299222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        updateLockIconImage(mTabControl.getCurrentTab().getLockIconType());
29933bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    }
29943bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins
29953bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    /**
29960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Updates the lock-icon image in the title-bar.
29970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
29980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void updateLockIconImage(int lockIconType) {
29990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        Drawable d = null;
30000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (lockIconType == LOCK_ICON_SECURE) {
30010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            d = mSecLockIcon;
30020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else if (lockIconType == LOCK_ICON_MIXED) {
30030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            d = mMixLockIcon;
30040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
300568579393973f745fc65a2781061af9bb8f2d7020Leon Scroggins        mTitleBar.setLock(d);
3006d746a94137a87ffcc1fcefdac9a3764c3bc3f5cdLeon Scroggins        if (!mXLargeScreenSize) {
3007d746a94137a87ffcc1fcefdac9a3764c3bc3f5cdLeon Scroggins            mFakeTitleBar.setLock(d);
3008d746a94137a87ffcc1fcefdac9a3764c3bc3f5cdLeon Scroggins        }
30090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
30100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
30110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
30120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Displays a page-info dialog.
30130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param tab The tab to show info about
30140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param fromShowSSLCertificateOnError The flag that indicates whether
30150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * this dialog was opened from the SSL-certificate-on-error dialog or
30160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * not. This is important, since we need to know whether to return to
30170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * the parent dialog or simply dismiss.
30180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
301922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private void showPageInfo(final Tab tab,
30200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                              final boolean fromShowSSLCertificateOnError) {
30210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final LayoutInflater factory = LayoutInflater
30220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .from(this);
30230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
30240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final View pageInfoView = factory.inflate(R.layout.page_info, null);
30250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
30260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final WebView view = tab.getWebView();
30270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
30280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String url = null;
30290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String title = null;
30300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
30310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (view == null) {
30320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            url = tab.getUrl();
30330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            title = tab.getTitle();
30340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else if (view == mTabControl.getCurrentWebView()) {
30350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project             // Use the cached title and url if this is the current WebView
30360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            url = mUrl;
30370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            title = mTitle;
30380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
30390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            url = view.getUrl();
30400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            title = view.getTitle();
30410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
30420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
30430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (url == null) {
30440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            url = "";
30450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
30460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (title == null) {
30470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            title = "";
30480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
30490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
30500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        ((TextView) pageInfoView.findViewById(R.id.address)).setText(url);
30510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        ((TextView) pageInfoView.findViewById(R.id.title)).setText(title);
30520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
30530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mPageInfoView = tab;
3054c7b92f811dfa3572578ddc6714c98a03936d9ce5Leon Scroggins        mPageInfoFromShowSSLCertificateOnError = fromShowSSLCertificateOnError;
30550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
30560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        AlertDialog.Builder alertDialogBuilder =
30570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            new AlertDialog.Builder(this)
30580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            .setTitle(R.string.page_info).setIcon(android.R.drawable.ic_dialog_info)
30590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            .setView(pageInfoView)
30600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            .setPositiveButton(
30610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                R.string.ok,
30620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                new DialogInterface.OnClickListener() {
30630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    public void onClick(DialogInterface dialog,
30640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        int whichButton) {
30650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        mPageInfoDialog = null;
30660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        mPageInfoView = null;
30670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
30680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        // if we came here from the SSL error dialog
30690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        if (fromShowSSLCertificateOnError) {
30700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            // go back to the SSL error dialog
30710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            showSSLCertificateOnError(
30720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorView,
30730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorHandler,
30740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorError);
30750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }
30760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
30770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                })
30780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            .setOnCancelListener(
30790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                new DialogInterface.OnCancelListener() {
30800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    public void onCancel(DialogInterface dialog) {
30810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        mPageInfoDialog = null;
30820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        mPageInfoView = null;
30830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
30840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        // if we came here from the SSL error dialog
30850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        if (fromShowSSLCertificateOnError) {
30860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            // go back to the SSL error dialog
30870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            showSSLCertificateOnError(
30880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorView,
30890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorHandler,
30900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorError);
30910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }
30920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
30930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                });
30940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
30950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // if we have a main top-level page SSL certificate set or a certificate
30960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // error
30970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (fromShowSSLCertificateOnError ||
30980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                (view != null && view.getCertificate() != null)) {
30990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // add a 'View Certificate' button
31000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            alertDialogBuilder.setNeutralButton(
31010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                R.string.view_certificate,
31020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                new DialogInterface.OnClickListener() {
31030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    public void onClick(DialogInterface dialog,
31040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        int whichButton) {
31050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        mPageInfoDialog = null;
31060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        mPageInfoView = null;
31070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
31080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        // if we came here from the SSL error dialog
31090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        if (fromShowSSLCertificateOnError) {
31100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            // go back to the SSL error dialog
31110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            showSSLCertificateOnError(
31120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorView,
31130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorHandler,
31140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorError);
31150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        } else {
31160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            // otherwise, display the top-most certificate from
31170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            // the chain
31180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            if (view.getCertificate() != null) {
31190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                showSSLCertificate(tab);
31200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            }
31210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }
31220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
31230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                });
31240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
31250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
31260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mPageInfoDialog = alertDialogBuilder.show();
31270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
31280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
31290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project       /**
31300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Displays the main top-level page SSL certificate dialog
31310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * (accessible from the Page-Info dialog).
31320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param tab The tab to show certificate for.
31330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
313422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private void showSSLCertificate(final Tab tab) {
31350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final View certificateView =
31360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                inflateCertificateView(tab.getWebView().getCertificate());
31370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (certificateView == null) {
31380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
31390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
31400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
31410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        LayoutInflater factory = LayoutInflater.from(this);
31420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
31430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final LinearLayout placeholder =
31440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                (LinearLayout)certificateView.findViewById(R.id.placeholder);
31450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
31460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        LinearLayout ll = (LinearLayout) factory.inflate(
31470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            R.layout.ssl_success, placeholder);
31480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        ((TextView)ll.findViewById(R.id.success))
31490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            .setText(R.string.ssl_certificate_is_valid);
31500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
31510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mSSLCertificateView = tab;
31520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mSSLCertificateDialog =
31530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            new AlertDialog.Builder(this)
31540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setTitle(R.string.ssl_certificate).setIcon(
31550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    R.drawable.ic_dialog_browser_certificate_secure)
31560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setView(certificateView)
31570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setPositiveButton(R.string.ok,
31580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new DialogInterface.OnClickListener() {
31590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            public void onClick(DialogInterface dialog,
31600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    int whichButton) {
31610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateDialog = null;
31620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateView = null;
31630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
31640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                showPageInfo(tab, false);
31650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            }
31660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        })
31670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setOnCancelListener(
31680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new DialogInterface.OnCancelListener() {
31690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            public void onCancel(DialogInterface dialog) {
31700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateDialog = null;
31710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateView = null;
31720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
31730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                showPageInfo(tab, false);
31740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            }
31750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        })
31760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .show();
31770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
31780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
31790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
31800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Displays the SSL error certificate dialog.
31810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param view The target web-view.
31820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param handler The SSL error handler responsible for cancelling the
31830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * connection that resulted in an SSL error or proceeding per user request.
31840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param error The SSL error object.
31850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
318622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void showSSLCertificateOnError(
31870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final WebView view, final SslErrorHandler handler, final SslError error) {
31880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
31890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final View certificateView =
31900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            inflateCertificateView(error.getCertificate());
31910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (certificateView == null) {
31920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
31930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
31940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
31950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        LayoutInflater factory = LayoutInflater.from(this);
31960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
31970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final LinearLayout placeholder =
31980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                (LinearLayout)certificateView.findViewById(R.id.placeholder);
31990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
32000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (error.hasError(SslError.SSL_UNTRUSTED)) {
32010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            LinearLayout ll = (LinearLayout)factory
32020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .inflate(R.layout.ssl_warning, placeholder);
32030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((TextView)ll.findViewById(R.id.warning))
32040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setText(R.string.ssl_untrusted);
32050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
32060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
32070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (error.hasError(SslError.SSL_IDMISMATCH)) {
32080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            LinearLayout ll = (LinearLayout)factory
32090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .inflate(R.layout.ssl_warning, placeholder);
32100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((TextView)ll.findViewById(R.id.warning))
32110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setText(R.string.ssl_mismatch);
32120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
32130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
32140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (error.hasError(SslError.SSL_EXPIRED)) {
32150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            LinearLayout ll = (LinearLayout)factory
32160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .inflate(R.layout.ssl_warning, placeholder);
32170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((TextView)ll.findViewById(R.id.warning))
32180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setText(R.string.ssl_expired);
32190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
32200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
32210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (error.hasError(SslError.SSL_NOTYETVALID)) {
32220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            LinearLayout ll = (LinearLayout)factory
32230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .inflate(R.layout.ssl_warning, placeholder);
32240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((TextView)ll.findViewById(R.id.warning))
32250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setText(R.string.ssl_not_yet_valid);
32260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
32270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
32280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mSSLCertificateOnErrorHandler = handler;
32290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mSSLCertificateOnErrorView = view;
32300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mSSLCertificateOnErrorError = error;
32310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mSSLCertificateOnErrorDialog =
32320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            new AlertDialog.Builder(this)
32330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setTitle(R.string.ssl_certificate).setIcon(
32340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    R.drawable.ic_dialog_browser_certificate_partially_secure)
32350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setView(certificateView)
32360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setPositiveButton(R.string.ok,
32370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new DialogInterface.OnClickListener() {
32380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            public void onClick(DialogInterface dialog,
32390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    int whichButton) {
32400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorDialog = null;
32410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorView = null;
32420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorHandler = null;
32430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorError = null;
32440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
324522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                view.getWebViewClient().onReceivedSslError(
324622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                                view, handler, error);
32470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            }
32480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        })
32490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                 .setNeutralButton(R.string.page_info_view,
32500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new DialogInterface.OnClickListener() {
32510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            public void onClick(DialogInterface dialog,
32520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    int whichButton) {
32530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorDialog = null;
32540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
32550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                // do not clear the dialog state: we will
32560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                // need to show the dialog again once the
32570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                // user is done exploring the page-info details
32580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
32590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                showPageInfo(mTabControl.getTabFromView(view),
32600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        true);
32610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            }
32620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        })
32630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setOnCancelListener(
32640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new DialogInterface.OnCancelListener() {
32650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            public void onCancel(DialogInterface dialog) {
32660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorDialog = null;
32670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorView = null;
32680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorHandler = null;
32690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorError = null;
32700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
327122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                view.getWebViewClient().onReceivedSslError(
327222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                                view, handler, error);
32730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            }
32740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        })
32750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .show();
32760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
32770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
32780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
32790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Inflates the SSL certificate view (helper method).
32800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param certificate The SSL certificate.
32810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @return The resultant certificate view with issued-to, issued-by,
32820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * issued-on, expires-on, and possibly other fields set.
32830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * If the input certificate is null, returns null.
32840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
32850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private View inflateCertificateView(SslCertificate certificate) {
32860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (certificate == null) {
32870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return null;
32880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
32890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
32900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        LayoutInflater factory = LayoutInflater.from(this);
32910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
32920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        View certificateView = factory.inflate(
32930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            R.layout.ssl_certificate, null);
32940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
32950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // issued to:
32960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        SslCertificate.DName issuedTo = certificate.getIssuedTo();
32970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (issuedTo != null) {
32980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((TextView) certificateView.findViewById(R.id.to_common))
32990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setText(issuedTo.getCName());
33000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((TextView) certificateView.findViewById(R.id.to_org))
33010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setText(issuedTo.getOName());
33020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((TextView) certificateView.findViewById(R.id.to_org_unit))
33030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setText(issuedTo.getUName());
33040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
33050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
33060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // issued by:
33070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        SslCertificate.DName issuedBy = certificate.getIssuedBy();
33080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (issuedBy != null) {
33090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((TextView) certificateView.findViewById(R.id.by_common))
33100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setText(issuedBy.getCName());
33110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((TextView) certificateView.findViewById(R.id.by_org))
33120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setText(issuedBy.getOName());
33130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((TextView) certificateView.findViewById(R.id.by_org_unit))
33140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setText(issuedBy.getUName());
33150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
33160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
33170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // issued on:
331895a2e4ab94514e4e41033b0d27a0e66855cff8ebBrian Carlstrom        String issuedOn = formatCertificateDate(
331995a2e4ab94514e4e41033b0d27a0e66855cff8ebBrian Carlstrom            certificate.getValidNotBeforeDate());
33200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        ((TextView) certificateView.findViewById(R.id.issued_on))
33210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            .setText(issuedOn);
33220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
33230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // expires on:
332495a2e4ab94514e4e41033b0d27a0e66855cff8ebBrian Carlstrom        String expiresOn = formatCertificateDate(
332595a2e4ab94514e4e41033b0d27a0e66855cff8ebBrian Carlstrom            certificate.getValidNotAfterDate());
33260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        ((TextView) certificateView.findViewById(R.id.expires_on))
33270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            .setText(expiresOn);
33280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
33290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return certificateView;
33300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
33310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
33320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
333395a2e4ab94514e4e41033b0d27a0e66855cff8ebBrian Carlstrom     * Formats the certificate date to a properly localized date string.
33340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @return Properly localized version of the certificate date string and
333595a2e4ab94514e4e41033b0d27a0e66855cff8ebBrian Carlstrom     * the "" if it fails to localize.
33360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
333795a2e4ab94514e4e41033b0d27a0e66855cff8ebBrian Carlstrom    private String formatCertificateDate(Date certificateDate) {
333895a2e4ab94514e4e41033b0d27a0e66855cff8ebBrian Carlstrom      if (certificateDate == null) {
333995a2e4ab94514e4e41033b0d27a0e66855cff8ebBrian Carlstrom          return "";
33400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project      }
334195a2e4ab94514e4e41033b0d27a0e66855cff8ebBrian Carlstrom      String formattedDate = DateFormat.getDateFormat(this).format(certificateDate);
334295a2e4ab94514e4e41033b0d27a0e66855cff8ebBrian Carlstrom      if (formattedDate == null) {
334395a2e4ab94514e4e41033b0d27a0e66855cff8ebBrian Carlstrom          return "";
334495a2e4ab94514e4e41033b0d27a0e66855cff8ebBrian Carlstrom      }
334595a2e4ab94514e4e41033b0d27a0e66855cff8ebBrian Carlstrom      return formattedDate;
33460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
33470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
33480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
33490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Displays an http-authentication dialog.
33500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
335122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void showHttpAuthentication(final HttpAuthHandler handler,
33520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            final String host, final String realm, final String title,
33530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            final String name, final String password, int focusId) {
33540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        LayoutInflater factory = LayoutInflater.from(this);
33550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final View v = factory
33560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .inflate(R.layout.http_authentication, null);
33570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (name != null) {
33580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((EditText) v.findViewById(R.id.username_edit)).setText(name);
33590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
33600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (password != null) {
33610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((EditText) v.findViewById(R.id.password_edit)).setText(password);
33620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
33630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
33640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String titleText = title;
33650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (titleText == null) {
33660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            titleText = getText(R.string.sign_in_to).toString().replace(
33670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    "%s1", host).replace("%s2", realm);
33680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
33690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
33700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mHttpAuthHandler = handler;
33710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        AlertDialog dialog = new AlertDialog.Builder(this)
33720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setTitle(titleText)
33730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setIcon(android.R.drawable.ic_dialog_alert)
33740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setView(v)
33750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setPositiveButton(R.string.action,
33760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new DialogInterface.OnClickListener() {
33770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                             public void onClick(DialogInterface dialog,
33780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                     int whichButton) {
33790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                String nm = ((EditText) v
33800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        .findViewById(R.id.username_edit))
33810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        .getText().toString();
33820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                String pw = ((EditText) v
33830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        .findViewById(R.id.password_edit))
33840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        .getText().toString();
33850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                BrowserActivity.this.setHttpAuthUsernamePassword
33860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        (host, realm, nm, pw);
33870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                handler.proceed(nm, pw);
33880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mHttpAuthenticationDialog = null;
33890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mHttpAuthHandler = null;
33900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            }})
33910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setNegativeButton(R.string.cancel,
33920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new DialogInterface.OnClickListener() {
33930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            public void onClick(DialogInterface dialog,
33940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    int whichButton) {
33950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                handler.cancel();
33960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                BrowserActivity.this.resetTitleAndRevertLockIcon();
33970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mHttpAuthenticationDialog = null;
33980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mHttpAuthHandler = null;
33990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            }})
34000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setOnCancelListener(new DialogInterface.OnCancelListener() {
34010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        public void onCancel(DialogInterface dialog) {
34020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            handler.cancel();
34030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            BrowserActivity.this.resetTitleAndRevertLockIcon();
34040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            mHttpAuthenticationDialog = null;
34050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            mHttpAuthHandler = null;
34060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }})
34070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .create();
34080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Make the IME appear when the dialog is displayed if applicable.
34090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        dialog.getWindow().setSoftInputMode(
34100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);
34110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        dialog.show();
34120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (focusId != 0) {
34130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            dialog.findViewById(focusId).requestFocus();
34140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
34150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            v.findViewById(R.id.username_edit).requestFocus();
34160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
34170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mHttpAuthenticationDialog = dialog;
34180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
34190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
34200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public int getProgress() {
34210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebView w = mTabControl.getCurrentWebView();
34220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (w != null) {
34230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return w.getProgress();
34240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
34250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return 100;
34260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
34270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
34280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
34290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
34300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Set HTTP authentication password.
34310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *
34320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param host The host for the password
34330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param realm The realm for the password
34340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param username The username for the password. If it is null, it means
34350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *            password can't be saved.
34360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param password The password
34370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
34380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public void setHttpAuthUsernamePassword(String host, String realm,
34390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                            String username,
34400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                            String password) {
344195a53b25504f12c3a5f8ecbbfcff7ac1dc047e4fSteve Block        WebView w = getTopWindow();
34420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (w != null) {
34430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            w.setHttpAuthUsernamePassword(host, realm, username, password);
34440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
34450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
34460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
34470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
34480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * connectivity manager says net has come or gone... inform the user
34490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param up true if net has come up, false if net has gone down
34500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
34510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public void onNetworkToggle(boolean up) {
34520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (up == mIsNetworkUp) {
34530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
34540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else if (up) {
34550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mIsNetworkUp = true;
34560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (mAlertDialog != null) {
34570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mAlertDialog.cancel();
34580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mAlertDialog = null;
34590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
34600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
34610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mIsNetworkUp = false;
3462eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott            if (mInLoad) {
3463eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott                createAndShowNetworkDialog();
3464eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott           }
34650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
34660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebView w = mTabControl.getCurrentWebView();
34670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (w != null) {
34680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            w.setNetworkAvailable(up);
34690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
34700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
34710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
347222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    boolean isNetworkUp() {
347322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return mIsNetworkUp;
347422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
347522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
3476eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott    // This method shows the network dialog alerting the user that the net is
3477eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott    // down. It will only show the dialog if mAlertDialog is null.
3478eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott    private void createAndShowNetworkDialog() {
3479eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott        if (mAlertDialog == null) {
3480eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott            mAlertDialog = new AlertDialog.Builder(this)
3481eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott                    .setTitle(R.string.loadSuspendedTitle)
3482eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott                    .setMessage(R.string.loadSuspended)
3483eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott                    .setPositiveButton(R.string.ok, null)
3484eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott                    .show();
3485eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott        }
3486eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott    }
3487eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott
34880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    @Override
34890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    protected void onActivityResult(int requestCode, int resultCode,
34900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    Intent intent) {
3491bb394f3e134b6e5898ef7ae861b75e95e618688fGrace Kloba        if (getTopWindow() == null) return;
3492bb394f3e134b6e5898ef7ae861b75e95e618688fGrace Kloba
34930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        switch (requestCode) {
34940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case COMBO_PAGE:
34950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (resultCode == RESULT_OK && intent != null) {
34960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    String data = intent.getAction();
34970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    Bundle extras = intent.getExtras();
34980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    if (extras != null && extras.getBoolean("new_window", false)) {
349925d3547e0df084f963e38c6a93c99b02bd619de3Leon Scroggins                        openTab(data);
35000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    } else {
350122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        final Tab currentTab =
35020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mTabControl.getCurrentTab();
35031f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                        dismissSubWindow(currentTab);
35041f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                        if (data != null && data.length() != 0) {
350592472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins                            loadUrl(getTopWindow(), data);
35060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }
35070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
35080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
3509fde9746ac3055848e110c35f19ec5893c621f766Leon Scroggins                // Deliberately fall through to PREFERENCES_PAGE, since the
3510fde9746ac3055848e110c35f19ec5893c621f766Leon Scroggins                // same extra may be attached to the COMBO_PAGE
3511fde9746ac3055848e110c35f19ec5893c621f766Leon Scroggins            case PREFERENCES_PAGE:
3512fde9746ac3055848e110c35f19ec5893c621f766Leon Scroggins                if (resultCode == RESULT_OK && intent != null) {
3513fde9746ac3055848e110c35f19ec5893c621f766Leon Scroggins                    String action = intent.getStringExtra(Intent.EXTRA_TEXT);
3514fde9746ac3055848e110c35f19ec5893c621f766Leon Scroggins                    if (BrowserSettings.PREF_CLEAR_HISTORY.equals(action)) {
3515fde9746ac3055848e110c35f19ec5893c621f766Leon Scroggins                        mTabControl.removeParentChildRelationShips();
3516fde9746ac3055848e110c35f19ec5893c621f766Leon Scroggins                    }
3517fde9746ac3055848e110c35f19ec5893c621f766Leon Scroggins                }
35180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
35198d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins            // Choose a file from the file picker.
35208d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins            case FILE_SELECTED:
35218d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins                if (null == mUploadMessage) break;
35228d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins                Uri result = intent == null || resultCode != RESULT_OK ? null
35238d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins                        : intent.getData();
35248d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins                mUploadMessage.onReceiveValue(result);
35258d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins                mUploadMessage = null;
35268d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins                break;
35270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            default:
35280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
35290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
3530304442375719effd41dbd53ae62de7a8d0cec7d9Leon Scroggins        getTopWindow().requestFocus();
35310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
35320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
35330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /*
35340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * This method is called as a result of the user selecting the options
3535f08809b2cf7e502fef5965691a7fb6d7cf0322afLeon Scroggins     * menu to see the download window. It shows the download window on top of
3536f08809b2cf7e502fef5965691a7fb6d7cf0322afLeon Scroggins     * the current window.
35370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
3538f08809b2cf7e502fef5965691a7fb6d7cf0322afLeon Scroggins    private void viewDownloads(Uri downloadRecord) {
35390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        Intent intent = new Intent(this,
35400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                BrowserDownloadPage.class);
35410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        intent.setData(downloadRecord);
354222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        startActivityForResult(intent, BrowserActivity.DOWNLOAD_PAGE);
35430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
35440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
35450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
3546160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins    /**
3547160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins     * Open the Go page.
3548160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins     * @param startWithHistory If true, open starting on the history tab.
3549160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins     *                         Otherwise, start with the bookmarks tab.
3550160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins     */
3551304442375719effd41dbd53ae62de7a8d0cec7d9Leon Scroggins    /* package */ void bookmarksOrHistoryPicker(boolean startWithHistory) {
35520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebView current = mTabControl.getCurrentWebView();
35530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (current == null) {
35540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
35550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
35560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        Intent intent = new Intent(this,
35570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                CombinedBookmarkHistoryActivity.class);
35580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String title = current.getTitle();
35590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String url = current.getUrl();
3560dcc2b6f08dd5677bc6ba761a9ba6f1c655113051Ben Murdoch        Bitmap thumbnail = createScreenshot(current);
3561dcc2b6f08dd5677bc6ba761a9ba6f1c655113051Ben Murdoch
35620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Just in case the user opens bookmarks before a page finishes loading
35630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // so the current history item, and therefore the page, is null.
35640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (null == url) {
35650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            url = mLastEnteredUrl;
35660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // This can happen.
35670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (null == url) {
35680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                url = mSettings.getHomePage();
35690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
35700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
35710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // In case the web page has not yet received its associated title.
35720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (title == null) {
35730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            title = url;
35740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
35750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        intent.putExtra("title", title);
35760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        intent.putExtra("url", url);
3577dcc2b6f08dd5677bc6ba761a9ba6f1c655113051Ben Murdoch        intent.putExtra("thumbnail", thumbnail);
3578304442375719effd41dbd53ae62de7a8d0cec7d9Leon Scroggins        // Disable opening in a new window if we have maxed out the windows
357922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        intent.putExtra("disable_new_window", !mTabControl.canCreateNewTab());
35803918d4443ff38ef1870e02aa51a8b29f8352bb1aPatrick Scott        intent.putExtra("touch_icon_url", current.getTouchIconUrl());
35810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (startWithHistory) {
35820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            intent.putExtra(CombinedBookmarkHistoryActivity.STARTING_TAB,
35830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    CombinedBookmarkHistoryActivity.HISTORY_TAB);
35840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
35850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        startActivityForResult(intent, COMBO_PAGE);
35860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
35870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
35880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Called when loading from context menu or LOAD_URL message
358992472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins    private void loadUrlFromContext(WebView view, String url) {
35900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // In case the user enters nothing.
35910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (url != null && url.length() != 0 && view != null) {
35920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            url = smartUrlFilter(url);
359322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (!view.getWebViewClient().shouldOverrideUrlLoading(view, url)) {
359492472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins                loadUrl(view, url);
35950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
35960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
35970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
35980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
359992472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins    /**
360092472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins     * Load the URL into the given WebView and update the title bar
360192472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins     * to reflect the new load.  Call this instead of WebView.loadUrl
360292472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins     * directly.
360392472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins     * @param view The WebView used to load url.
360492472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins     * @param url The URL to load.
360592472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins     */
360692472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins    private void loadUrl(WebView view, String url) {
360792472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins        updateTitleBarForNewLoad(view, url);
360892472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins        view.loadUrl(url);
360992472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins    }
361092472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins
361192472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins    /**
361292472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins     * Load UrlData into a Tab and update the title bar to reflect the new
361392472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins     * load.  Call this instead of UrlData.loadIn directly.
361492472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins     * @param t The Tab used to load.
361592472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins     * @param data The UrlData being loaded.
361692472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins     */
361792472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins    private void loadUrlDataIn(Tab t, UrlData data) {
361892472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins        updateTitleBarForNewLoad(t.getWebView(), data.mUrl);
361992472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins        data.loadIn(t);
362092472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins    }
362192472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins
362292472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins    /**
362392472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins     * If the WebView is the top window, update the title bar to reflect
362492472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins     * loading the new URL.  i.e. set its text, clear the favicon (which
362592472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins     * will be set once the page begins loading), and set the progress to
362692472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins     * INITIAL_PROGRESS to show that the page has begun to load. Called
362792472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins     * by loadUrl and loadUrlDataIn.
362892472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins     * @param view The WebView that is starting a load.
362992472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins     * @param url The URL that is being loaded.
363092472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins     */
363192472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins    private void updateTitleBarForNewLoad(WebView view, String url) {
363292472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins        if (view == getTopWindow()) {
363392472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins            setUrlTitle(url, null);
363492472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins            setFavicon(null);
363592472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins            onProgressChanged(view, INITIAL_PROGRESS);
363692472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins        }
363792472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins    }
363892472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins
36390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private String smartUrlFilter(Uri inUri) {
36400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (inUri != null) {
36410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return smartUrlFilter(inUri.toString());
36420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
36430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return null;
36440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
36450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
3646b34f87a2e13af13d697130482af01b537ab7c5fdFeng Qian    protected static final Pattern ACCEPTED_URI_SCHEMA = Pattern.compile(
36470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            "(?i)" + // switch on case insensitive matching
36480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            "(" +    // begin group for schema
36490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            "(?:http|https|file):\\/\\/" +
365025ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima            "|(?:inline|data|about|content|javascript):" +
36510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ")" +
36520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            "(.*)" );
36530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
36540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
36550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Attempts to determine whether user input is a URL or search
36560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * terms.  Anything with a space is passed to search.
36570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *
36580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Converts to lowercase any mistakenly uppercased schema (i.e.,
36590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * "Http://" converts to "http://"
36600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *
36610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @return Original or modified URL
36620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *
36630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
36640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    String smartUrlFilter(String url) {
36650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
36660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String inUrl = url.trim();
36670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        boolean hasSpace = inUrl.indexOf(' ') != -1;
36680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
36690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        Matcher matcher = ACCEPTED_URI_SCHEMA.matcher(inUrl);
36700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (matcher.matches()) {
36710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // force scheme to lowercase
36720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            String scheme = matcher.group(1);
36730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            String lcScheme = scheme.toLowerCase();
36740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (!lcScheme.equals(scheme)) {
3675123ecfb21e7ca670e3d04efe58780b3bac54a9a1Mitsuru Oshima                inUrl = lcScheme + matcher.group(2);
3676123ecfb21e7ca670e3d04efe58780b3bac54a9a1Mitsuru Oshima            }
3677123ecfb21e7ca670e3d04efe58780b3bac54a9a1Mitsuru Oshima            if (hasSpace) {
3678123ecfb21e7ca670e3d04efe58780b3bac54a9a1Mitsuru Oshima                inUrl = inUrl.replace(" ", "%20");
36790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
36800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return inUrl;
36810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
36820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (hasSpace) {
3683565505b1a2c1d3099496af5910760087602e994aSatish Sampath            // FIXME: Is this the correct place to add to searches?
3684565505b1a2c1d3099496af5910760087602e994aSatish Sampath            // what if someone else calls this function?
3685565505b1a2c1d3099496af5910760087602e994aSatish Sampath            int shortcut = parseUrlShortcut(inUrl);
3686565505b1a2c1d3099496af5910760087602e994aSatish Sampath            if (shortcut != SHORTCUT_INVALID) {
3687565505b1a2c1d3099496af5910760087602e994aSatish Sampath                Browser.addSearchUrl(mResolver, inUrl);
3688565505b1a2c1d3099496af5910760087602e994aSatish Sampath                String query = inUrl.substring(2);
3689565505b1a2c1d3099496af5910760087602e994aSatish Sampath                switch (shortcut) {
3690565505b1a2c1d3099496af5910760087602e994aSatish Sampath                case SHORTCUT_GOOGLE_SEARCH:
369147fdfdb989ffb79590a39c40792be995de32e521Grace Kloba                    return URLUtil.composeSearchUrl(query, QuickSearch_G, QUERY_PLACE_HOLDER);
3692565505b1a2c1d3099496af5910760087602e994aSatish Sampath                case SHORTCUT_WIKIPEDIA_SEARCH:
3693565505b1a2c1d3099496af5910760087602e994aSatish Sampath                    return URLUtil.composeSearchUrl(query, QuickSearch_W, QUERY_PLACE_HOLDER);
3694565505b1a2c1d3099496af5910760087602e994aSatish Sampath                case SHORTCUT_DICTIONARY_SEARCH:
3695565505b1a2c1d3099496af5910760087602e994aSatish Sampath                    return URLUtil.composeSearchUrl(query, QuickSearch_D, QUERY_PLACE_HOLDER);
3696565505b1a2c1d3099496af5910760087602e994aSatish Sampath                case SHORTCUT_GOOGLE_MOBILE_LOCAL_SEARCH:
36970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // FIXME: we need location in this case
3698565505b1a2c1d3099496af5910760087602e994aSatish Sampath                    return URLUtil.composeSearchUrl(query, QuickSearch_L, QUERY_PLACE_HOLDER);
36990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
37000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
37010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
37025ee906c089567bca705e18561357510d7b55cb5aDan Egnor            if (Patterns.WEB_URL.matcher(inUrl).matches()) {
37030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                return URLUtil.guessUrl(inUrl);
37040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
37050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
37060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
37070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        Browser.addSearchUrl(mResolver, inUrl);
370847fdfdb989ffb79590a39c40792be995de32e521Grace Kloba        return URLUtil.composeSearchUrl(inUrl, QuickSearch_G, QUERY_PLACE_HOLDER);
37090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
37100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
3711bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch    /* package */ void setShouldShowErrorConsole(boolean flag) {
3712bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch        if (flag == mShouldShowErrorConsole) {
3713bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch            // Nothing to do.
3714bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch            return;
3715bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch        }
3716bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch
3717bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch        mShouldShowErrorConsole = flag;
3718bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch
371922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        ErrorConsoleView errorConsole = mTabControl.getCurrentTab()
372022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                .getErrorConsole(true);
3721bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch
3722bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch        if (flag) {
3723bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch            // Setting the show state of the console will cause it's the layout to be inflated.
3724bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch            if (errorConsole.numberOfErrors() > 0) {
3725bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch                errorConsole.showConsole(ErrorConsoleView.SHOW_MINIMIZED);
3726bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch            } else {
3727bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch                errorConsole.showConsole(ErrorConsoleView.SHOW_NONE);
3728bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch            }
3729bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch
3730bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch            // Now we can add it to the main view.
3731bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch            mErrorConsoleContainer.addView(errorConsole,
373215b8ec6b226f4d57307716e1f495e10a91f8cbf4Romain Guy                    new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
3733bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch                                                  ViewGroup.LayoutParams.WRAP_CONTENT));
3734bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch        } else {
3735bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch            mErrorConsoleContainer.removeView(errorConsole);
3736bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch        }
3737bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch
3738bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch    }
3739bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch
374022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    boolean shouldShowErrorConsole() {
374122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return mShouldShowErrorConsole;
374222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
374322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
3744163ab74e2f85b53a1a374c49677073fb64d35f28Andrei Popescu    private void setStatusBarVisibility(boolean visible) {
3745163ab74e2f85b53a1a374c49677073fb64d35f28Andrei Popescu        int flag = visible ? 0 : WindowManager.LayoutParams.FLAG_FULLSCREEN;
3746163ab74e2f85b53a1a374c49677073fb64d35f28Andrei Popescu        getWindow().setFlags(flag, WindowManager.LayoutParams.FLAG_FULLSCREEN);
3747163ab74e2f85b53a1a374c49677073fb64d35f28Andrei Popescu    }
3748163ab74e2f85b53a1a374c49677073fb64d35f28Andrei Popescu
374956199cc25e7ee0455ec2a8099098b66b8554f677Andrei Popescu
375056199cc25e7ee0455ec2a8099098b66b8554f677Andrei Popescu    private void sendNetworkType(String type, String subtype) {
375156199cc25e7ee0455ec2a8099098b66b8554f677Andrei Popescu        WebView w = mTabControl.getCurrentWebView();
375256199cc25e7ee0455ec2a8099098b66b8554f677Andrei Popescu        if (w != null) {
375356199cc25e7ee0455ec2a8099098b66b8554f677Andrei Popescu            w.setNetworkType(type, subtype);
375456199cc25e7ee0455ec2a8099098b66b8554f677Andrei Popescu        }
375556199cc25e7ee0455ec2a8099098b66b8554f677Andrei Popescu    }
375656199cc25e7ee0455ec2a8099098b66b8554f677Andrei Popescu
375730995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu    private void packageChanged(String packageName, boolean wasAdded) {
375830995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu        WebView w = mTabControl.getCurrentWebView();
375930995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu        if (w == null) {
376030995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu            return;
376130995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu        }
376230995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu
376330995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu        if (wasAdded) {
376430995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu            w.addPackageName(packageName);
376530995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu        } else {
376630995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu            w.removePackageName(packageName);
376730995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu        }
376830995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu    }
376930995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu
377030995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu    private void addPackageNames(Set<String> packageNames) {
377130995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu        WebView w = mTabControl.getCurrentWebView();
377230995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu        if (w == null) {
377330995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu            return;
377430995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu        }
377530995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu
377630995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu        w.addPackageNames(packageNames);
377730995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu    }
377830995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu
377930995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu    private void getInstalledPackages() {
378030995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu        AsyncTask<Void, Void, Set<String> > task =
378130995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu            new AsyncTask<Void, Void, Set<String> >() {
378230995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu            protected Set<String> doInBackground(Void... unused) {
378330995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu                Set<String> installedPackages = new HashSet<String>();
378430995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu                PackageManager pm = BrowserActivity.this.getPackageManager();
378530995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu                if (pm != null) {
378630995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu                    List<PackageInfo> packages = pm.getInstalledPackages(0);
378730995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu                    for (PackageInfo p : packages) {
378830995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu                        if (BrowserActivity.this.sGoogleApps.contains(p.packageName)) {
378930995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu                            installedPackages.add(p.packageName);
379030995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu                        }
379130995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu                    }
379230995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu                }
379330995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu
379430995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu                return installedPackages;
379530995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu            }
379630995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu
379730995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu            // Executes on the UI thread
379830995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu            protected void onPostExecute(Set<String> installedPackages) {
379930995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu                addPackageNames(installedPackages);
380030995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu            }
380130995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu        };
380230995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu        task.execute();
380330995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu    }
380430995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu
3805eb6eef4c45df2d65c3e70660493a147a2be405e3Grace Kloba    final static int LOCK_ICON_UNSECURE = 0;
3806eb6eef4c45df2d65c3e70660493a147a2be405e3Grace Kloba    final static int LOCK_ICON_SECURE   = 1;
3807eb6eef4c45df2d65c3e70660493a147a2be405e3Grace Kloba    final static int LOCK_ICON_MIXED    = 2;
38080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
38090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private BrowserSettings mSettings;
38100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private TabControl      mTabControl;
38110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private ContentResolver mResolver;
38120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private FrameLayout     mContentView;
3813adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu    private View            mCustomView;
3814adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu    private FrameLayout     mCustomViewContainer;
3815c9b5556351b59caec77b4eec1ad30652fec6a4d9Andrei Popescu    private WebChromeClient.CustomViewCallback mCustomViewCallback;
38160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
38170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // FIXME, temp address onPrepareMenu performance problem. When we move everything out of
38180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // view, we should rewrite this.
38190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private int mCurrentMenuState = 0;
38200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private int mMenuState = R.id.MAIN_MENU;
3821adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu    private int mOldMenuState = EMPTY_MENU;
38220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private static final int EMPTY_MENU = -1;
38230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private Menu mMenu;
38240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
38250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private FindDialog mFindDialog;
38260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Used to prevent chording to result in firing two shortcuts immediately
38270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // one after another.  Fixes bug 1211714.
38280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    boolean mCanChord;
38290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
38300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private boolean mInLoad;
38310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private boolean mIsNetworkUp;
3832b7cc8b439dc595dc48e1c2183b35d23ad72dfbe5Ben Murdoch    private boolean mDidStopLoad;
38330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
38341f10cbfca5bf96e1466e0ed3ce1dbcd6fcfd0608Cary Clark    /* package */ boolean mActivityInPause = true;
38350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
38360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private boolean mMenuIsDown;
38370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
38380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private static boolean mInTrace;
38390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
38400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Performance probe
38410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private static final int[] SYSTEM_CPU_FORMAT = new int[] {
38420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Process.PROC_SPACE_TERM | Process.PROC_COMBINE,
38430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Process.PROC_SPACE_TERM | Process.PROC_OUT_LONG, // 1: user time
38440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Process.PROC_SPACE_TERM | Process.PROC_OUT_LONG, // 2: nice time
38450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Process.PROC_SPACE_TERM | Process.PROC_OUT_LONG, // 3: sys time
38460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Process.PROC_SPACE_TERM | Process.PROC_OUT_LONG, // 4: idle time
38470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Process.PROC_SPACE_TERM | Process.PROC_OUT_LONG, // 5: iowait time
38480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Process.PROC_SPACE_TERM | Process.PROC_OUT_LONG, // 6: irq time
38490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Process.PROC_SPACE_TERM | Process.PROC_OUT_LONG  // 7: softirq time
38500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    };
38510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
38520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private long mStart;
38530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private long mProcessStart;
38540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private long mUserStart;
38550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private long mSystemStart;
38560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private long mIdleStart;
38570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private long mIrqStart;
38580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
38590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private long mUiStart;
38600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
38610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private Drawable    mMixLockIcon;
38620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private Drawable    mSecLockIcon;
38630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
38640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /* hold a ref so we can auto-cancel if necessary */
38650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private AlertDialog mAlertDialog;
38660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
38670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // The up-to-date URL and title (these can be different from those stored
38680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // in WebView, since it takes some time for the information in WebView to
38690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // get updated)
38700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private String mUrl;
38710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private String mTitle;
38720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
38730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // As PageInfo has different style for landscape / portrait, we have
38740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // to re-open it when configuration changed
38750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private AlertDialog mPageInfoDialog;
387622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private Tab mPageInfoView;
38770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // If the Page-Info dialog is launched from the SSL-certificate-on-error
38780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // dialog, we should not just dismiss it, but should get back to the
38790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // SSL-certificate-on-error dialog. This flag is used to store this state
3880c7b92f811dfa3572578ddc6714c98a03936d9ce5Leon Scroggins    private boolean mPageInfoFromShowSSLCertificateOnError;
38810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
38820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // as SSLCertificateOnError has different style for landscape / portrait,
38830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // we have to re-open it when configuration changed
38840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private AlertDialog mSSLCertificateOnErrorDialog;
38850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private WebView mSSLCertificateOnErrorView;
38860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private SslErrorHandler mSSLCertificateOnErrorHandler;
38870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private SslError mSSLCertificateOnErrorError;
38880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
38890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // as SSLCertificate has different style for landscape / portrait, we
38900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // have to re-open it when configuration changed
38910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private AlertDialog mSSLCertificateDialog;
389222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private Tab mSSLCertificateView;
38930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
38940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // as HttpAuthentication has different style for landscape / portrait, we
38950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // have to re-open it when configuration changed
38960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private AlertDialog mHttpAuthenticationDialog;
38970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private HttpAuthHandler mHttpAuthHandler;
38980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
38990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /*package*/ static final FrameLayout.LayoutParams COVER_SCREEN_PARAMS =
39000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                            new FrameLayout.LayoutParams(
390115b8ec6b226f4d57307716e1f495e10a91f8cbf4Romain Guy                                            ViewGroup.LayoutParams.MATCH_PARENT,
390215b8ec6b226f4d57307716e1f495e10a91f8cbf4Romain Guy                                            ViewGroup.LayoutParams.MATCH_PARENT);
3903adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu    /*package*/ static final FrameLayout.LayoutParams COVER_SCREEN_GRAVITY_CENTER =
3904adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu                                            new FrameLayout.LayoutParams(
390515b8ec6b226f4d57307716e1f495e10a91f8cbf4Romain Guy                                            ViewGroup.LayoutParams.MATCH_PARENT,
390615b8ec6b226f4d57307716e1f495e10a91f8cbf4Romain Guy                                            ViewGroup.LayoutParams.MATCH_PARENT,
3907adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu                                            Gravity.CENTER);
390847fdfdb989ffb79590a39c40792be995de32e521Grace Kloba    // Google search
390947fdfdb989ffb79590a39c40792be995de32e521Grace Kloba    final static String QuickSearch_G = "http://www.google.com/m?q=%s";
39100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Wikipedia search
39110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    final static String QuickSearch_W = "http://en.wikipedia.org/w/index.php?search=%s&go=Go";
39120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Dictionary search
39130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    final static String QuickSearch_D = "http://dictionary.reference.com/search?q=%s";
39140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Google Mobile Local search
39150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    final static String QuickSearch_L = "http://www.google.com/m/search?site=local&q=%s&near=mountain+view";
39160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
39170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    final static String QUERY_PLACE_HOLDER = "%s";
39180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
39190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // "source" parameter for Google search through search key
39200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    final static String GOOGLE_SEARCH_SOURCE_SEARCHKEY = "browser-key";
39210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // "source" parameter for Google search through goto menu
39220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    final static String GOOGLE_SEARCH_SOURCE_GOTO = "browser-goto";
39230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // "source" parameter for Google search through simplily type
39240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    final static String GOOGLE_SEARCH_SOURCE_TYPE = "browser-type";
39250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // "source" parameter for Google search suggested by the browser
39260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    final static String GOOGLE_SEARCH_SOURCE_SUGGEST = "browser-suggest";
39270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // "source" parameter for Google search from unknown source
39280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    final static String GOOGLE_SEARCH_SOURCE_UNKNOWN = "unknown";
39290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
39300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private final static String LOGTAG = "browser";
39310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
39320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private String mLastEnteredUrl;
39330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
39340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private PowerManager.WakeLock mWakeLock;
39350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private final static int WAKELOCK_TIMEOUT = 5 * 60 * 1000; // 5 minutes
39360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
39370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private Toast mStopToast;
39380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
393968579393973f745fc65a2781061af9bb8f2d7020Leon Scroggins    private TitleBar mTitleBar;
394081db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins
3941bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch    private LinearLayout mErrorConsoleContainer = null;
3942bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch    private boolean mShouldShowErrorConsole = false;
3943bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch
39440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // As the ids are dynamically created, we can't guarantee that they will
39450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // be in sequence, so this static array maps ids to a window number.
39460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    final static private int[] WINDOW_SHORTCUT_ID_ARRAY =
39470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    { R.id.window_one_menu_id, R.id.window_two_menu_id, R.id.window_three_menu_id,
39480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project      R.id.window_four_menu_id, R.id.window_five_menu_id, R.id.window_six_menu_id,
39490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project      R.id.window_seven_menu_id, R.id.window_eight_menu_id };
39500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
39510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // monitor platform changes
39520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private IntentFilter mNetworkStateChangedFilter;
39530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private BroadcastReceiver mNetworkStateIntentReceiver;
39540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
3955b4da0ad0351996f639b50f9f29b123a9b5c24fd0Grace Kloba    private BroadcastReceiver mPackageInstallationReceiver;
3956b4da0ad0351996f639b50f9f29b123a9b5c24fd0Grace Kloba
3957a7611811e0d744a7220b7bf80c8f795af5ea53edBjorn Bringert    private SystemAllowGeolocationOrigins mSystemAllowGeolocationOrigins;
3958a7611811e0d744a7220b7bf80c8f795af5ea53edBjorn Bringert
39590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // activity requestCode
396078a98e459323f938e97789a6131beddbebb459ceNicolas Roard    final static int COMBO_PAGE                 = 1;
396178a98e459323f938e97789a6131beddbebb459ceNicolas Roard    final static int DOWNLOAD_PAGE              = 2;
396278a98e459323f938e97789a6131beddbebb459ceNicolas Roard    final static int PREFERENCES_PAGE           = 3;
39638d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins    final static int FILE_SELECTED              = 4;
39640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
3965540035dfd1347c78eeec10ec0847e18fcc50ef36Andrei Popescu    // the default <video> poster
3966540035dfd1347c78eeec10ec0847e18fcc50ef36Andrei Popescu    private Bitmap mDefaultVideoPoster;
3967540035dfd1347c78eeec10ec0847e18fcc50ef36Andrei Popescu    // the video progress view
3968540035dfd1347c78eeec10ec0847e18fcc50ef36Andrei Popescu    private View mVideoProgressView;
3969540035dfd1347c78eeec10ec0847e18fcc50ef36Andrei Popescu
397030995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu    // The Google packages we monitor for the navigator.isApplicationInstalled()
397130995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu    // API. Add as needed.
397230995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu    private static Set<String> sGoogleApps;
397330995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu    static {
397430995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu        sGoogleApps = new HashSet<String>();
397530995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu        sGoogleApps.add("com.google.android.youtube");
397630995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu    }
397730995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu
397825ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima    /**
397925ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima     * A UrlData class to abstract how the content will be set to WebView.
398025ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima     * This base class uses loadUrl to show the content.
398125ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima     */
39826eac63e78d43d04e31c4d16830c44c4d9df82639Leon Scroggins    /* package */ static class UrlData {
3983068e48b469f5abca53ee3da38f933cf2c25c93b8Grace Kloba        final String mUrl;
3984068e48b469f5abca53ee3da38f933cf2c25c93b8Grace Kloba        final Map<String, String> mHeaders;
398558d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        final Intent mVoiceIntent;
398660e095c190496d42327f8ec2ef990c044d15a76fGrace Kloba
398725ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima        UrlData(String url) {
398825ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima            this.mUrl = url;
3989068e48b469f5abca53ee3da38f933cf2c25c93b8Grace Kloba            this.mHeaders = null;
399058d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins            this.mVoiceIntent = null;
399125ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima        }
399260e095c190496d42327f8ec2ef990c044d15a76fGrace Kloba
399358d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        UrlData(String url, Map<String, String> headers, Intent intent) {
3994068e48b469f5abca53ee3da38f933cf2c25c93b8Grace Kloba            this.mUrl = url;
3995068e48b469f5abca53ee3da38f933cf2c25c93b8Grace Kloba            this.mHeaders = headers;
3996a1cc3fdce19a336c251297c61cd83ac6cf767cd1Leon Scroggins            if (RecognizerResultsIntent.ACTION_VOICE_SEARCH_RESULTS
3997a1cc3fdce19a336c251297c61cd83ac6cf767cd1Leon Scroggins                    .equals(intent.getAction())) {
399858d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins                this.mVoiceIntent = intent;
399958d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins            } else {
400058d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins                this.mVoiceIntent = null;
400158d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins            }
400260e095c190496d42327f8ec2ef990c044d15a76fGrace Kloba        }
400360e095c190496d42327f8ec2ef990c044d15a76fGrace Kloba
400425ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima        boolean isEmpty() {
400558d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins            return mVoiceIntent == null && (mUrl == null || mUrl.length() == 0);
400625ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima        }
400725ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima
400892472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins        /**
400992472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins         * Load this UrlData into the given Tab.  Use loadUrlDataIn to update
401092472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins         * the title bar as well.
401192472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins         */
401258d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        public void loadIn(Tab t) {
401358d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins            if (mVoiceIntent != null) {
401458d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins                t.activateVoiceSearchMode(mVoiceIntent);
401558d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins            } else {
401658d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins                t.getWebView().loadUrl(mUrl, mHeaders);
401758d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins            }
401825ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima        }
401925ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima    };
402025ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima
40211f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins    /* package */ static final UrlData EMPTY_URL_DATA = new UrlData(null);
40220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project}
4023