BrowserActivity.java revision cc14c8c4da26ff93a96078c7c9108682c23bd1af
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;
900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.webkit.CookieManager;
910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.webkit.CookieSyncManager;
920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.webkit.DownloadListener;
930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.webkit.HttpAuthHandler;
94b4da0ad0351996f639b50f9f29b123a9b5c24fd0Grace Klobaimport android.webkit.PluginManager;
950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.webkit.SslErrorHandler;
960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.webkit.URLUtil;
97cb6cc864e53f7d916622daf3b2cec133b36d6a55Leon Clarkeimport android.webkit.ValueCallback;
980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.webkit.WebChromeClient;
990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.webkit.WebHistoryItem;
1000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.webkit.WebIconDatabase;
1010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.webkit.WebView;
1020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.widget.EditText;
1030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.widget.FrameLayout;
1040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.widget.LinearLayout;
1050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.widget.TextView;
1060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.widget.Toast;
107752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintanaimport android.accounts.Account;
108752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintanaimport android.accounts.AccountManager;
109752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintanaimport android.accounts.AccountManagerFuture;
110752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintanaimport android.accounts.AuthenticatorException;
111752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintanaimport android.accounts.OperationCanceledException;
112752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintanaimport android.accounts.AccountManagerCallback;
1130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
114d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringertimport com.android.browser.search.SearchEngine;
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
17522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    @Override
17622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    public void onCreate(Bundle icicle) {
17731a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort        if (LOGV_ENABLED) {
1780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Log.v(LOGTAG, this + " onStart");
1790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
1800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        super.onCreate(icicle);
1810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // test the browser in OpenGL
1820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // requestWindowFeature(Window.FEATURE_OPENGL);
1830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
184d334bf564b72416e77e707d25f8c55cfe1d85709Mike Reed        // enable this to test the browser in 32bit
185d334bf564b72416e77e707d25f8c55cfe1d85709Mike Reed        if (false) {
186d334bf564b72416e77e707d25f8c55cfe1d85709Mike Reed            getWindow().setFormat(PixelFormat.RGBX_8888);
187d334bf564b72416e77e707d25f8c55cfe1d85709Mike Reed            BitmapFactory.setDefaultConfig(Bitmap.Config.ARGB_8888);
188d334bf564b72416e77e707d25f8c55cfe1d85709Mike Reed        }
189d334bf564b72416e77e707d25f8c55cfe1d85709Mike Reed
1900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        setDefaultKeyMode(DEFAULT_KEYS_SEARCH_LOCAL);
1910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
1920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mResolver = getContentResolver();
1930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
194cc14c8c4da26ff93a96078c7c9108682c23bd1afLeon Scroggins III        // Keep a settings instance handy.
195cc14c8c4da26ff93a96078c7c9108682c23bd1afLeon Scroggins III        mSettings = BrowserSettings.getInstance();
196cc14c8c4da26ff93a96078c7c9108682c23bd1afLeon Scroggins III
1970923d69a8ca45222cabd82a80eaa88da9f132e9aGrace Kloba        // If this was a web search request, pass it on to the default web
1980923d69a8ca45222cabd82a80eaa88da9f132e9aGrace Kloba        // search provider and finish this activity.
1990923d69a8ca45222cabd82a80eaa88da9f132e9aGrace Kloba        if (handleWebSearchIntent(getIntent())) {
2000923d69a8ca45222cabd82a80eaa88da9f132e9aGrace Kloba            finish();
2010923d69a8ca45222cabd82a80eaa88da9f132e9aGrace Kloba            return;
2020923d69a8ca45222cabd82a80eaa88da9f132e9aGrace Kloba        }
2030923d69a8ca45222cabd82a80eaa88da9f132e9aGrace Kloba
2040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mSecLockIcon = Resources.getSystem().getDrawable(
2050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                android.R.drawable.ic_secure);
2060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mMixLockIcon = Resources.getSystem().getDrawable(
2070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                android.R.drawable.ic_partial_secure);
2080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
20981db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins        FrameLayout frameLayout = (FrameLayout) getWindow().getDecorView()
21081db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins                .findViewById(com.android.internal.R.id.content);
2113bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins        mBrowserFrameLayout = (FrameLayout) LayoutInflater.from(this)
2123bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                .inflate(R.layout.custom_screen, null);
2133bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins        mContentView = (FrameLayout) mBrowserFrameLayout.findViewById(
2143bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                R.id.main_content);
2153bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins        mErrorConsoleContainer = (LinearLayout) mBrowserFrameLayout
2163bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                .findViewById(R.id.error_console);
2173bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins        mCustomViewContainer = (FrameLayout) mBrowserFrameLayout
2183bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                .findViewById(R.id.fullscreen_custom_content);
2193bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins        frameLayout.addView(mBrowserFrameLayout, COVER_SCREEN_PARAMS);
22068579393973f745fc65a2781061af9bb8f2d7020Leon Scroggins        mTitleBar = new TitleBar(this);
2211542f74d866056aac0cc5ffc328940a4b8ba626cGrace Kloba        // mTitleBar will be always shown in the fully loaded mode
2221542f74d866056aac0cc5ffc328940a4b8ba626cGrace Kloba        mTitleBar.setProgress(100);
223fe87bd3a3897e4bad65bb3d284659ae2f4e57570Leon Scroggins        mFakeTitleBar = new TitleBar(this);
2240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
2250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Create the tab control and our initial tab
2260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mTabControl = new TabControl(this);
2270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
2280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Open the icon database and retain all the bookmark urls for favicons
2290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        retainIconsOnStartup();
2300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
2310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mSettings.setTabControl(mTabControl);
2320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
2330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
2340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "Browser");
2350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
2366adacc90222a3293bc631ef88ee5613e23b2d4c0Patrick Scott        // Find out if the network is currently up.
2376adacc90222a3293bc631ef88ee5613e23b2d4c0Patrick Scott        ConnectivityManager cm = (ConnectivityManager) getSystemService(
2386adacc90222a3293bc631ef88ee5613e23b2d4c0Patrick Scott                Context.CONNECTIVITY_SERVICE);
2396adacc90222a3293bc631ef88ee5613e23b2d4c0Patrick Scott        NetworkInfo info = cm.getActiveNetworkInfo();
2406adacc90222a3293bc631ef88ee5613e23b2d4c0Patrick Scott        if (info != null) {
2416adacc90222a3293bc631ef88ee5613e23b2d4c0Patrick Scott            mIsNetworkUp = info.isAvailable();
2426adacc90222a3293bc631ef88ee5613e23b2d4c0Patrick Scott        }
2436adacc90222a3293bc631ef88ee5613e23b2d4c0Patrick Scott
244a34f686112fb4f9fbea00b8c2c47153d34e93e41Grace Kloba        /* enables registration for changes in network status from
245a34f686112fb4f9fbea00b8c2c47153d34e93e41Grace Kloba           http stack */
246a34f686112fb4f9fbea00b8c2c47153d34e93e41Grace Kloba        mNetworkStateChangedFilter = new IntentFilter();
247a34f686112fb4f9fbea00b8c2c47153d34e93e41Grace Kloba        mNetworkStateChangedFilter.addAction(
248a34f686112fb4f9fbea00b8c2c47153d34e93e41Grace Kloba                ConnectivityManager.CONNECTIVITY_ACTION);
249a34f686112fb4f9fbea00b8c2c47153d34e93e41Grace Kloba        mNetworkStateIntentReceiver = new BroadcastReceiver() {
250a34f686112fb4f9fbea00b8c2c47153d34e93e41Grace Kloba                @Override
251a34f686112fb4f9fbea00b8c2c47153d34e93e41Grace Kloba                public void onReceive(Context context, Intent intent) {
252a34f686112fb4f9fbea00b8c2c47153d34e93e41Grace Kloba                    if (intent.getAction().equals(
253a34f686112fb4f9fbea00b8c2c47153d34e93e41Grace Kloba                            ConnectivityManager.CONNECTIVITY_ACTION)) {
254e4c98469644d3fa2689cf6658b1999add13c7e0eAndrei Popescu
255e4c98469644d3fa2689cf6658b1999add13c7e0eAndrei Popescu                        NetworkInfo info = intent.getParcelableExtra(
256e4c98469644d3fa2689cf6658b1999add13c7e0eAndrei Popescu                                ConnectivityManager.EXTRA_NETWORK_INFO);
257e4c98469644d3fa2689cf6658b1999add13c7e0eAndrei Popescu                        String typeName = info.getTypeName();
258e4c98469644d3fa2689cf6658b1999add13c7e0eAndrei Popescu                        String subtypeName = info.getSubtypeName();
259e4c98469644d3fa2689cf6658b1999add13c7e0eAndrei Popescu                        sendNetworkType(typeName.toLowerCase(),
260e4c98469644d3fa2689cf6658b1999add13c7e0eAndrei Popescu                                (subtypeName != null ? subtypeName.toLowerCase() : ""));
261e4c98469644d3fa2689cf6658b1999add13c7e0eAndrei Popescu
262e4c98469644d3fa2689cf6658b1999add13c7e0eAndrei Popescu                        onNetworkToggle(info.isAvailable());
263a34f686112fb4f9fbea00b8c2c47153d34e93e41Grace Kloba                    }
264a34f686112fb4f9fbea00b8c2c47153d34e93e41Grace Kloba                }
265a34f686112fb4f9fbea00b8c2c47153d34e93e41Grace Kloba            };
266a34f686112fb4f9fbea00b8c2c47153d34e93e41Grace Kloba
267615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba        IntentFilter filter = new IntentFilter(Intent.ACTION_PACKAGE_ADDED);
268615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba        filter.addAction(Intent.ACTION_PACKAGE_REMOVED);
269615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba        filter.addDataScheme("package");
270615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba        mPackageInstallationReceiver = new BroadcastReceiver() {
271615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba            @Override
272615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba            public void onReceive(Context context, Intent intent) {
273615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                final String action = intent.getAction();
274615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                final String packageName = intent.getData()
275615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                        .getSchemeSpecificPart();
276615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                final boolean replacing = intent.getBooleanExtra(
277615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                        Intent.EXTRA_REPLACING, false);
278615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                if (Intent.ACTION_PACKAGE_REMOVED.equals(action) && replacing) {
279615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                    // if it is replacing, refreshPlugins() when adding
280615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                    return;
281615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                }
28230995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu
28330995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu                if (sGoogleApps.contains(packageName)) {
28430995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu                    BrowserActivity.this.packageChanged(packageName,
28530995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu                            Intent.ACTION_PACKAGE_ADDED.equals(action));
28630995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu                }
28730995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu
288615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                PackageManager pm = BrowserActivity.this.getPackageManager();
289615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                PackageInfo pkgInfo = null;
290615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                try {
291615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                    pkgInfo = pm.getPackageInfo(packageName,
292615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                            PackageManager.GET_PERMISSIONS);
293615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                } catch (PackageManager.NameNotFoundException e) {
294615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                    return;
295615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                }
296615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                if (pkgInfo != null) {
297615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                    String permissions[] = pkgInfo.requestedPermissions;
298615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                    if (permissions == null) {
299615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                        return;
300615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                    }
301615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                    boolean permissionOk = false;
302615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                    for (String permit : permissions) {
303615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                        if (PluginManager.PLUGIN_PERMISSION.equals(permit)) {
304615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                            permissionOk = true;
305615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                            break;
306615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                        }
307615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                    }
308615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                    if (permissionOk) {
309615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                        PluginManager.getInstance(BrowserActivity.this)
310615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                                .refreshPlugins(
311615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                                        Intent.ACTION_PACKAGE_ADDED
312615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                                                .equals(action));
313615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                    }
314615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                }
315615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba            }
316615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba        };
317615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba        registerReceiver(mPackageInstallationReceiver, filter);
318615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba
3190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (!mTabControl.restoreState(icicle)) {
3200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // clear up the thumbnail directory if we can't restore the state as
3210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // none of the files in the directory are referenced any more.
3220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            new ClearThumbnails().execute(
3230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    mTabControl.getThumbnailDir().listFiles());
324aab3f09b5c2d39b19067e57635614080b2403a46Grace Kloba            // there is no quit on Android. But if we can't restore the state,
325aab3f09b5c2d39b19067e57635614080b2403a46Grace Kloba            // we can treat it as a new Browser, remove the old session cookies.
326aab3f09b5c2d39b19067e57635614080b2403a46Grace Kloba            CookieManager.getInstance().removeSessionCookie();
3270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            final Intent intent = getIntent();
3280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            final Bundle extra = intent.getExtras();
3290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Create an initial tab.
3300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // If the intent is ACTION_VIEW and data is not null, the Browser is
3310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // invoked to view the content by another application. In this case,
3320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // the tab will be close when exit.
33325ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima            UrlData urlData = getUrlDataFromIntent(intent);
33425ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima
33558d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins            String action = intent.getAction();
33622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            final Tab t = mTabControl.createNewTab(
33758d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins                    (Intent.ACTION_VIEW.equals(action) &&
33858d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins                    intent.getData() != null)
339a1cc3fdce19a336c251297c61cd83ac6cf767cd1Leon Scroggins                    || RecognizerResultsIntent.ACTION_VOICE_SEARCH_RESULTS
340a1cc3fdce19a336c251297c61cd83ac6cf767cd1Leon Scroggins                    .equals(action),
34125ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima                    intent.getStringExtra(Browser.EXTRA_APPLICATION_ID), urlData.mUrl);
3420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mTabControl.setCurrentTab(t);
3430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            attachTabToContentView(t);
3440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            WebView webView = t.getWebView();
3450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (extra != null) {
3460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                int scale = extra.getInt(Browser.INITIAL_ZOOM_LEVEL, 0);
3470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (scale > 0 && scale <= 1000) {
3480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    webView.setInitialScale(scale);
3490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
3500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
3510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
35225ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima            if (urlData.isEmpty()) {
35398d5fce7c687cfcc956b10d44946d31f39b6dc15Shimeng (Simon) Wang                loadUrl(webView, mSettings.getHomePage());
3540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } else {
3559d53da05812f959745810a33bb4e06b273393c42Patrick Scott                loadUrlDataIn(t, urlData);
3560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
3570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
3580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // TabControl.restoreState() will create a new tab even if
3591f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins            // restoring the state fails.
3600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            attachTabToContentView(mTabControl.getCurrentTab());
3610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
362615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba
36323cbeb795fe865a5c64f275bf51217fb55363cc0Cary Clark        // Delete old thumbnails to save space
36423cbeb795fe865a5c64f275bf51217fb55363cc0Cary Clark        File dir = mTabControl.getThumbnailDir();
36523cbeb795fe865a5c64f275bf51217fb55363cc0Cary Clark        if (dir.exists()) {
36623cbeb795fe865a5c64f275bf51217fb55363cc0Cary Clark            for (String child : dir.list()) {
36723cbeb795fe865a5c64f275bf51217fb55363cc0Cary Clark                File f = new File(dir, child);
36823cbeb795fe865a5c64f275bf51217fb55363cc0Cary Clark                f.delete();
36923cbeb795fe865a5c64f275bf51217fb55363cc0Cary Clark            }
37023cbeb795fe865a5c64f275bf51217fb55363cc0Cary Clark        }
37123cbeb795fe865a5c64f275bf51217fb55363cc0Cary Clark
372b3c02da4553b1a629b16377970fdabae28394c94Feng Qian        // Read JavaScript flags if it exists.
373b3c02da4553b1a629b16377970fdabae28394c94Feng Qian        String jsFlags = mSettings.getJsFlags();
374b3c02da4553b1a629b16377970fdabae28394c94Feng Qian        if (jsFlags.trim().length() != 0) {
375b3c02da4553b1a629b16377970fdabae28394c94Feng Qian            mTabControl.getCurrentWebView().setJsFlags(jsFlags);
376b3c02da4553b1a629b16377970fdabae28394c94Feng Qian        }
37730995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu        // Work out which packages are installed on the system.
37830995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu        getInstalledPackages();
379a7611811e0d744a7220b7bf80c8f795af5ea53edBjorn Bringert
380a7611811e0d744a7220b7bf80c8f795af5ea53edBjorn Bringert        // Start watching the default geolocation permissions
381a7611811e0d744a7220b7bf80c8f795af5ea53edBjorn Bringert        mSystemAllowGeolocationOrigins
382a7611811e0d744a7220b7bf80c8f795af5ea53edBjorn Bringert                = new SystemAllowGeolocationOrigins(getApplicationContext());
383a7611811e0d744a7220b7bf80c8f795af5ea53edBjorn Bringert        mSystemAllowGeolocationOrigins.start();
3840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
3850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
38658d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    /**
38758d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins     * Feed the previously stored results strings to the BrowserProvider so that
38858d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins     * the SearchDialog will show them instead of the standard searches.
38958d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins     * @param result String to show on the editable line of the SearchDialog.
39058d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins     */
39158d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    /* package */ void showVoiceSearchResults(String result) {
39258d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        ContentProviderClient client = mResolver.acquireContentProviderClient(
39358d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins                Browser.BOOKMARKS_URI);
39458d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        ContentProvider prov = client.getLocalContentProvider();
39558d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        BrowserProvider bp = (BrowserProvider) prov;
39658d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        bp.setQueryResults(mTabControl.getCurrentTab().getVoiceSearchResults());
39758d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        client.release();
39858d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins
399fbb3f15f725e890837431f402b43e802045a4f3fLeon Scroggins        Bundle bundle = createGoogleSearchSourceBundle(
400fbb3f15f725e890837431f402b43e802045a4f3fLeon Scroggins                GOOGLE_SEARCH_SOURCE_SEARCHKEY);
401fbb3f15f725e890837431f402b43e802045a4f3fLeon Scroggins        bundle.putBoolean(SearchManager.CONTEXT_IS_VOICE, true);
402fbb3f15f725e890837431f402b43e802045a4f3fLeon Scroggins        startSearch(result, false, bundle, false);
40358d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    }
40458d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins
4050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    @Override
4060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    protected void onNewIntent(Intent intent) {
40722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        Tab current = mTabControl.getCurrentTab();
4080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // When a tab is closed on exit, the current tab index is set to -1.
4090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Reset before proceed as Browser requires the current tab to be set.
4100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (current == null) {
4110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Try to reset the tab in case the index was incorrect.
4120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            current = mTabControl.getTab(0);
4130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (current == null) {
4140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // No tabs at all so just ignore this intent.
4150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                return;
4160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
4170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mTabControl.setCurrentTab(current);
4180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            attachTabToContentView(current);
4190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            resetTitleAndIcon(current.getWebView());
4200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
4210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final String action = intent.getAction();
4220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final int flags = intent.getFlags();
4230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (Intent.ACTION_MAIN.equals(action) ||
4240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                (flags & Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY) != 0) {
4250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // just resume the browser
4260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
4270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
428b8a844da0049965b3cef5739dbab19c7ac766762Leon Scroggins        // In case the SearchDialog is open.
429b8a844da0049965b3cef5739dbab19c7ac766762Leon Scroggins        ((SearchManager) getSystemService(Context.SEARCH_SERVICE))
430b8a844da0049965b3cef5739dbab19c7ac766762Leon Scroggins                .stopSearch();
431a1cc3fdce19a336c251297c61cd83ac6cf767cd1Leon Scroggins        boolean activateVoiceSearch = RecognizerResultsIntent
432a1cc3fdce19a336c251297c61cd83ac6cf767cd1Leon Scroggins                .ACTION_VOICE_SEARCH_RESULTS.equals(action);
4330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (Intent.ACTION_VIEW.equals(action)
4340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                || Intent.ACTION_SEARCH.equals(action)
4350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                || MediaStore.INTENT_ACTION_MEDIA_SEARCH.equals(action)
43658d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins                || Intent.ACTION_WEB_SEARCH.equals(action)
43758d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins                || activateVoiceSearch) {
4383b18ce37c13fce7212948df90a012d7011924a6eLeon Scroggins            if (current.isInVoiceSearchMode()) {
4393b18ce37c13fce7212948df90a012d7011924a6eLeon Scroggins                String title = current.getVoiceDisplayTitle();
4403b18ce37c13fce7212948df90a012d7011924a6eLeon Scroggins                if (title != null && title.equals(intent.getStringExtra(
4413b18ce37c13fce7212948df90a012d7011924a6eLeon Scroggins                        SearchManager.QUERY))) {
4423b18ce37c13fce7212948df90a012d7011924a6eLeon Scroggins                    // The user submitted the same search as the last voice
4433b18ce37c13fce7212948df90a012d7011924a6eLeon Scroggins                    // search, so do nothing.
4443b18ce37c13fce7212948df90a012d7011924a6eLeon Scroggins                    return;
4453b18ce37c13fce7212948df90a012d7011924a6eLeon Scroggins                }
4461fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins                if (Intent.ACTION_SEARCH.equals(action)
4471fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins                        && current.voiceSearchSourceIsGoogle()) {
4481fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins                    Intent logIntent = new Intent(
4491fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins                            LoggingEvents.ACTION_LOG_EVENT);
4501fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins                    logIntent.putExtra(LoggingEvents.EXTRA_EVENT,
4511fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins                            LoggingEvents.VoiceSearch.QUERY_UPDATED);
4521fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins                    logIntent.putExtra(
4531fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins                            LoggingEvents.VoiceSearch.EXTRA_QUERY_UPDATED_VALUE,
4541fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins                            intent.getDataString());
4551fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins                    sendBroadcast(logIntent);
4561fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins                    // Note, onPageStarted will revert the voice title bar
4571fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins                    // When http://b/issue?id=2379215 is fixed, we should update
4581fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins                    // the title bar here.
4591fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins                }
4603b18ce37c13fce7212948df90a012d7011924a6eLeon Scroggins            }
461565505b1a2c1d3099496af5910760087602e994aSatish Sampath            // If this was a search request (e.g. search query directly typed into the address bar),
462565505b1a2c1d3099496af5910760087602e994aSatish Sampath            // pass it on to the default web search provider.
463565505b1a2c1d3099496af5910760087602e994aSatish Sampath            if (handleWebSearchIntent(intent)) {
464565505b1a2c1d3099496af5910760087602e994aSatish Sampath                return;
465565505b1a2c1d3099496af5910760087602e994aSatish Sampath            }
466565505b1a2c1d3099496af5910760087602e994aSatish Sampath
46725ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima            UrlData urlData = getUrlDataFromIntent(intent);
46825ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima            if (urlData.isEmpty()) {
46925ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima                urlData = new UrlData(mSettings.getHomePage());
4700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
47125ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima
472cc63403643786905262f505ab5266d8e80b9924cGrace Kloba            final String appId = intent
473cc63403643786905262f505ab5266d8e80b9924cGrace Kloba                    .getStringExtra(Browser.EXTRA_APPLICATION_ID);
4744720868afa09efffadd845019f2d8268ae3f2c78Leon Scroggins            if ((Intent.ACTION_VIEW.equals(action)
4754720868afa09efffadd845019f2d8268ae3f2c78Leon Scroggins                    // If a voice search has no appId, it means that it came
4764720868afa09efffadd845019f2d8268ae3f2c78Leon Scroggins                    // from the browser.  In that case, reuse the current tab.
4774720868afa09efffadd845019f2d8268ae3f2c78Leon Scroggins                    || (activateVoiceSearch && appId != null))
478cc63403643786905262f505ab5266d8e80b9924cGrace Kloba                    && !getPackageName().equals(appId)
479cc63403643786905262f505ab5266d8e80b9924cGrace Kloba                    && (flags & Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT) != 0) {
48022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                Tab appTab = mTabControl.getTabFromId(appId);
481f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                if (appTab != null) {
482f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    Log.i(LOGTAG, "Reusing tab for " + appId);
483f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    // Dismiss the subwindow if applicable.
484f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    dismissSubWindow(appTab);
485f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    // Since we might kill the WebView, remove it from the
486f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    // content view first.
487f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    removeTabFromContentView(appTab);
488f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    // Recreate the main WebView after destroying the old one.
489f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    // If the WebView has the same original url and is on that
490f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    // page, it can be reused.
491f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    boolean needsLoad =
4926eac63e78d43d04e31c4d16830c44c4d9df82639Leon Scroggins                            mTabControl.recreateWebView(appTab, urlData);
493bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch
494f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    if (current != appTab) {
4951f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                        switchToTab(mTabControl.getTabIndex(appTab));
4961f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                        if (needsLoad) {
4979d53da05812f959745810a33bb4e06b273393c42Patrick Scott                            loadUrlDataIn(appTab, urlData);
4981f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                        }
499f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    } else {
5001f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                        // If the tab was the current tab, we have to attach
5011f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                        // it to the view system again.
5021f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                        attachTabToContentView(appTab);
5031f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                        if (needsLoad) {
5049d53da05812f959745810a33bb4e06b273393c42Patrick Scott                            loadUrlDataIn(appTab, urlData);
505f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                        }
506f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    }
507f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    return;
508cd11589fc3930906d4b9b7dd18aa52a9f1eb0c8aPatrick Scott                } else {
509cd11589fc3930906d4b9b7dd18aa52a9f1eb0c8aPatrick Scott                    // No matching application tab, try to find a regular tab
510cd11589fc3930906d4b9b7dd18aa52a9f1eb0c8aPatrick Scott                    // with a matching url.
511cd11589fc3930906d4b9b7dd18aa52a9f1eb0c8aPatrick Scott                    appTab = mTabControl.findUnusedTabWithUrl(urlData.mUrl);
51225515f8bd458a2471d13d876cfb0e18d8ff2a00fLeon Scroggins                    if (appTab != null) {
51325515f8bd458a2471d13d876cfb0e18d8ff2a00fLeon Scroggins                        if (current != appTab) {
51425515f8bd458a2471d13d876cfb0e18d8ff2a00fLeon Scroggins                            switchToTab(mTabControl.getTabIndex(appTab));
51525515f8bd458a2471d13d876cfb0e18d8ff2a00fLeon Scroggins                        }
51625515f8bd458a2471d13d876cfb0e18d8ff2a00fLeon Scroggins                        // Otherwise, we are already viewing the correct tab.
517cd11589fc3930906d4b9b7dd18aa52a9f1eb0c8aPatrick Scott                    } else {
518cd11589fc3930906d4b9b7dd18aa52a9f1eb0c8aPatrick Scott                        // if FLAG_ACTIVITY_BROUGHT_TO_FRONT flag is on, the url
519cd11589fc3930906d4b9b7dd18aa52a9f1eb0c8aPatrick Scott                        // will be opened in a new tab unless we have reached
520cd11589fc3930906d4b9b7dd18aa52a9f1eb0c8aPatrick Scott                        // MAX_TABS. Then the url will be opened in the current
521cd11589fc3930906d4b9b7dd18aa52a9f1eb0c8aPatrick Scott                        // tab. If a new tab is created, it will have "true" for
522cd11589fc3930906d4b9b7dd18aa52a9f1eb0c8aPatrick Scott                        // exit on close.
5231f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                        openTabAndShow(urlData, true, appId);
524cd11589fc3930906d4b9b7dd18aa52a9f1eb0c8aPatrick Scott                    }
525f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                }
5260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } else {
527638d3f45791a31d0b290e180b93bad49576eb6d3Grace Kloba                if (!urlData.isEmpty()
528638d3f45791a31d0b290e180b93bad49576eb6d3Grace Kloba                        && urlData.mUrl.startsWith("about:debug")) {
529638d3f45791a31d0b290e180b93bad49576eb6d3Grace Kloba                    if ("about:debug.dom".equals(urlData.mUrl)) {
530638d3f45791a31d0b290e180b93bad49576eb6d3Grace Kloba                        current.getWebView().dumpDomTree(false);
531638d3f45791a31d0b290e180b93bad49576eb6d3Grace Kloba                    } else if ("about:debug.dom.file".equals(urlData.mUrl)) {
532638d3f45791a31d0b290e180b93bad49576eb6d3Grace Kloba                        current.getWebView().dumpDomTree(true);
533638d3f45791a31d0b290e180b93bad49576eb6d3Grace Kloba                    } else if ("about:debug.render".equals(urlData.mUrl)) {
534638d3f45791a31d0b290e180b93bad49576eb6d3Grace Kloba                        current.getWebView().dumpRenderTree(false);
535638d3f45791a31d0b290e180b93bad49576eb6d3Grace Kloba                    } else if ("about:debug.render.file".equals(urlData.mUrl)) {
536638d3f45791a31d0b290e180b93bad49576eb6d3Grace Kloba                        current.getWebView().dumpRenderTree(true);
537638d3f45791a31d0b290e180b93bad49576eb6d3Grace Kloba                    } else if ("about:debug.display".equals(urlData.mUrl)) {
538638d3f45791a31d0b290e180b93bad49576eb6d3Grace Kloba                        current.getWebView().dumpDisplayTree();
5399b78e1d1e0bd819ae03df5594d4a56519e5d87c7Mike Reed                    } else if (urlData.mUrl.startsWith("about:debug.drag")) {
5409b78e1d1e0bd819ae03df5594d4a56519e5d87c7Mike Reed                        int index = urlData.mUrl.codePointAt(16) - '0';
5419b78e1d1e0bd819ae03df5594d4a56519e5d87c7Mike Reed                        if (index <= 0 || index > 9) {
5429b78e1d1e0bd819ae03df5594d4a56519e5d87c7Mike Reed                            current.getWebView().setDragTracker(null);
5439b78e1d1e0bd819ae03df5594d4a56519e5d87c7Mike Reed                        } else {
5449b78e1d1e0bd819ae03df5594d4a56519e5d87c7Mike Reed                            current.getWebView().setDragTracker(new MeshTracker(index));
5459b78e1d1e0bd819ae03df5594d4a56519e5d87c7Mike Reed                        }
546638d3f45791a31d0b290e180b93bad49576eb6d3Grace Kloba                    } else {
547638d3f45791a31d0b290e180b93bad49576eb6d3Grace Kloba                        mSettings.toggleDebugSettings();
548638d3f45791a31d0b290e180b93bad49576eb6d3Grace Kloba                    }
5490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    return;
5500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
5511f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                // Get rid of the subwindow if it exists
5521f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                dismissSubWindow(current);
5538588d15a7c0b87049469fd80f9c53eb274cd837bLeon Scroggins                // If the current Tab is being used as an application tab,
5548588d15a7c0b87049469fd80f9c53eb274cd837bLeon Scroggins                // remove the association, since the new Intent means that it is
5558588d15a7c0b87049469fd80f9c53eb274cd837bLeon Scroggins                // no longer associated with that application.
5568588d15a7c0b87049469fd80f9c53eb274cd837bLeon Scroggins                current.setAppId(null);
5579d53da05812f959745810a33bb4e06b273393c42Patrick Scott                loadUrlDataIn(current, urlData);
5580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
5590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
5600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
5610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
562565505b1a2c1d3099496af5910760087602e994aSatish Sampath    private int parseUrlShortcut(String url) {
563565505b1a2c1d3099496af5910760087602e994aSatish Sampath        if (url == null) return SHORTCUT_INVALID;
564565505b1a2c1d3099496af5910760087602e994aSatish Sampath
565565505b1a2c1d3099496af5910760087602e994aSatish Sampath        // FIXME: quick search, need to be customized by setting
566565505b1a2c1d3099496af5910760087602e994aSatish Sampath        if (url.length() > 2 && url.charAt(1) == ' ') {
567565505b1a2c1d3099496af5910760087602e994aSatish Sampath            switch (url.charAt(0)) {
568565505b1a2c1d3099496af5910760087602e994aSatish Sampath            case 'g': return SHORTCUT_GOOGLE_SEARCH;
569565505b1a2c1d3099496af5910760087602e994aSatish Sampath            case 'w': return SHORTCUT_WIKIPEDIA_SEARCH;
570565505b1a2c1d3099496af5910760087602e994aSatish Sampath            case 'd': return SHORTCUT_DICTIONARY_SEARCH;
571565505b1a2c1d3099496af5910760087602e994aSatish Sampath            case 'l': return SHORTCUT_GOOGLE_MOBILE_LOCAL_SEARCH;
572565505b1a2c1d3099496af5910760087602e994aSatish Sampath            }
573565505b1a2c1d3099496af5910760087602e994aSatish Sampath        }
574565505b1a2c1d3099496af5910760087602e994aSatish Sampath        return SHORTCUT_INVALID;
575565505b1a2c1d3099496af5910760087602e994aSatish Sampath    }
576565505b1a2c1d3099496af5910760087602e994aSatish Sampath
577565505b1a2c1d3099496af5910760087602e994aSatish Sampath    /**
578565505b1a2c1d3099496af5910760087602e994aSatish Sampath     * Launches the default web search activity with the query parameters if the given intent's data
579565505b1a2c1d3099496af5910760087602e994aSatish Sampath     * are identified as plain search terms and not URLs/shortcuts.
580565505b1a2c1d3099496af5910760087602e994aSatish Sampath     * @return true if the intent was handled and web search activity was launched, false if not.
581565505b1a2c1d3099496af5910760087602e994aSatish Sampath     */
582565505b1a2c1d3099496af5910760087602e994aSatish Sampath    private boolean handleWebSearchIntent(Intent intent) {
583565505b1a2c1d3099496af5910760087602e994aSatish Sampath        if (intent == null) return false;
584565505b1a2c1d3099496af5910760087602e994aSatish Sampath
585565505b1a2c1d3099496af5910760087602e994aSatish Sampath        String url = null;
586565505b1a2c1d3099496af5910760087602e994aSatish Sampath        final String action = intent.getAction();
587a1cc3fdce19a336c251297c61cd83ac6cf767cd1Leon Scroggins        if (RecognizerResultsIntent.ACTION_VOICE_SEARCH_RESULTS.equals(
588a1cc3fdce19a336c251297c61cd83ac6cf767cd1Leon Scroggins                action)) {
58958d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins            return false;
59058d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        }
591565505b1a2c1d3099496af5910760087602e994aSatish Sampath        if (Intent.ACTION_VIEW.equals(action)) {
5921e70505659dd9bf0f7e03bce787ba880f9b7a8aaGrace Kloba            Uri data = intent.getData();
5931e70505659dd9bf0f7e03bce787ba880f9b7a8aaGrace Kloba            if (data != null) url = data.toString();
594565505b1a2c1d3099496af5910760087602e994aSatish Sampath        } else if (Intent.ACTION_SEARCH.equals(action)
595565505b1a2c1d3099496af5910760087602e994aSatish Sampath                || MediaStore.INTENT_ACTION_MEDIA_SEARCH.equals(action)
596565505b1a2c1d3099496af5910760087602e994aSatish Sampath                || Intent.ACTION_WEB_SEARCH.equals(action)) {
597565505b1a2c1d3099496af5910760087602e994aSatish Sampath            url = intent.getStringExtra(SearchManager.QUERY);
598565505b1a2c1d3099496af5910760087602e994aSatish Sampath        }
5990485170e03e079eb61b9dd52fc2c98da02fa7b2cBjorn Bringert        return handleWebSearchRequest(url, intent.getBundleExtra(SearchManager.APP_DATA),
6000485170e03e079eb61b9dd52fc2c98da02fa7b2cBjorn Bringert                intent.getStringExtra(SearchManager.EXTRA_DATA_KEY));
601565505b1a2c1d3099496af5910760087602e994aSatish Sampath    }
602565505b1a2c1d3099496af5910760087602e994aSatish Sampath
603565505b1a2c1d3099496af5910760087602e994aSatish Sampath    /**
604565505b1a2c1d3099496af5910760087602e994aSatish Sampath     * Launches the default web search activity with the query parameters if the given url string
605565505b1a2c1d3099496af5910760087602e994aSatish Sampath     * was identified as plain search terms and not URL/shortcut.
606565505b1a2c1d3099496af5910760087602e994aSatish Sampath     * @return true if the request was handled and web search activity was launched, false if not.
607565505b1a2c1d3099496af5910760087602e994aSatish Sampath     */
6080485170e03e079eb61b9dd52fc2c98da02fa7b2cBjorn Bringert    private boolean handleWebSearchRequest(String inUrl, Bundle appData, String extraData) {
609565505b1a2c1d3099496af5910760087602e994aSatish Sampath        if (inUrl == null) return false;
610565505b1a2c1d3099496af5910760087602e994aSatish Sampath
611565505b1a2c1d3099496af5910760087602e994aSatish Sampath        // In general, we shouldn't modify URL from Intent.
612565505b1a2c1d3099496af5910760087602e994aSatish Sampath        // But currently, we get the user-typed URL from search box as well.
613565505b1a2c1d3099496af5910760087602e994aSatish Sampath        String url = fixUrl(inUrl).trim();
614565505b1a2c1d3099496af5910760087602e994aSatish Sampath
615565505b1a2c1d3099496af5910760087602e994aSatish Sampath        // URLs and site specific search shortcuts are handled by the regular flow of control, so
616565505b1a2c1d3099496af5910760087602e994aSatish Sampath        // return early.
6175ee906c089567bca705e18561357510d7b55cb5aDan Egnor        if (Patterns.WEB_URL.matcher(url).matches()
618bc5b9f358a2b75bf3a104b9f5cd477ad2f6f740fSatish Sampath                || ACCEPTED_URI_SCHEMA.matcher(url).matches()
619565505b1a2c1d3099496af5910760087602e994aSatish Sampath                || parseUrlShortcut(url) != SHORTCUT_INVALID) {
620565505b1a2c1d3099496af5910760087602e994aSatish Sampath            return false;
621565505b1a2c1d3099496af5910760087602e994aSatish Sampath        }
622565505b1a2c1d3099496af5910760087602e994aSatish Sampath
6238d06e36fe80f516e04ad33ff8b446720e36cabfdLeon Scroggins        final ContentResolver cr = mResolver;
6248d06e36fe80f516e04ad33ff8b446720e36cabfdLeon Scroggins        final String newUrl = url;
6258d06e36fe80f516e04ad33ff8b446720e36cabfdLeon Scroggins        new AsyncTask<Void, Void, Void>() {
6268d06e36fe80f516e04ad33ff8b446720e36cabfdLeon Scroggins            protected Void doInBackground(Void... unused) {
6278d06e36fe80f516e04ad33ff8b446720e36cabfdLeon Scroggins                Browser.updateVisitedHistory(cr, newUrl, false);
6288d06e36fe80f516e04ad33ff8b446720e36cabfdLeon Scroggins                Browser.addSearchUrl(cr, newUrl);
6298d06e36fe80f516e04ad33ff8b446720e36cabfdLeon Scroggins                return null;
6308d06e36fe80f516e04ad33ff8b446720e36cabfdLeon Scroggins            }
6318d06e36fe80f516e04ad33ff8b446720e36cabfdLeon Scroggins        }.execute();
632565505b1a2c1d3099496af5910760087602e994aSatish Sampath
633d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert        SearchEngine searchEngine = mSettings.getSearchEngine();
634d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert        if (searchEngine == null) return false;
635d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert        searchEngine.startSearch(this, url, appData, extraData);
636565505b1a2c1d3099496af5910760087602e994aSatish Sampath
637565505b1a2c1d3099496af5910760087602e994aSatish Sampath        return true;
638565505b1a2c1d3099496af5910760087602e994aSatish Sampath    }
639565505b1a2c1d3099496af5910760087602e994aSatish Sampath
64025ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima    private UrlData getUrlDataFromIntent(Intent intent) {
64158d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        String url = "";
642068e48b469f5abca53ee3da38f933cf2c25c93b8Grace Kloba        Map<String, String> headers = null;
6430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (intent != null) {
6440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            final String action = intent.getAction();
6450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (Intent.ACTION_VIEW.equals(action)) {
6460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                url = smartUrlFilter(intent.getData());
6470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (url != null && url.startsWith("content:")) {
6480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    /* Append mimetype so webview knows how to display */
6490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    String mimeType = intent.resolveType(getContentResolver());
6500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    if (mimeType != null) {
6510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        url += "?" + mimeType;
6520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
6530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
654068e48b469f5abca53ee3da38f933cf2c25c93b8Grace Kloba                if (url != null && url.startsWith("http")) {
65500f54c589fd38431efd42ea2a551a49e64d595d5Grace Kloba                    final Bundle pairs = intent
65600f54c589fd38431efd42ea2a551a49e64d595d5Grace Kloba                            .getBundleExtra(Browser.EXTRA_HEADERS);
6572d508edbf54ea74cd4e89be8b622b1cbd587464aGrace Kloba                    if (pairs != null && !pairs.isEmpty()) {
65800f54c589fd38431efd42ea2a551a49e64d595d5Grace Kloba                        Iterator<String> iter = pairs.keySet().iterator();
659068e48b469f5abca53ee3da38f933cf2c25c93b8Grace Kloba                        headers = new HashMap<String, String>();
66000f54c589fd38431efd42ea2a551a49e64d595d5Grace Kloba                        while (iter.hasNext()) {
66100f54c589fd38431efd42ea2a551a49e64d595d5Grace Kloba                            String key = iter.next();
66200f54c589fd38431efd42ea2a551a49e64d595d5Grace Kloba                            headers.put(key, pairs.getString(key));
663068e48b469f5abca53ee3da38f933cf2c25c93b8Grace Kloba                        }
664068e48b469f5abca53ee3da38f933cf2c25c93b8Grace Kloba                    }
66525ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima                }
6660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } else if (Intent.ACTION_SEARCH.equals(action)
6670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    || MediaStore.INTENT_ACTION_MEDIA_SEARCH.equals(action)
6680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    || Intent.ACTION_WEB_SEARCH.equals(action)) {
6690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                url = intent.getStringExtra(SearchManager.QUERY);
6700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (url != null) {
6710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    mLastEnteredUrl = url;
6720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // In general, we shouldn't modify URL from Intent.
6730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // But currently, we get the user-typed URL from search box as well.
6740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    url = fixUrl(url);
6750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    url = smartUrlFilter(url);
6768d06e36fe80f516e04ad33ff8b446720e36cabfdLeon Scroggins                    final ContentResolver cr = mResolver;
6778d06e36fe80f516e04ad33ff8b446720e36cabfdLeon Scroggins                    final String newUrl = url;
6788d06e36fe80f516e04ad33ff8b446720e36cabfdLeon Scroggins                    new AsyncTask<Void, Void, Void>() {
6798d06e36fe80f516e04ad33ff8b446720e36cabfdLeon Scroggins                        protected Void doInBackground(Void... unused) {
6808d06e36fe80f516e04ad33ff8b446720e36cabfdLeon Scroggins                            Browser.updateVisitedHistory(cr, newUrl, false);
6818d06e36fe80f516e04ad33ff8b446720e36cabfdLeon Scroggins                            return null;
6828d06e36fe80f516e04ad33ff8b446720e36cabfdLeon Scroggins                        }
6838d06e36fe80f516e04ad33ff8b446720e36cabfdLeon Scroggins                    }.execute();
6840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    String searchSource = "&source=android-" + GOOGLE_SEARCH_SOURCE_SUGGEST + "&";
6850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    if (url.contains(searchSource)) {
6860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        String source = null;
6870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        final Bundle appData = intent.getBundleExtra(SearchManager.APP_DATA);
6880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        if (appData != null) {
68910d1cca0c208d1f9db23893a8515685e04cfe224Bjorn Bringert                            source = appData.getString(Search.SOURCE);
6900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }
6910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        if (TextUtils.isEmpty(source)) {
6920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            source = GOOGLE_SEARCH_SOURCE_UNKNOWN;
6930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }
6940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        url = url.replace(searchSource, "&source=android-"+source+"&");
6950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
6960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
6970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
6980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
69958d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        return new UrlData(url, headers, intent);
7000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
70158d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    /* package */ void showVoiceTitleBar(String title) {
70258d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        mTitleBar.setInVoiceMode(true);
70358d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        mFakeTitleBar.setInVoiceMode(true);
7040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
70558d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        mTitleBar.setDisplayTitle(title);
70658d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        mFakeTitleBar.setDisplayTitle(title);
70758d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    }
70858d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    /* package */ void revertVoiceTitleBar() {
70958d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        mTitleBar.setInVoiceMode(false);
71058d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        mFakeTitleBar.setInVoiceMode(false);
71158d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins
712003a5ddf3a7ff1b30bfd82cddc8da49cb9fedf15Leon Scroggins        mTitleBar.setDisplayTitle(mUrl);
713003a5ddf3a7ff1b30bfd82cddc8da49cb9fedf15Leon Scroggins        mFakeTitleBar.setDisplayTitle(mUrl);
71458d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    }
7150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /* package */ static String fixUrl(String inUrl) {
716652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark        // FIXME: Converting the url to lower case
717652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark        // duplicates functionality in smartUrlFilter().
718652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark        // However, changing all current callers of fixUrl to
719652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark        // call smartUrlFilter in addition may have unwanted
720652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark        // consequences, and is deferred for now.
721652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark        int colon = inUrl.indexOf(':');
722652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark        boolean allLower = true;
723652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark        for (int index = 0; index < colon; index++) {
724652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark            char ch = inUrl.charAt(index);
725652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark            if (!Character.isLetter(ch)) {
726652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark                break;
727652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark            }
728652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark            allLower &= Character.isLowerCase(ch);
729652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark            if (index == colon - 1 && !allLower) {
730652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark                inUrl = inUrl.substring(0, colon).toLowerCase()
731652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark                        + inUrl.substring(colon);
732652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark            }
733652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark        }
7340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (inUrl.startsWith("http://") || inUrl.startsWith("https://"))
7350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return inUrl;
7360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (inUrl.startsWith("http:") ||
7370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                inUrl.startsWith("https:")) {
7380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (inUrl.startsWith("http:/") || inUrl.startsWith("https:/")) {
7390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                inUrl = inUrl.replaceFirst("/", "//");
7400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } else inUrl = inUrl.replaceFirst(":", "://");
7410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
7420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return inUrl;
7430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
7440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
74522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    @Override
74622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    protected void onResume() {
7470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        super.onResume();
74831a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort        if (LOGV_ENABLED) {
7490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Log.v(LOGTAG, "BrowserActivity.onResume: this=" + this);
7500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
7510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
7520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (!mActivityInPause) {
7530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Log.e(LOGTAG, "BrowserActivity is already resumed.");
7540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
7550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
7560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
7577bfa63b55644fbf2da1fe6a24b3be0267529202cMike Reed        mTabControl.resumeCurrentTab();
7580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mActivityInPause = false;
7597bfa63b55644fbf2da1fe6a24b3be0267529202cMike Reed        resumeWebViewTimers();
7600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
7610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mWakeLock.isHeld()) {
7620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mHandler.removeMessages(RELEASE_WAKELOCK);
7630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mWakeLock.release();
7640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
7650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
7660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        registerReceiver(mNetworkStateIntentReceiver,
7670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                         mNetworkStateChangedFilter);
7680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebView.enablePlatformNotifications();
7690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
7700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
7713bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    /**
7723bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     * Since the actual title bar is embedded in the WebView, and removing it
773fe87bd3a3897e4bad65bb3d284659ae2f4e57570Leon Scroggins     * would change its appearance, use a different TitleBar to show overlayed
774fe87bd3a3897e4bad65bb3d284659ae2f4e57570Leon Scroggins     * at the top of the screen, when the menu is open or the page is loading.
7753bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     */
7763bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    private TitleBar mFakeTitleBar;
7773bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins
7783bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    /**
7793bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     * Keeps track of whether the options menu is open.  This is important in
7803bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     * determining whether to show or hide the title bar overlay.
7813bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     */
7823bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    private boolean mOptionsMenuOpen;
7833bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins
7843bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    /**
7853bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     * Only meaningful when mOptionsMenuOpen is true.  This variable keeps track
7863bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     * of whether the configuration has changed.  The first onMenuOpened call
7873bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     * after a configuration change is simply a reopening of the same menu
7883bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     * (i.e. mIconView did not change).
7893bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     */
7903bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    private boolean mConfigChanged;
7913bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins
7923bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    /**
7933bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     * Whether or not the options menu is in its smaller, icon menu form.  When
7943bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     * true, we want the title bar overlay to be up.  When false, we do not.
7953bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     * Only meaningful if mOptionsMenuOpen is true.
7963bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     */
7973bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    private boolean mIconView;
7983bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins
799a81a764063d2f849fba0cbc3039f86e67c2960ddLeon Scroggins    @Override
800a81a764063d2f849fba0cbc3039f86e67c2960ddLeon Scroggins    public boolean onMenuOpened(int featureId, Menu menu) {
8013bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins        if (Window.FEATURE_OPTIONS_PANEL == featureId) {
8023bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins            if (mOptionsMenuOpen) {
8033bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                if (mConfigChanged) {
8043bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                    // We do not need to make any changes to the state of the
8053bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                    // title bar, since the only thing that happened was a
8063bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                    // change in orientation
8073bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                    mConfigChanged = false;
8083bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                } else {
8093bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                    if (mIconView) {
8103bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                        // Switching the menu to expanded view, so hide the
8113bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                        // title bar.
8123bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                        hideFakeTitleBar();
8133bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                        mIconView = false;
8143bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                    } else {
8153bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                        // Switching the menu back to icon view, so show the
8163bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                        // title bar once again.
8173bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                        showFakeTitleBar();
8183bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                        mIconView = true;
8193bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                    }
8203bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                }
8213bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins            } else {
8223bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                // The options menu is closed, so open it, and show the title
8233bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                showFakeTitleBar();
8243bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                mOptionsMenuOpen = true;
8253bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                mConfigChanged = false;
8263bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                mIconView = true;
8273bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins            }
8283bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins        }
829a81a764063d2f849fba0cbc3039f86e67c2960ddLeon Scroggins        return true;
830a81a764063d2f849fba0cbc3039f86e67c2960ddLeon Scroggins    }
831a81a764063d2f849fba0cbc3039f86e67c2960ddLeon Scroggins
8323bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    private void showFakeTitleBar() {
833fe87bd3a3897e4bad65bb3d284659ae2f4e57570Leon Scroggins        if (mFakeTitleBar.getParent() == null && mActiveTabsPage == null
834847c25b877f1c912fe54ba7d3890df7ed3798e47Grace Kloba                && !mActivityInPause) {
835847c25b877f1c912fe54ba7d3890df7ed3798e47Grace Kloba            WebView mainView = mTabControl.getCurrentWebView();
836847c25b877f1c912fe54ba7d3890df7ed3798e47Grace Kloba            // if there is no current WebView, don't show the faked title bar;
83765190702c53f2d3ceb8e3c88d707bd6ff874034cGrace Kloba            if (mainView == null) {
838a04645545690d9f637ccae4d043a5a1b8478a832Cary Clark                return;
839a04645545690d9f637ccae4d043a5a1b8478a832Cary Clark            }
8402c326e62316884a20822035c5470168d0e3b89ffCary Clark            // Do not need to check for null, since the current tab will have
8412c326e62316884a20822035c5470168d0e3b89ffCary Clark            // at least a main WebView, or we would have returned above.
8422c326e62316884a20822035c5470168d0e3b89ffCary Clark            if (dialogIsUp()) {
8432c326e62316884a20822035c5470168d0e3b89ffCary Clark                // Do not show the fake title bar, which would cover up the
8442c326e62316884a20822035c5470168d0e3b89ffCary Clark                // find or select dialog.
8452c326e62316884a20822035c5470168d0e3b89ffCary Clark                return;
8462c326e62316884a20822035c5470168d0e3b89ffCary Clark            }
8473bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins
8483bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins            WindowManager manager
8493bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                    = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
8503bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins
8513bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins            // Add the title bar to the window manager so it can receive touches
8523bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins            // while the menu is up
8533bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins            WindowManager.LayoutParams params
8543bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                    = new WindowManager.LayoutParams(
85515b8ec6b226f4d57307716e1f495e10a91f8cbf4Romain Guy                    ViewGroup.LayoutParams.MATCH_PARENT,
8563bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                    ViewGroup.LayoutParams.WRAP_CONTENT,
857847c25b877f1c912fe54ba7d3890df7ed3798e47Grace Kloba                    WindowManager.LayoutParams.TYPE_APPLICATION,
8583bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                    WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
859685498685d8424f48d77d26d8d5790da34645f44Leon Scroggins                    PixelFormat.TRANSLUCENT);
8603bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins            params.gravity = Gravity.TOP;
861847c25b877f1c912fe54ba7d3890df7ed3798e47Grace Kloba            boolean atTop = mainView.getScrollY() == 0;
86283932c74ba031eb2f581f1557c1a90f4b5bbb423Leon Scroggins            params.windowAnimations = atTop ? 0 : R.style.TitleBar;
86313f9aced9c949d452a5cb44ffc55c82f97871c89Grace Kloba            manager.addView(mFakeTitleBar, params);
8643bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins        }
8653bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    }
8663bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins
8673bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    @Override
8683bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    public void onOptionsMenuClosed(Menu menu) {
8693bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins        mOptionsMenuOpen = false;
870a27ff19e24cb1c9fef5624dbc4554548349b5b31Leon Scroggins        if (!mInLoad) {
871a27ff19e24cb1c9fef5624dbc4554548349b5b31Leon Scroggins            hideFakeTitleBar();
872a27ff19e24cb1c9fef5624dbc4554548349b5b31Leon Scroggins        } else if (!mIconView) {
873a27ff19e24cb1c9fef5624dbc4554548349b5b31Leon Scroggins            // The page is currently loading, and we are in expanded mode, so
874a27ff19e24cb1c9fef5624dbc4554548349b5b31Leon Scroggins            // we were not showing the menu.  Show it once again.  It will be
875a27ff19e24cb1c9fef5624dbc4554548349b5b31Leon Scroggins            // removed when the page finishes.
876a27ff19e24cb1c9fef5624dbc4554548349b5b31Leon Scroggins            showFakeTitleBar();
877a27ff19e24cb1c9fef5624dbc4554548349b5b31Leon Scroggins        }
8783bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    }
87922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
8803bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    private void hideFakeTitleBar() {
881fe87bd3a3897e4bad65bb3d284659ae2f4e57570Leon Scroggins        if (mFakeTitleBar.getParent() == null) return;
88220329570ba9409637298da90b83f25801d7a3d55Leon Scroggins        WindowManager.LayoutParams params = (WindowManager.LayoutParams)
88313f9aced9c949d452a5cb44ffc55c82f97871c89Grace Kloba                mFakeTitleBar.getLayoutParams();
88420329570ba9409637298da90b83f25801d7a3d55Leon Scroggins        WebView mainView = mTabControl.getCurrentWebView();
88520329570ba9409637298da90b83f25801d7a3d55Leon Scroggins        // Although we decided whether or not to animate based on the current
88620329570ba9409637298da90b83f25801d7a3d55Leon Scroggins        // scroll position, the scroll position may have changed since the
88720329570ba9409637298da90b83f25801d7a3d55Leon Scroggins        // fake title bar was displayed.  Make sure it has the appropriate
88820329570ba9409637298da90b83f25801d7a3d55Leon Scroggins        // animation/lack thereof before removing.
88920329570ba9409637298da90b83f25801d7a3d55Leon Scroggins        params.windowAnimations = mainView != null && mainView.getScrollY() == 0
89083932c74ba031eb2f581f1557c1a90f4b5bbb423Leon Scroggins                ? 0 : R.style.TitleBar;
8913bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins        WindowManager manager
8923bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                    = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
89313f9aced9c949d452a5cb44ffc55c82f97871c89Grace Kloba        manager.updateViewLayout(mFakeTitleBar, params);
89413f9aced9c949d452a5cb44ffc55c82f97871c89Grace Kloba        manager.removeView(mFakeTitleBar);
8953bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    }
8963bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins
8970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
898c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins     * Special method for the fake title bar to call when displaying its context
899c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins     * menu, since it is in its own Window, and its parent does not show a
900c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins     * context menu.
901c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins     */
902c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins    /* package */ void showTitleBarContextMenu() {
90365f4a3ce9e5c4a5227bbcbb995e5e15f1f85d3d7Cary Clark        if (null == mTitleBar.getParent()) {
90465f4a3ce9e5c4a5227bbcbb995e5e15f1f85d3d7Cary Clark            return;
90565f4a3ce9e5c4a5227bbcbb995e5e15f1f85d3d7Cary Clark        }
906c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins        openContextMenu(mTitleBar);
907c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins    }
908c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins
909b2b19f501ee05448ca81bddaaca70e9b2f51cb54Leon Scroggins    @Override
910b2b19f501ee05448ca81bddaaca70e9b2f51cb54Leon Scroggins    public void onContextMenuClosed(Menu menu) {
911b2b19f501ee05448ca81bddaaca70e9b2f51cb54Leon Scroggins        super.onContextMenuClosed(menu);
912b2b19f501ee05448ca81bddaaca70e9b2f51cb54Leon Scroggins        if (mInLoad) {
913b2b19f501ee05448ca81bddaaca70e9b2f51cb54Leon Scroggins            showFakeTitleBar();
914b2b19f501ee05448ca81bddaaca70e9b2f51cb54Leon Scroggins        }
915b2b19f501ee05448ca81bddaaca70e9b2f51cb54Leon Scroggins    }
916b2b19f501ee05448ca81bddaaca70e9b2f51cb54Leon Scroggins
917c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins    /**
9180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *  onSaveInstanceState(Bundle map)
9190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *  onSaveInstanceState is called right before onStop(). The map contains
9200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *  the saved state.
9210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
92222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    @Override
92322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    protected void onSaveInstanceState(Bundle outState) {
92431a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort        if (LOGV_ENABLED) {
9250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Log.v(LOGTAG, "BrowserActivity.onSaveInstanceState: this=" + this);
9260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
9270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // the default implementation requires each view to have an id. As the
9280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // browser handles the state itself and it doesn't use id for the views,
9290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // don't call the default implementation. Otherwise it will trigger the
9300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // warning like this, "couldn't save which view has focus because the
9310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // focused view XXX has no id".
9320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
9330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Save all the tabs
9340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mTabControl.saveState(outState);
9350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
9360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
93722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    @Override
93822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    protected void onPause() {
9390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        super.onPause();
9400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
9410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mActivityInPause) {
9420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Log.e(LOGTAG, "BrowserActivity is already paused.");
9430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
9440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
9450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
9467bfa63b55644fbf2da1fe6a24b3be0267529202cMike Reed        mTabControl.pauseCurrentTab();
9470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mActivityInPause = true;
9487bfa63b55644fbf2da1fe6a24b3be0267529202cMike Reed        if (mTabControl.getCurrentIndex() >= 0 && !pauseWebViewTimers()) {
9490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mWakeLock.acquire();
9500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mHandler.sendMessageDelayed(mHandler
9510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    .obtainMessage(RELEASE_WAKELOCK), WAKELOCK_TIMEOUT);
9520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
9530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
954a2ab6a7dc0f7023c1d7ebb1cbad397c5dc3d6453Leon Scroggins        // FIXME: This removes the active tabs page and resets the menu to
955a2ab6a7dc0f7023c1d7ebb1cbad397c5dc3d6453Leon Scroggins        // MAIN_MENU.  A better solution might be to do this work in onNewIntent
956a2ab6a7dc0f7023c1d7ebb1cbad397c5dc3d6453Leon Scroggins        // but then we would need to save it in onSaveInstanceState and restore
957a2ab6a7dc0f7023c1d7ebb1cbad397c5dc3d6453Leon Scroggins        // it in onCreate/onRestoreInstanceState
958a2ab6a7dc0f7023c1d7ebb1cbad397c5dc3d6453Leon Scroggins        if (mActiveTabsPage != null) {
959a2ab6a7dc0f7023c1d7ebb1cbad397c5dc3d6453Leon Scroggins            removeActiveTabPage(true);
960a2ab6a7dc0f7023c1d7ebb1cbad397c5dc3d6453Leon Scroggins        }
961a2ab6a7dc0f7023c1d7ebb1cbad397c5dc3d6453Leon Scroggins
9620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        cancelStopToast();
9630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
9640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // unregister network state listener
9650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        unregisterReceiver(mNetworkStateIntentReceiver);
9660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebView.disablePlatformNotifications();
9670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
9680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
96922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    @Override
97022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    protected void onDestroy() {
97131a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort        if (LOGV_ENABLED) {
9720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Log.v(LOGTAG, "BrowserActivity.onDestroy: this=" + this);
9730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
9740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        super.onDestroy();
9750923d69a8ca45222cabd82a80eaa88da9f132e9aGrace Kloba
9768d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins        if (mUploadMessage != null) {
9778d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins            mUploadMessage.onReceiveValue(null);
9788d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins            mUploadMessage = null;
9798d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins        }
9808d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins
9810923d69a8ca45222cabd82a80eaa88da9f132e9aGrace Kloba        if (mTabControl == null) return;
9820923d69a8ca45222cabd82a80eaa88da9f132e9aGrace Kloba
9831fc98a322e9df6b0e797c26de6b2cb23d69ad5d3Grace Kloba        // Remove the fake title bar if it is there
9841fc98a322e9df6b0e797c26de6b2cb23d69ad5d3Grace Kloba        hideFakeTitleBar();
9851fc98a322e9df6b0e797c26de6b2cb23d69ad5d3Grace Kloba
9860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Remove the current tab and sub window
98722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        Tab t = mTabControl.getCurrentTab();
988fb5e77fac7b8b311fe72827183f8988f5ee92a5fPatrick Scott        if (t != null) {
989fb5e77fac7b8b311fe72827183f8988f5ee92a5fPatrick Scott            dismissSubWindow(t);
990fb5e77fac7b8b311fe72827183f8988f5ee92a5fPatrick Scott            removeTabFromContentView(t);
991fb5e77fac7b8b311fe72827183f8988f5ee92a5fPatrick Scott        }
9920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Destroy all the tabs
9930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mTabControl.destroy();
9940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebIconDatabase.getInstance().close();
9950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
996b4da0ad0351996f639b50f9f29b123a9b5c24fd0Grace Kloba        unregisterReceiver(mPackageInstallationReceiver);
997a7611811e0d744a7220b7bf80c8f795af5ea53edBjorn Bringert
998a7611811e0d744a7220b7bf80c8f795af5ea53edBjorn Bringert        // Stop watching the default geolocation permissions
999a7611811e0d744a7220b7bf80c8f795af5ea53edBjorn Bringert        mSystemAllowGeolocationOrigins.stop();
1000a7611811e0d744a7220b7bf80c8f795af5ea53edBjorn Bringert        mSystemAllowGeolocationOrigins = null;
10010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
10020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
10030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    @Override
10040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public void onConfigurationChanged(Configuration newConfig) {
10053bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins        mConfigChanged = true;
10060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        super.onConfigurationChanged(newConfig);
10070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
10080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mPageInfoDialog != null) {
10090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mPageInfoDialog.dismiss();
10100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            showPageInfo(
10110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mPageInfoView,
1012c7b92f811dfa3572578ddc6714c98a03936d9ce5Leon Scroggins                mPageInfoFromShowSSLCertificateOnError);
10130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
10140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mSSLCertificateDialog != null) {
10150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mSSLCertificateDialog.dismiss();
10160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            showSSLCertificate(
10170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mSSLCertificateView);
10180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
10190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mSSLCertificateOnErrorDialog != null) {
10200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mSSLCertificateOnErrorDialog.dismiss();
10210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            showSSLCertificateOnError(
10220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mSSLCertificateOnErrorView,
10230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mSSLCertificateOnErrorHandler,
10240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mSSLCertificateOnErrorError);
10250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
10260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mHttpAuthenticationDialog != null) {
10270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            String title = ((TextView) mHttpAuthenticationDialog
10280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    .findViewById(com.android.internal.R.id.alertTitle)).getText()
10290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    .toString();
10300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            String name = ((TextView) mHttpAuthenticationDialog
10310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    .findViewById(R.id.username_edit)).getText().toString();
10320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            String password = ((TextView) mHttpAuthenticationDialog
10330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    .findViewById(R.id.password_edit)).getText().toString();
10340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            int focusId = mHttpAuthenticationDialog.getCurrentFocus()
10350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    .getId();
10360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mHttpAuthenticationDialog.dismiss();
10370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            showHttpAuthentication(mHttpAuthHandler, null, null, title,
10380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    name, password, focusId);
10390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
10400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
10410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
104222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    @Override
104322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    public void onLowMemory() {
10440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        super.onLowMemory();
10450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mTabControl.freeMemory();
10460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
10470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
1048ff4d92ca529f8b77db67d0aea5d9988d5e390211Cary Clark    private void resumeWebViewTimers() {
104922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        Tab tab = mTabControl.getCurrentTab();
1050ff4d92ca529f8b77db67d0aea5d9988d5e390211Cary Clark        if (tab == null) return; // monkey can trigger this
105122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        boolean inLoad = tab.inLoad();
105222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if ((!mActivityInPause && !inLoad) || (mActivityInPause && inLoad)) {
10530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            CookieSyncManager.getInstance().startSync();
105422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            WebView w = tab.getWebView();
10550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (w != null) {
10560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                w.resumeTimers();
10570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
10580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
10590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
10600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
10617bfa63b55644fbf2da1fe6a24b3be0267529202cMike Reed    private boolean pauseWebViewTimers() {
106222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        Tab tab = mTabControl.getCurrentTab();
106322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        boolean inLoad = tab.inLoad();
106422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mActivityInPause && !inLoad) {
10650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            CookieSyncManager.getInstance().stopSync();
10660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            WebView w = mTabControl.getCurrentWebView();
10670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (w != null) {
10680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                w.pauseTimers();
10690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
10700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return true;
10710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
10720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return false;
10730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
10740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
10750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
10760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Open the icon database and retain all the icons for visited sites.
10770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void retainIconsOnStartup() {
10780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final WebIconDatabase db = WebIconDatabase.getInstance();
10790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        db.open(getDir("icons", 0).getPath());
10802c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins        Cursor c = null;
10810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        try {
10822c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins            c = Browser.getAllBookmarks(mResolver);
10832c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins            if (c.moveToFirst()) {
10842c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins                int urlIndex = c.getColumnIndex(Browser.BookmarkColumns.URL);
10852c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins                do {
10862c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins                    String url = c.getString(urlIndex);
10872c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins                    db.retainIconForPageUrl(url);
10882c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins                } while (c.moveToNext());
10890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
10900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } catch (IllegalStateException e) {
10910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Log.e(LOGTAG, "retainIconsOnStartup", e);
10922c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins        } finally {
10932c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins            if (c!= null) c.close();
10940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
10950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
10960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
10970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Helper method for getting the top window.
10980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    WebView getTopWindow() {
10990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return mTabControl.getCurrentTopWebView();
11000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
11010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
110222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    TabControl getTabControl() {
110322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return mTabControl;
110422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
110522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
11060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    @Override
11070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public boolean onCreateOptionsMenu(Menu menu) {
11080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        super.onCreateOptionsMenu(menu);
11090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
11100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        MenuInflater inflater = getMenuInflater();
11110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        inflater.inflate(R.menu.browser, menu);
11120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mMenu = menu;
11130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        updateInLoadMenuItems();
11140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return true;
11150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
11160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
11170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
11180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * As the menu can be open when loading state changes
11190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * we must manually update the state of the stop/reload menu
11200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * item
11210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
11220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void updateInLoadMenuItems() {
11230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mMenu == null) {
11240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
11250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
11260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        MenuItem src = mInLoad ?
11270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mMenu.findItem(R.id.stop_menu_id):
11280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    mMenu.findItem(R.id.reload_menu_id);
11290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        MenuItem dest = mMenu.findItem(R.id.stop_reload_menu_id);
11300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        dest.setIcon(src.getIcon());
11310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        dest.setTitle(src.getTitle());
11320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
11330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
11340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    @Override
11350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public boolean onContextItemSelected(MenuItem item) {
11360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // chording is not an issue with context menus, but we use the same
11370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // options selector, so set mCanChord to true so we can access them.
11380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mCanChord = true;
11390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        int id = item.getItemId();
114096afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins        boolean result = true;
11410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        switch (id) {
1142c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins            // For the context menu from the title bar
1143c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins            case R.id.title_bar_copy_page_url:
114496afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                Tab currentTab = mTabControl.getCurrentTab();
114596afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                if (null == currentTab) {
114696afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                    result = false;
114796afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                    break;
1148c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins                }
114996afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                WebView mainView = currentTab.getWebView();
115096afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                if (null == mainView) {
115196afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                    result = false;
115296afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                    break;
1153c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins                }
115496afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                copy(mainView.getUrl());
1155c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins                break;
11560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // -- Browser context menu
11570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.open_context_menu_id:
11580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.open_newtab_context_menu_id:
11590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.bookmark_context_menu_id:
11600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.save_link_context_menu_id:
11610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.share_link_context_menu_id:
11620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.copy_link_context_menu_id:
1163c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins                final WebView webView = getTopWindow();
1164c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins                if (null == webView) {
116596afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                    result = false;
116696afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                    break;
1167c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins                }
1168c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins                final HashMap hrefMap = new HashMap();
1169c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins                hrefMap.put("webview", webView);
1170c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins                final Message msg = mHandler.obtainMessage(
1171c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins                        FOCUS_NODE_HREF, id, 0, hrefMap);
11720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                webView.requestFocusNodeHref(msg);
11730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
11740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
11750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            default:
11760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // For other context menus
117796afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                result = onOptionsItemSelected(item);
11780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
11790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mCanChord = false;
118096afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins        return result;
11810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
11820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
11830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private Bundle createGoogleSearchSourceBundle(String source) {
11840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        Bundle bundle = new Bundle();
118510d1cca0c208d1f9db23893a8515685e04cfe224Bjorn Bringert        bundle.putString(Search.SOURCE, source);
11860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return bundle;
11870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
11880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
11898ad299270a97dfa3f9bcb956096bc152498fb727Leon Scroggins    /* package */ void editUrl() {
119068579393973f745fc65a2781061af9bb8f2d7020Leon Scroggins        if (mOptionsMenuOpen) closeOptionsMenu();
11915bbe98025a2c606a35c91b826760020890daadb1Leon Scroggins        String url = (getTopWindow() == null) ? null : getTopWindow().getUrl();
119283f473462fcd7869031a423c02b957c6e938a2f6Grace Kloba        startSearch(mSettings.getHomePage().equals(url) ? null : url, true,
11938ad299270a97dfa3f9bcb956096bc152498fb727Leon Scroggins                null, false);
11940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
11950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
11968ad299270a97dfa3f9bcb956096bc152498fb727Leon Scroggins    /**
11978ad299270a97dfa3f9bcb956096bc152498fb727Leon Scroggins     * Overriding this to insert a local information bundle
11988ad299270a97dfa3f9bcb956096bc152498fb727Leon Scroggins     */
11990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    @Override
12000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public void startSearch(String initialQuery, boolean selectInitialQuery,
12010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Bundle appSearchData, boolean globalSearch) {
12020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (appSearchData == null) {
12030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            appSearchData = createGoogleSearchSourceBundle(GOOGLE_SEARCH_SOURCE_TYPE);
12040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
1205430057dad085f3c3dbc386f127b1f5a10a9851daLeon Scroggins III
1206430057dad085f3c3dbc386f127b1f5a10a9851daLeon Scroggins III        SearchEngine searchEngine = mSettings.getSearchEngine();
1207430057dad085f3c3dbc386f127b1f5a10a9851daLeon Scroggins III        if (searchEngine != null && !searchEngine.supportsVoiceSearch()) {
1208430057dad085f3c3dbc386f127b1f5a10a9851daLeon Scroggins III            appSearchData.putBoolean(SearchManager.DISABLE_VOICE_SEARCH, true);
1209430057dad085f3c3dbc386f127b1f5a10a9851daLeon Scroggins III        }
1210430057dad085f3c3dbc386f127b1f5a10a9851daLeon Scroggins III
12110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        super.startSearch(initialQuery, selectInitialQuery, appSearchData, globalSearch);
12120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
12130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
12141f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins    /**
12151f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins     * Switch tabs.  Called by the TitleBarSet when sliding the title bar
12161f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins     * results in changing tabs.
1217160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins     * @param index Index of the tab to change to, as defined by
1218160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins     *              mTabControl.getTabIndex(Tab t).
1219160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins     * @return boolean True if we successfully switched to a different tab.  If
1220160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins     *                 the indexth tab is null, or if that tab is the same as
1221160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins     *                 the current one, return false.
12221f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins     */
1223160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins    /* package */ boolean switchToTab(int index) {
122422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        Tab tab = mTabControl.getTab(index);
122522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        Tab currentTab = mTabControl.getCurrentTab();
12261f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins        if (tab == null || tab == currentTab) {
1227160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins            return false;
12281f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins        }
12291f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins        if (currentTab != null) {
12301f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins            // currentTab may be null if it was just removed.  In that case,
12311f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins            // we do not need to remove it
12321f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins            removeTabFromContentView(currentTab);
12331f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins        }
12341f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins        mTabControl.setCurrentTab(tab);
12351f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins        attachTabToContentView(tab);
1236eb6eef4c45df2d65c3e70660493a147a2be405e3Grace Kloba        resetTitleIconAndProgress();
1237eb6eef4c45df2d65c3e70660493a147a2be405e3Grace Kloba        updateLockIconToLatest();
1238160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins        return true;
12391f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins    }
12401f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins
124122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /* package */ Tab openTabToHomePage() {
12420a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins        return openTabAndShow(mSettings.getHomePage(), false, null);
12430a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins    }
12440a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins
12451f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins    /* package */ void closeCurrentWindow() {
124622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        final Tab current = mTabControl.getCurrentTab();
1247160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins        if (mTabControl.getTabCount() == 1) {
1248304442375719effd41dbd53ae62de7a8d0cec7d9Leon Scroggins            // This is the last tab.  Open a new one, with the home
1249304442375719effd41dbd53ae62de7a8d0cec7d9Leon Scroggins            // page and close the current one.
125022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            openTabToHomePage();
1251160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins            closeTab(current);
1252160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins            return;
1253160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins        }
125422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        final Tab parent = current.getParentTab();
12551f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins        int indexToShow = -1;
12561f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins        if (parent != null) {
12571f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins            indexToShow = mTabControl.getTabIndex(parent);
12581f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins        } else {
1259160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins            final int currentIndex = mTabControl.getCurrentIndex();
1260160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins            // Try to move to the tab to the right
1261160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins            indexToShow = currentIndex + 1;
1262160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins            if (indexToShow > mTabControl.getTabCount() - 1) {
1263160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins                // Try to move to the tab to the left
1264160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins                indexToShow = currentIndex - 1;
12651f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins            }
12661f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins        }
1267160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins        if (switchToTab(indexToShow)) {
1268160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins            // Close window
1269160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins            closeTab(current);
1270160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins        }
12711f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins    }
12721f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins
12730a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins    private ActiveTabsPage mActiveTabsPage;
12740a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins
12750a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins    /**
12760a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins     * Remove the active tabs page.
12770a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins     * @param needToAttach If true, the active tabs page did not attach a tab
12780a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins     *                     to the content view, so we need to do that here.
12790a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins     */
12800a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins    /* package */ void removeActiveTabPage(boolean needToAttach) {
12810a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins        mContentView.removeView(mActiveTabsPage);
12820a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins        mActiveTabsPage = null;
12830a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins        mMenuState = R.id.MAIN_MENU;
12840a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins        if (needToAttach) {
12850a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins            attachTabToContentView(mTabControl.getCurrentTab());
12860a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins        }
12870a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins        getTopWindow().requestFocus();
12880a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins    }
12890a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins
12902c326e62316884a20822035c5470168d0e3b89ffCary Clark    private WebView showDialog(WebDialog dialog) {
12912c326e62316884a20822035c5470168d0e3b89ffCary Clark        Tab tab = mTabControl.getCurrentTab();
12922c326e62316884a20822035c5470168d0e3b89ffCary Clark        if (tab.getSubWebView() == null) {
12932c326e62316884a20822035c5470168d0e3b89ffCary Clark            // If the find or select is being performed on the main webview,
12942c326e62316884a20822035c5470168d0e3b89ffCary Clark            // remove the embedded title bar.
12952c326e62316884a20822035c5470168d0e3b89ffCary Clark            WebView mainView = tab.getWebView();
12962c326e62316884a20822035c5470168d0e3b89ffCary Clark            if (mainView != null) {
12972c326e62316884a20822035c5470168d0e3b89ffCary Clark                mainView.setEmbeddedTitleBar(null);
12982c326e62316884a20822035c5470168d0e3b89ffCary Clark            }
12992c326e62316884a20822035c5470168d0e3b89ffCary Clark        }
13002c326e62316884a20822035c5470168d0e3b89ffCary Clark        hideFakeTitleBar();
13012c326e62316884a20822035c5470168d0e3b89ffCary Clark        mMenuState = EMPTY_MENU;
13022c326e62316884a20822035c5470168d0e3b89ffCary Clark        return tab.showDialog(dialog);
13032c326e62316884a20822035c5470168d0e3b89ffCary Clark    }
13042c326e62316884a20822035c5470168d0e3b89ffCary Clark
13050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    @Override
13060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public boolean onOptionsItemSelected(MenuItem item) {
13070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (!mCanChord) {
13080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // The user has already fired a shortcut with this hold down of the
13090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // menu key.
13100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return false;
13110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
13121f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins        if (null == getTopWindow()) {
13130d7ae0ed82e21d472cde8cf92b5657d8ee8ca0d8Leon Scroggins            return false;
13140d7ae0ed82e21d472cde8cf92b5657d8ee8ca0d8Leon Scroggins        }
13156ee9c498b8cf648f1507281ed5a1834ba3390907Grace Kloba        if (mMenuIsDown) {
13166ee9c498b8cf648f1507281ed5a1834ba3390907Grace Kloba            // The shortcut action consumes the MENU. Even if it is still down,
13176ee9c498b8cf648f1507281ed5a1834ba3390907Grace Kloba            // it won't trigger the next shortcut action. In the case of the
13186ee9c498b8cf648f1507281ed5a1834ba3390907Grace Kloba            // shortcut action triggering a new activity, like Bookmarks, we
13196ee9c498b8cf648f1507281ed5a1834ba3390907Grace Kloba            // won't get onKeyUp for MENU. So it is important to reset it here.
13206ee9c498b8cf648f1507281ed5a1834ba3390907Grace Kloba            mMenuIsDown = false;
13216ee9c498b8cf648f1507281ed5a1834ba3390907Grace Kloba        }
13220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        switch (item.getItemId()) {
13230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // -- Main menu
1324a81a764063d2f849fba0cbc3039f86e67c2960ddLeon Scroggins            case R.id.new_tab_menu_id:
13250a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins                openTabToHomePage();
1326a81a764063d2f849fba0cbc3039f86e67c2960ddLeon Scroggins                break;
1327a81a764063d2f849fba0cbc3039f86e67c2960ddLeon Scroggins
132864b80f3efd95d7b5192731e995ccde79c4c6c11fLeon Scroggins            case R.id.goto_menu_id:
13298ad299270a97dfa3f9bcb956096bc152498fb727Leon Scroggins                editUrl();
1330b3a5bedeede968b53363a6c517f92bc2484bb42dLeon Scroggins                break;
1331b3a5bedeede968b53363a6c517f92bc2484bb42dLeon Scroggins
1332b3a5bedeede968b53363a6c517f92bc2484bb42dLeon Scroggins            case R.id.bookmarks_menu_id:
1333304442375719effd41dbd53ae62de7a8d0cec7d9Leon Scroggins                bookmarksOrHistoryPicker(false);
13340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
13350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
13360a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins            case R.id.active_tabs_menu_id:
13370a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins                mActiveTabsPage = new ActiveTabsPage(this, mTabControl);
13380a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins                removeTabFromContentView(mTabControl.getCurrentTab());
133943de61666cfc98a3acc41c7161a1a8b0bdb2b72bLeon Scroggins                hideFakeTitleBar();
13400a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins                mContentView.addView(mActiveTabsPage, COVER_SCREEN_PARAMS);
13410a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins                mActiveTabsPage.requestFocus();
13420a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins                mMenuState = EMPTY_MENU;
13430a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins                break;
13440a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins
13451f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins            case R.id.add_bookmark_menu_id:
13461f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                Intent i = new Intent(BrowserActivity.this,
13471f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                        AddBookmarkPage.class);
13481f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                WebView w = getTopWindow();
13491f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                i.putExtra("url", w.getUrl());
13501f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                i.putExtra("title", w.getTitle());
135183cdb2c40f2dbcbdf522a2af0ec8224c7195c6c1Grace Kloba                i.putExtra("touch_icon_url", w.getTouchIconUrl());
1352dcc2b6f08dd5677bc6ba761a9ba6f1c655113051Ben Murdoch                i.putExtra("thumbnail", createScreenshot(w));
13531f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                startActivity(i);
13540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
13550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
13560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.stop_reload_menu_id:
13570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (mInLoad) {
13580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    stopLoading();
13590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                } else {
13600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    getTopWindow().reload();
13610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
13620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
13630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
13640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.back_menu_id:
13650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                getTopWindow().goBack();
13660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
13670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
13680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.forward_menu_id:
13690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                getTopWindow().goForward();
13700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
13710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
13720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.close_menu_id:
13730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // Close the subwindow if it exists.
13740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (mTabControl.getCurrentSubWindow() != null) {
13750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    dismissSubWindow(mTabControl.getCurrentTab());
13760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    break;
13770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
13781f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                closeCurrentWindow();
13790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
13800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
13810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.homepage_menu_id:
138222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                Tab current = mTabControl.getCurrentTab();
13830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (current != null) {
13840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    dismissSubWindow(current);
138592472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins                    loadUrl(current.getWebView(), mSettings.getHomePage());
13860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
13870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
13880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
13890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.preferences_menu_id:
13900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                Intent intent = new Intent(this,
13910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        BrowserPreferencesPage.class);
1392d530494de9c182af4aff97ddd46343b32594da51Leon Scroggins                intent.putExtra(BrowserPreferencesPage.CURRENT_PAGE,
1393d530494de9c182af4aff97ddd46343b32594da51Leon Scroggins                        getTopWindow().getUrl());
13940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                startActivityForResult(intent, PREFERENCES_PAGE);
13950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
13960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
13970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.find_menu_id:
13982c326e62316884a20822035c5470168d0e3b89ffCary Clark                showFindDialog();
13990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
14000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
14010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.select_text_id:
14025feb8ad06b1000aec9403209b10b5d5210b2e241Cary Clark                if (true) {
14035feb8ad06b1000aec9403209b10b5d5210b2e241Cary Clark                    Tab currentTab = mTabControl.getCurrentTab();
14045feb8ad06b1000aec9403209b10b5d5210b2e241Cary Clark                    if (currentTab != null) {
14055feb8ad06b1000aec9403209b10b5d5210b2e241Cary Clark                        currentTab.getWebView().setUpSelect();
14065feb8ad06b1000aec9403209b10b5d5210b2e241Cary Clark                    }
14075feb8ad06b1000aec9403209b10b5d5210b2e241Cary Clark                } else {
14085feb8ad06b1000aec9403209b10b5d5210b2e241Cary Clark                    showSelectDialog();
14095feb8ad06b1000aec9403209b10b5d5210b2e241Cary Clark                }
14100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
14112c326e62316884a20822035c5470168d0e3b89ffCary Clark
14120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.page_info_menu_id:
14130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                showPageInfo(mTabControl.getCurrentTab(), false);
14140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
14150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
14160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.classic_history_menu_id:
1417304442375719effd41dbd53ae62de7a8d0cec7d9Leon Scroggins                bookmarksOrHistoryPicker(true);
14180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
14190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
142096afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins            case R.id.title_bar_share_page_url:
14210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.share_page_menu_id:
142296afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                Tab currentTab = mTabControl.getCurrentTab();
142396afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                if (null == currentTab) {
142496afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                    mCanChord = false;
142596afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                    return false;
142696afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                }
142796afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                currentTab.populatePickerData();
142896afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                sharePage(this, currentTab.getTitle(),
142996afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                        currentTab.getUrl(), currentTab.getFavicon(),
143096afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                        createScreenshot(currentTab.getWebView()));
14310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
14320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
14330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.dump_nav_menu_id:
14340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                getTopWindow().debugDump();
14350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
14360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
14377a8b88b0e0f20544df5ee34b798398603261b733Andrei Popescu            case R.id.dump_counters_menu_id:
14387a8b88b0e0f20544df5ee34b798398603261b733Andrei Popescu                getTopWindow().dumpV8Counters();
14397a8b88b0e0f20544df5ee34b798398603261b733Andrei Popescu                break;
14407a8b88b0e0f20544df5ee34b798398603261b733Andrei Popescu
14410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.zoom_in_menu_id:
14420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                getTopWindow().zoomIn();
14430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
14440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
14450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.zoom_out_menu_id:
14460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                getTopWindow().zoomOut();
14470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
14480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
14490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.view_downloads_menu_id:
14500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                viewDownloads(null);
14510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
14520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
14530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.window_one_menu_id:
14540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.window_two_menu_id:
14550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.window_three_menu_id:
14560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.window_four_menu_id:
14570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.window_five_menu_id:
14580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.window_six_menu_id:
14590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.window_seven_menu_id:
14600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.window_eight_menu_id:
14610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                {
14620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    int menuid = item.getItemId();
14630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    for (int id = 0; id < WINDOW_SHORTCUT_ID_ARRAY.length; id++) {
14640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        if (WINDOW_SHORTCUT_ID_ARRAY[id] == menuid) {
146522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            Tab desiredTab = mTabControl.getTab(id);
14660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            if (desiredTab != null &&
14670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    desiredTab != mTabControl.getCurrentTab()) {
14681f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                                switchToTab(id);
14690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            }
14700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            break;
14710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }
14720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
14730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
14740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
14750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
14760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            default:
14770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (!super.onOptionsItemSelected(item)) {
14780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    return false;
14790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
14800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // Otherwise fall through.
14810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
14820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mCanChord = false;
14830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return true;
14840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
14850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
14862c326e62316884a20822035c5470168d0e3b89ffCary Clark    private boolean dialogIsUp() {
14872c326e62316884a20822035c5470168d0e3b89ffCary Clark        return null != mFindDialog && mFindDialog.isVisible() ||
14882c326e62316884a20822035c5470168d0e3b89ffCary Clark            null != mSelectDialog && mSelectDialog.isVisible();
14892c326e62316884a20822035c5470168d0e3b89ffCary Clark    }
14902c326e62316884a20822035c5470168d0e3b89ffCary Clark
14912c326e62316884a20822035c5470168d0e3b89ffCary Clark    private boolean closeDialog(WebDialog dialog) {
14922c326e62316884a20822035c5470168d0e3b89ffCary Clark        if (null == dialog || !dialog.isVisible()) return false;
14932c326e62316884a20822035c5470168d0e3b89ffCary Clark        Tab currentTab = mTabControl.getCurrentTab();
14942c326e62316884a20822035c5470168d0e3b89ffCary Clark        currentTab.closeDialog(dialog);
14952c326e62316884a20822035c5470168d0e3b89ffCary Clark        dialog.dismiss();
14962c326e62316884a20822035c5470168d0e3b89ffCary Clark        return true;
14972c326e62316884a20822035c5470168d0e3b89ffCary Clark    }
14982c326e62316884a20822035c5470168d0e3b89ffCary Clark
14992c326e62316884a20822035c5470168d0e3b89ffCary Clark    /*
15002c326e62316884a20822035c5470168d0e3b89ffCary Clark     * Remove the find dialog or select dialog.
15012c326e62316884a20822035c5470168d0e3b89ffCary Clark     */
15022c326e62316884a20822035c5470168d0e3b89ffCary Clark    public void closeDialogs() {
15032c326e62316884a20822035c5470168d0e3b89ffCary Clark        if (!(closeDialog(mFindDialog) || closeDialog(mSelectDialog))) return;
15042c326e62316884a20822035c5470168d0e3b89ffCary Clark        // If the Find was being performed in the main WebView, replace the
15052c326e62316884a20822035c5470168d0e3b89ffCary Clark        // embedded title bar.
15062c326e62316884a20822035c5470168d0e3b89ffCary Clark        Tab currentTab = mTabControl.getCurrentTab();
15072c326e62316884a20822035c5470168d0e3b89ffCary Clark        if (currentTab.getSubWebView() == null) {
15082c326e62316884a20822035c5470168d0e3b89ffCary Clark            WebView mainView = currentTab.getWebView();
15092c326e62316884a20822035c5470168d0e3b89ffCary Clark            if (mainView != null) {
15102c326e62316884a20822035c5470168d0e3b89ffCary Clark                mainView.setEmbeddedTitleBar(mTitleBar);
15112c326e62316884a20822035c5470168d0e3b89ffCary Clark            }
15122c326e62316884a20822035c5470168d0e3b89ffCary Clark        }
15130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mMenuState = R.id.MAIN_MENU;
15142c326e62316884a20822035c5470168d0e3b89ffCary Clark        if (mInLoad) {
15152c326e62316884a20822035c5470168d0e3b89ffCary Clark            // The title bar was hidden, because otherwise it would cover up the
15162c326e62316884a20822035c5470168d0e3b89ffCary Clark            // find or select dialog.  Now that the dialog has been removed,
15172c326e62316884a20822035c5470168d0e3b89ffCary Clark            // show the fake title bar once again.
15182c326e62316884a20822035c5470168d0e3b89ffCary Clark            showFakeTitleBar();
15192c326e62316884a20822035c5470168d0e3b89ffCary Clark        }
15202c326e62316884a20822035c5470168d0e3b89ffCary Clark    }
15212c326e62316884a20822035c5470168d0e3b89ffCary Clark
15222c326e62316884a20822035c5470168d0e3b89ffCary Clark    public void showFindDialog() {
15232c326e62316884a20822035c5470168d0e3b89ffCary Clark        if (null == mFindDialog) {
15242c326e62316884a20822035c5470168d0e3b89ffCary Clark            mFindDialog = new FindDialog(this);
15252c326e62316884a20822035c5470168d0e3b89ffCary Clark        }
15262c326e62316884a20822035c5470168d0e3b89ffCary Clark        showDialog(mFindDialog).setFindIsUp(true);
15272c326e62316884a20822035c5470168d0e3b89ffCary Clark    }
15282c326e62316884a20822035c5470168d0e3b89ffCary Clark
15292c326e62316884a20822035c5470168d0e3b89ffCary Clark    public void setFindDialogText(String text) {
15302c326e62316884a20822035c5470168d0e3b89ffCary Clark        mFindDialog.setText(text);
15312c326e62316884a20822035c5470168d0e3b89ffCary Clark    }
15322c326e62316884a20822035c5470168d0e3b89ffCary Clark
15332c326e62316884a20822035c5470168d0e3b89ffCary Clark    public void showSelectDialog() {
15342c326e62316884a20822035c5470168d0e3b89ffCary Clark        if (null == mSelectDialog) {
15352c326e62316884a20822035c5470168d0e3b89ffCary Clark            mSelectDialog = new SelectDialog(this);
15362c326e62316884a20822035c5470168d0e3b89ffCary Clark        }
15372c326e62316884a20822035c5470168d0e3b89ffCary Clark        showDialog(mSelectDialog).setUpSelect();
15382c326e62316884a20822035c5470168d0e3b89ffCary Clark        mSelectDialog.hideSoftInput();
15390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
15400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
154122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    @Override
154222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    public boolean onPrepareOptionsMenu(Menu menu) {
15430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // This happens when the user begins to hold down the menu key, so
15440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // allow them to chord to get a shortcut.
15450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mCanChord = true;
15460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Note: setVisible will decide whether an item is visible; while
15470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // setEnabled() will decide whether an item is enabled, which also means
15480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // whether the matching shortcut key will function.
15490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        super.onPrepareOptionsMenu(menu);
15500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        switch (mMenuState) {
15510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case EMPTY_MENU:
15520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (mCurrentMenuState != mMenuState) {
15530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    menu.setGroupVisible(R.id.MAIN_MENU, false);
15540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    menu.setGroupEnabled(R.id.MAIN_MENU, false);
15550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    menu.setGroupEnabled(R.id.MAIN_SHORTCUT_MENU, false);
15560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
15570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
15580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            default:
15590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (mCurrentMenuState != mMenuState) {
15600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    menu.setGroupVisible(R.id.MAIN_MENU, true);
15610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    menu.setGroupEnabled(R.id.MAIN_MENU, true);
15620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    menu.setGroupEnabled(R.id.MAIN_SHORTCUT_MENU, true);
15630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
15640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                final WebView w = getTopWindow();
15650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                boolean canGoBack = false;
15660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                boolean canGoForward = false;
15670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                boolean isHome = false;
15680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (w != null) {
15690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    canGoBack = w.canGoBack();
15700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    canGoForward = w.canGoForward();
15710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    isHome = mSettings.getHomePage().equals(w.getUrl());
15720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
15730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                final MenuItem back = menu.findItem(R.id.back_menu_id);
15740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                back.setEnabled(canGoBack);
15750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
15760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                final MenuItem home = menu.findItem(R.id.homepage_menu_id);
15770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                home.setEnabled(!isHome);
15780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
15790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.forward_menu_id)
15800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        .setEnabled(canGoForward);
15810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
1582a81a764063d2f849fba0cbc3039f86e67c2960ddLeon Scroggins                menu.findItem(R.id.new_tab_menu_id).setEnabled(
158322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        mTabControl.canCreateNewTab());
1584a81a764063d2f849fba0cbc3039f86e67c2960ddLeon Scroggins
15850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // decide whether to show the share link option
15860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                PackageManager pm = getPackageManager();
15870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                Intent send = new Intent(Intent.ACTION_SEND);
15880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                send.setType("text/plain");
15890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                ResolveInfo ri = pm.resolveActivity(send, PackageManager.MATCH_DEFAULT_ONLY);
15900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.share_page_menu_id).setVisible(ri != null);
15910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
15920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                boolean isNavDump = mSettings.isNavDump();
15930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                final MenuItem nav = menu.findItem(R.id.dump_nav_menu_id);
15940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                nav.setVisible(isNavDump);
15950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                nav.setEnabled(isNavDump);
15967a8b88b0e0f20544df5ee34b798398603261b733Andrei Popescu
15977a8b88b0e0f20544df5ee34b798398603261b733Andrei Popescu                boolean showDebugSettings = mSettings.showDebugSettings();
15987a8b88b0e0f20544df5ee34b798398603261b733Andrei Popescu                final MenuItem counter = menu.findItem(R.id.dump_counters_menu_id);
15997a8b88b0e0f20544df5ee34b798398603261b733Andrei Popescu                counter.setVisible(showDebugSettings);
16007a8b88b0e0f20544df5ee34b798398603261b733Andrei Popescu                counter.setEnabled(showDebugSettings);
16017a8b88b0e0f20544df5ee34b798398603261b733Andrei Popescu
16020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
16030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
16040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mCurrentMenuState = mMenuState;
16050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return true;
16060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
16070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
16080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    @Override
16090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public void onCreateContextMenu(ContextMenu menu, View v,
16100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ContextMenuInfo menuInfo) {
16114e9f89b0a64395133b9160dcb4533d2dc62a424fLeon Scroggins        if (v instanceof TitleBar) {
16124e9f89b0a64395133b9160dcb4533d2dc62a424fLeon Scroggins            return;
16134e9f89b0a64395133b9160dcb4533d2dc62a424fLeon Scroggins        }
16140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebView webview = (WebView) v;
16150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebView.HitTestResult result = webview.getHitTestResult();
16160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (result == null) {
16170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
16180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
16190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
16200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        int type = result.getType();
16210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (type == WebView.HitTestResult.UNKNOWN_TYPE) {
16220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Log.w(LOGTAG,
16230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    "We should not show context menu when nothing is touched");
16240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
16250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
16260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (type == WebView.HitTestResult.EDIT_TEXT_TYPE) {
16270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // let TextView handles context menu
16280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
16290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
16300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
16310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Note, http://b/issue?id=1106666 is requesting that
16320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // an inflated menu can be used again. This is not available
16330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // yet, so inflate each time (yuk!)
16340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        MenuInflater inflater = getMenuInflater();
16350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        inflater.inflate(R.menu.browsercontext, menu);
16360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
16370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Show the correct menu group
16380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String extra = result.getExtra();
16390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        menu.setGroupVisible(R.id.PHONE_MENU,
16400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                type == WebView.HitTestResult.PHONE_TYPE);
16410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        menu.setGroupVisible(R.id.EMAIL_MENU,
16420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                type == WebView.HitTestResult.EMAIL_TYPE);
16430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        menu.setGroupVisible(R.id.GEO_MENU,
16440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                type == WebView.HitTestResult.GEO_TYPE);
16450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        menu.setGroupVisible(R.id.IMAGE_MENU,
16460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                type == WebView.HitTestResult.IMAGE_TYPE
16470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                || type == WebView.HitTestResult.SRC_IMAGE_ANCHOR_TYPE);
16480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        menu.setGroupVisible(R.id.ANCHOR_MENU,
16490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                type == WebView.HitTestResult.SRC_ANCHOR_TYPE
16500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                || type == WebView.HitTestResult.SRC_IMAGE_ANCHOR_TYPE);
16510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
16520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Setup custom handling depending on the type
16530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        switch (type) {
16540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case WebView.HitTestResult.PHONE_TYPE:
16550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.setHeaderTitle(Uri.decode(extra));
16560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.dial_context_menu_id).setIntent(
16570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new Intent(Intent.ACTION_VIEW, Uri
16580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                .parse(WebView.SCHEME_TEL + extra)));
16590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                Intent addIntent = new Intent(Intent.ACTION_INSERT_OR_EDIT);
16600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                addIntent.putExtra(Insert.PHONE, Uri.decode(extra));
16615e335a381a0cd66e94117b202c1f34f5cb29c9b8Cary Clark                addIntent.setType(ContactsContract.Contacts.CONTENT_ITEM_TYPE);
16620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.add_contact_context_menu_id).setIntent(
16630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        addIntent);
16640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.copy_phone_context_menu_id).setOnMenuItemClickListener(
16650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new Copy(extra));
16660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
16670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
16680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case WebView.HitTestResult.EMAIL_TYPE:
16690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.setHeaderTitle(extra);
16700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.email_context_menu_id).setIntent(
16710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new Intent(Intent.ACTION_VIEW, Uri
16720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                .parse(WebView.SCHEME_MAILTO + extra)));
16730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.copy_mail_context_menu_id).setOnMenuItemClickListener(
16740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new Copy(extra));
16750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
16760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
16770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case WebView.HitTestResult.GEO_TYPE:
16780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.setHeaderTitle(extra);
16790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.map_context_menu_id).setIntent(
16800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new Intent(Intent.ACTION_VIEW, Uri
16810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                .parse(WebView.SCHEME_GEO
16820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        + URLEncoder.encode(extra))));
16830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.copy_geo_context_menu_id).setOnMenuItemClickListener(
16840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new Copy(extra));
16850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
16860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
16870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case WebView.HitTestResult.SRC_ANCHOR_TYPE:
16880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case WebView.HitTestResult.SRC_IMAGE_ANCHOR_TYPE:
16890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                TextView titleView = (TextView) LayoutInflater.from(this)
16900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        .inflate(android.R.layout.browser_link_context_header,
16910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        null);
16920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                titleView.setText(extra);
16930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.setHeaderView(titleView);
16940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // decide whether to show the open link in new tab option
16950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.open_newtab_context_menu_id).setVisible(
169622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        mTabControl.canCreateNewTab());
1697de353621650d17a412b6ffe2cbf0366db5f11c40Ben Murdoch                menu.findItem(R.id.bookmark_context_menu_id).setVisible(
1698de353621650d17a412b6ffe2cbf0366db5f11c40Ben Murdoch                        Bookmarks.urlHasAcceptableScheme(extra));
16990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                PackageManager pm = getPackageManager();
17000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                Intent send = new Intent(Intent.ACTION_SEND);
17010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                send.setType("text/plain");
17020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                ResolveInfo ri = pm.resolveActivity(send, PackageManager.MATCH_DEFAULT_ONLY);
17030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.share_link_context_menu_id).setVisible(ri != null);
17040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (type == WebView.HitTestResult.SRC_ANCHOR_TYPE) {
17050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    break;
17060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
17070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // otherwise fall through to handle image part
17080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case WebView.HitTestResult.IMAGE_TYPE:
17090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (type == WebView.HitTestResult.IMAGE_TYPE) {
17100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    menu.setHeaderTitle(extra);
17110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
17120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.view_image_context_menu_id).setIntent(
17130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new Intent(Intent.ACTION_VIEW, Uri.parse(extra)));
17140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.download_context_menu_id).
17150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        setOnMenuItemClickListener(new Download(extra));
17164f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                menu.findItem(R.id.set_wallpaper_context_menu_id).
17174f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                        setOnMenuItemClickListener(new SetAsWallpaper(extra));
17180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
17190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
17200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            default:
17210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                Log.w(LOGTAG, "We should not get here.");
17220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
17230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
1724b2b19f501ee05448ca81bddaaca70e9b2f51cb54Leon Scroggins        hideFakeTitleBar();
17250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
17260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
17270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Attach the given tab to the content view.
1728c928c30a51eee84b40cb7045842c288c1cfafff0Grace Kloba    // this should only be called for the current tab.
172922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private void attachTabToContentView(Tab t) {
17302bc69918d97a767a02132090e58718077381ba1aSteve Block        // Attach the container that contains the main WebView and any other UI
17312bc69918d97a767a02132090e58718077381ba1aSteve Block        // associated with the tab.
1732d0119535d0c490e087be114ae8fd1639bb1945dcPatrick Scott        t.attachTabToContentView(mContentView);
1733bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch
1734bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch        if (mShouldShowErrorConsole) {
173522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            ErrorConsoleView errorConsole = t.getErrorConsole(true);
1736bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch            if (errorConsole.numberOfErrors() == 0) {
1737bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch                errorConsole.showConsole(ErrorConsoleView.SHOW_NONE);
1738bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch            } else {
1739bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch                errorConsole.showConsole(ErrorConsoleView.SHOW_MINIMIZED);
1740bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch            }
1741bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch
1742bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch            mErrorConsoleContainer.addView(errorConsole,
174315b8ec6b226f4d57307716e1f495e10a91f8cbf4Romain Guy                    new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
1744bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch                                                  ViewGroup.LayoutParams.WRAP_CONTENT));
1745bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch        }
1746bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch
174739ab28eba0c8c837ac80851ec0dd2af336aa3f85Leon Scroggins        WebView view = t.getWebView();
174855a5bc2a8f3c9a0721eeaa5a45241e00d5da95efLeon Scroggins        view.setEmbeddedTitleBar(mTitleBar);
174958d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        if (t.isInVoiceSearchMode()) {
175058d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins            showVoiceTitleBar(t.getVoiceDisplayTitle());
175158d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        } else {
175258d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins            revertVoiceTitleBar();
175358d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        }
17540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Request focus on the top window.
17550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        t.getTopWindow().requestFocus();
17560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
17570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
17580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Attach a sub window to the main WebView of the given tab.
175922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void attachSubWindow(Tab t) {
1760d0119535d0c490e087be114ae8fd1639bb1945dcPatrick Scott        t.attachSubWindow(mContentView);
1761d0119535d0c490e087be114ae8fd1639bb1945dcPatrick Scott        getTopWindow().requestFocus();
17620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
17630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
17640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Remove the given tab from the content view.
176522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private void removeTabFromContentView(Tab t) {
17662bc69918d97a767a02132090e58718077381ba1aSteve Block        // Remove the container that contains the main WebView.
1767d0119535d0c490e087be114ae8fd1639bb1945dcPatrick Scott        t.removeTabFromContentView(mContentView);
1768bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch
176922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        ErrorConsoleView errorConsole = t.getErrorConsole(false);
177022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (errorConsole != null) {
177122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mErrorConsoleContainer.removeView(errorConsole);
1772bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch        }
1773bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch
177439ab28eba0c8c837ac80851ec0dd2af336aa3f85Leon Scroggins        WebView view = t.getWebView();
1775bb85b9016201d45ea939d7cb7edd0ba6616a111cLeon Scroggins        if (view != null) {
1776bb85b9016201d45ea939d7cb7edd0ba6616a111cLeon Scroggins            view.setEmbeddedTitleBar(null);
1777bb85b9016201d45ea939d7cb7edd0ba6616a111cLeon Scroggins        }
17780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
17790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
17800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Remove the sub window if it exists. Also called by TabControl when the
17810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // user clicks the 'X' to dismiss a sub window.
178222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /* package */ void dismissSubWindow(Tab t) {
1783d0119535d0c490e087be114ae8fd1639bb1945dcPatrick Scott        t.removeSubWindow(mContentView);
178422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // dismiss the subwindow. This will destroy the WebView.
178522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        t.dismissSubWindow();
1786d0119535d0c490e087be114ae8fd1639bb1945dcPatrick Scott        getTopWindow().requestFocus();
17870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
17880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
17891f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins    // A wrapper function of {@link #openTabAndShow(UrlData, boolean, String)}
179025ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima    // that accepts url as string.
179122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private Tab openTabAndShow(String url, boolean closeOnExit, String appId) {
17921f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins        return openTabAndShow(new UrlData(url), closeOnExit, appId);
17930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
17940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
17950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // This method does a ton of stuff. It will attempt to create a new tab
17960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // if we haven't reached MAX_TABS. Otherwise it uses the current tab. If
17971f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins    // url isn't null, it will load the given url.
179822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /* package */Tab openTabAndShow(UrlData urlData, boolean closeOnExit,
179922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            String appId) {
180022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        final Tab currentTab = mTabControl.getCurrentTab();
180122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mTabControl.canCreateNewTab()) {
180222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            final Tab tab = mTabControl.createNewTab(closeOnExit, appId,
180322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    urlData.mUrl);
18041f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins            WebView webview = tab.getWebView();
18050a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins            // If the last tab was removed from the active tabs page, currentTab
18060a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins            // will be null.
18070a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins            if (currentTab != null) {
18080a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins                removeTabFromContentView(currentTab);
18090a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins            }
18108bbd69f50abd537bfe7eb314b3a3e20241ac22bdPatrick Scott            // We must set the new tab as the current tab to reflect the old
18118bbd69f50abd537bfe7eb314b3a3e20241ac22bdPatrick Scott            // animation behavior.
18128bbd69f50abd537bfe7eb314b3a3e20241ac22bdPatrick Scott            mTabControl.setCurrentTab(tab);
1813eb6eef4c45df2d65c3e70660493a147a2be405e3Grace Kloba            attachTabToContentView(tab);
1814160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins            if (!urlData.isEmpty()) {
18159d53da05812f959745810a33bb4e06b273393c42Patrick Scott                loadUrlDataIn(tab, urlData);
18160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
18171f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins            return tab;
181864b80f3efd95d7b5192731e995ccde79c4c6c11fLeon Scroggins        } else {
18191f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins            // Get rid of the subwindow if it exists
18201f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins            dismissSubWindow(currentTab);
18211f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins            if (!urlData.isEmpty()) {
18221f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                // Load the given url.
18239d53da05812f959745810a33bb4e06b273393c42Patrick Scott                loadUrlDataIn(currentTab, urlData);
18240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
182558d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins            return currentTab;
18260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
18270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
18280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
182922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private Tab openTab(String url) {
18300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mSettings.openInBackground()) {
183122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            Tab t = mTabControl.createNewTab();
18320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (t != null) {
18331f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                WebView view = t.getWebView();
183492472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins                loadUrl(view, url);
18350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
1836c9181841c7ed6b9f7dfc953eab8dc7ba1047022cGrace Kloba            return t;
18370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
18381f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins            return openTabAndShow(url, false, null);
18390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
18400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
18410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
18420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private class Copy implements OnMenuItemClickListener {
18430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        private CharSequence mText;
18440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
18450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public boolean onMenuItemClick(MenuItem item) {
18460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            copy(mText);
18470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return true;
18480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
18490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
18500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public Copy(CharSequence toCopy) {
18510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mText = toCopy;
18520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
18530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
18540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
18550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private class Download implements OnMenuItemClickListener {
18560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        private String mText;
18570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
18580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public boolean onMenuItemClick(MenuItem item) {
18590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            onDownloadStartNoStream(mText, null, null, null, -1);
18600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return true;
18610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
18620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
18630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public Download(String toDownload) {
18640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mText = toDownload;
18650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
18660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
18670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
18684f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch    private class SetAsWallpaper extends Thread implements
18694f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch            OnMenuItemClickListener, DialogInterface.OnCancelListener {
18704f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch        private URL mUrl;
18714f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch        private ProgressDialog mWallpaperProgress;
18724f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch        private boolean mCanceled = false;
18734f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch
18744f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch        public SetAsWallpaper(String url) {
18754f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch            try {
18764f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                mUrl = new URL(url);
18774f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch            } catch (MalformedURLException e) {
18784f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                mUrl = null;
18794f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch            }
18804f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch        }
18814f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch
18824f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch        public void onCancel(DialogInterface dialog) {
18834f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch            mCanceled = true;
18844f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch        }
18854f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch
18864f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch        public boolean onMenuItemClick(MenuItem item) {
18874f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch            if (mUrl != null) {
18884f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                // The user may have tried to set a image with a large file size as their
18894f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                // background so it may take a few moments to perform the operation. Display
18904f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                // a progress spinner while it is working.
18914f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                mWallpaperProgress = new ProgressDialog(BrowserActivity.this);
18924f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                mWallpaperProgress.setIndeterminate(true);
18934f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                mWallpaperProgress.setMessage(getText(R.string.progress_dialog_setting_wallpaper));
18944f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                mWallpaperProgress.setCancelable(true);
18954f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                mWallpaperProgress.setOnCancelListener(this);
18964f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                mWallpaperProgress.show();
18974f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                start();
18984f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch            }
18994f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch            return true;
19004f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch        }
19014f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch
19024f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch        public void run() {
19034f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch            Drawable oldWallpaper = BrowserActivity.this.getWallpaper();
19044f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch            try {
19054f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                // TODO: This will cause the resource to be downloaded again, when we
19064f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                // should in most cases be able to grab it from the cache. To fix this
19074f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                // we should query WebCore to see if we can access a cached version and
19084f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                // instead open an input stream on that. This pattern could also be used
19094f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                // in the download manager where the same problem exists.
19104f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                InputStream inputstream = mUrl.openStream();
19114f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                if (inputstream != null) {
19124f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                    setWallpaper(inputstream);
19134f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                }
19144f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch            } catch (IOException e) {
19154f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                Log.e(LOGTAG, "Unable to set new wallpaper");
19164f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                // Act as though the user canceled the operation so we try to
19174f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                // restore the old wallpaper.
19184f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                mCanceled = true;
19194f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch            }
19204f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch
19214f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch            if (mCanceled) {
19224f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                // Restore the old wallpaper if the user cancelled whilst we were setting
19234f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                // the new wallpaper.
19244f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                int width = oldWallpaper.getIntrinsicWidth();
19254f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                int height = oldWallpaper.getIntrinsicHeight();
19264f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                Bitmap bm = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);
19274f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                Canvas canvas = new Canvas(bm);
19284f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                oldWallpaper.setBounds(0, 0, width, height);
19294f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                oldWallpaper.draw(canvas);
19304f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                try {
19314f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                    setWallpaper(bm);
19324f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                } catch (IOException e) {
19334f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                    Log.e(LOGTAG, "Unable to restore old wallpaper.");
19344f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                }
19354f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                mCanceled = false;
19364f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch            }
19374f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch
19384f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch            if (mWallpaperProgress.isShowing()) {
19394f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                mWallpaperProgress.dismiss();
19404f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch            }
19414f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch        }
19424f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch    }
19434f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch
19440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void copy(CharSequence text) {
19450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        try {
19460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            IClipboard clip = IClipboard.Stub.asInterface(ServiceManager.getService("clipboard"));
19470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (clip != null) {
19480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                clip.setClipboardText(text);
19490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
19500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } catch (android.os.RemoteException e) {
19510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Log.e(LOGTAG, "Copy failed", e);
19520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
19530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
19540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
19550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
19560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Resets the browser title-view to whatever it must be
19570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * (for example, if we had a loading error)
19580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * When we have a new page, we call resetTitle, when we
19590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * have to reset the titlebar to whatever it used to be
19600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * (for example, if the user chose to stop loading), we
19610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * call resetTitleAndRevertLockIcon.
19620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
19630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /* package */ void resetTitleAndRevertLockIcon() {
196422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mTabControl.getCurrentTab().revertLockIcon();
196522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        updateLockIconToLatest();
19660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        resetTitleIconAndProgress();
19670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
19680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
19690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
19700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Reset the title, favicon, and progress.
19710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
19720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void resetTitleIconAndProgress() {
19730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebView current = mTabControl.getCurrentWebView();
19740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (current == null) {
19750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
19760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
19770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        resetTitleAndIcon(current);
19780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        int progress = current.getProgress();
197922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        current.getWebChromeClient().onProgressChanged(current, progress);
19800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
19810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
19820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Reset the title and the icon based on the given item.
19830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void resetTitleAndIcon(WebView view) {
19840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebHistoryItem item = view.copyBackForwardList().getCurrentItem();
19850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (item != null) {
198668579393973f745fc65a2781061af9bb8f2d7020Leon Scroggins            setUrlTitle(item.getUrl(), item.getTitle());
19870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            setFavicon(item.getFavicon());
19880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
198968579393973f745fc65a2781061af9bb8f2d7020Leon Scroggins            setUrlTitle(null, null);
19900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            setFavicon(null);
19910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
19920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
19930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
19940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
19950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Sets a title composed of the URL and the title string.
19960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param url The URL of the site being loaded.
19970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param title The title of the site being loaded.
19980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
199922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void setUrlTitle(String url, String title) {
20000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mUrl = url;
20010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mTitle = title;
20020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
200358d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        // If we are in voice search mode, the title has already been set.
200458d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        if (mTabControl.getCurrentTab().isInVoiceSearchMode()) return;
200558d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        mTitleBar.setDisplayTitle(url);
200658d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        mFakeTitleBar.setDisplayTitle(url);
20070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
20080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
20090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
20100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param url The URL to build a title version of the URL from.
20110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @return The title version of the URL or null if fails.
20120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * The title version of the URL can be either the URL hostname,
20130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * or the hostname with an "https://" prefix (for secure URLs),
20140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * or an empty string if, for example, the URL in question is a
20150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * file:// URL with no hostname.
20160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
201732e14a6deccfa75490b3032bb4ddd5ae90f89de8Leon Scroggins    /* package */ static String buildTitleUrl(String url) {
20180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String titleUrl = null;
20190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
20200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (url != null) {
20210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            try {
20220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // parse the url string
20230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                URL urlObj = new URL(url);
20240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (urlObj != null) {
20250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    titleUrl = "";
20260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
20270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    String protocol = urlObj.getProtocol();
20280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    String host = urlObj.getHost();
20290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
20300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    if (host != null && 0 < host.length()) {
20310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        titleUrl = host;
20320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        if (protocol != null) {
20330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            // if a secure site, add an "https://" prefix!
20340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            if (protocol.equalsIgnoreCase("https")) {
20350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                titleUrl = protocol + "://" + host;
20360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            }
20370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }
20380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
20390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
20400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } catch (MalformedURLException e) {}
20410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
20420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
20430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return titleUrl;
20440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
20450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
20460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Set the favicon in the title bar.
204722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void setFavicon(Bitmap icon) {
204868579393973f745fc65a2781061af9bb8f2d7020Leon Scroggins        mTitleBar.setFavicon(icon);
2049fe87bd3a3897e4bad65bb3d284659ae2f4e57570Leon Scroggins        mFakeTitleBar.setFavicon(icon);
20500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
20510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
20520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
20530a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins     * Close the tab, remove its associated title bar, and adjust mTabControl's
20540a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins     * current tab to a valid value.
20551f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins     */
205622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /* package */ void closeTab(Tab t) {
20570a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins        int currentIndex = mTabControl.getCurrentIndex();
20580a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins        int removeIndex = mTabControl.getTabIndex(t);
20591f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins        mTabControl.removeTab(t);
20600a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins        if (currentIndex >= removeIndex && currentIndex != 0) {
20610a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins            currentIndex--;
20620a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins        }
20630a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins        mTabControl.setCurrentTab(mTabControl.getTab(currentIndex));
2064a5bf1deca120315a2643ea5b010f94d853461b15Andrei Popescu        resetTitleIconAndProgress();
20650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
20660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
2067dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins    /* package */ void goBackOnePageOrQuit() {
206822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        Tab current = mTabControl.getCurrentTab();
20690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (current == null) {
20700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            /*
20710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project             * Instead of finishing the activity, simply push this to the back
20720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project             * of the stack and let ActivityManager to choose the foreground
20730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project             * activity. As BrowserActivity is singleTask, it will be always the
20740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project             * root of the task. So we can use either true or false for
20750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project             * moveTaskToBack().
20760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project             */
20770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            moveTaskToBack(true);
207800d85e74921459b34e70eb93368245b4c0a9bf5fGrace Kloba            return;
20790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
20800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebView w = current.getWebView();
20810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (w.canGoBack()) {
20820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            w.goBack();
20830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
20840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Check to see if we are closing a window that was created by
20850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // another window. If so, we switch back to that window.
208622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            Tab parent = current.getParentTab();
20870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (parent != null) {
20881f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                switchToTab(mTabControl.getTabIndex(parent));
20891f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                // Now we close the other tab
20901f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                closeTab(current);
20910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } else {
20920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (current.closeOnExit()) {
209322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    // force the tab's inLoad() to be false as we are going to
209422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    // either finish the activity or remove the tab. This will
209522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    // ensure pauseWebViewTimers() taking action.
209622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    mTabControl.getCurrentTab().clearInLoad();
20970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    if (mTabControl.getTabCount() == 1) {
20980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        finish();
20990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        return;
21000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
21017bfa63b55644fbf2da1fe6a24b3be0267529202cMike Reed                    // call pauseWebViewTimers() now, we won't be able to call
21027bfa63b55644fbf2da1fe6a24b3be0267529202cMike Reed                    // it in onPause() as the WebView won't be valid.
2103ec1b5ad8d8283b1fbbc5d7fa1cd50ef95b9e594dGrace Kloba                    // Temporarily change mActivityInPause to be true as
2104ec1b5ad8d8283b1fbbc5d7fa1cd50ef95b9e594dGrace Kloba                    // pauseWebViewTimers() will do nothing if mActivityInPause
2105ec1b5ad8d8283b1fbbc5d7fa1cd50ef95b9e594dGrace Kloba                    // is false.
2106918e1d78b2db6ef21c71a07868572d9cda498476Grace Kloba                    boolean savedState = mActivityInPause;
2107918e1d78b2db6ef21c71a07868572d9cda498476Grace Kloba                    if (savedState) {
2108ec1b5ad8d8283b1fbbc5d7fa1cd50ef95b9e594dGrace Kloba                        Log.e(LOGTAG, "BrowserActivity is already paused "
2109ec1b5ad8d8283b1fbbc5d7fa1cd50ef95b9e594dGrace Kloba                                + "while handing goBackOnePageOrQuit.");
2110918e1d78b2db6ef21c71a07868572d9cda498476Grace Kloba                    }
2111918e1d78b2db6ef21c71a07868572d9cda498476Grace Kloba                    mActivityInPause = true;
21127bfa63b55644fbf2da1fe6a24b3be0267529202cMike Reed                    pauseWebViewTimers();
2113918e1d78b2db6ef21c71a07868572d9cda498476Grace Kloba                    mActivityInPause = savedState;
21140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    removeTabFromContentView(current);
21150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    mTabControl.removeTab(current);
21160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
21170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                /*
21180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                 * Instead of finishing the activity, simply push this to the back
21190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                 * of the stack and let ActivityManager to choose the foreground
21200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                 * activity. As BrowserActivity is singleTask, it will be always the
21210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                 * root of the task. So we can use either true or false for
21220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                 * moveTaskToBack().
21230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                 */
21240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                moveTaskToBack(true);
21250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
21260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
21270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
21280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
212922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    boolean isMenuDown() {
213022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return mMenuIsDown;
213122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
213222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
21335942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba    @Override
21345942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba    public boolean onKeyDown(int keyCode, KeyEvent event) {
2135f65b50ddd2f7ed1205002d74082fff1ac2336d5cLeon Scroggins        // Even if MENU is already held down, we need to call to super to open
2136f65b50ddd2f7ed1205002d74082fff1ac2336d5cLeon Scroggins        // the IME on long press.
2137f65b50ddd2f7ed1205002d74082fff1ac2336d5cLeon Scroggins        if (KeyEvent.KEYCODE_MENU == keyCode) {
2138f65b50ddd2f7ed1205002d74082fff1ac2336d5cLeon Scroggins            mMenuIsDown = true;
2139f65b50ddd2f7ed1205002d74082fff1ac2336d5cLeon Scroggins            return super.onKeyDown(keyCode, event);
2140f65b50ddd2f7ed1205002d74082fff1ac2336d5cLeon Scroggins        }
21415942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba        // The default key mode is DEFAULT_KEYS_SEARCH_LOCAL. As the MENU is
21425942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba        // still down, we don't want to trigger the search. Pretend to consume
21435942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba        // the key and do nothing.
21445942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba        if (mMenuIsDown) return true;
21455942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba
21465942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba        switch(keyCode) {
21475942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba            case KeyEvent.KEYCODE_SPACE:
2148da0fe556a00773ce2af25eb6dcc5442bd08c7addGrace Kloba                // WebView/WebTextView handle the keys in the KeyDown. As
2149da0fe556a00773ce2af25eb6dcc5442bd08c7addGrace Kloba                // the Activity's shortcut keys are only handled when WebView
2150da0fe556a00773ce2af25eb6dcc5442bd08c7addGrace Kloba                // doesn't, have to do it in onKeyDown instead of onKeyUp.
2151da0fe556a00773ce2af25eb6dcc5442bd08c7addGrace Kloba                if (event.isShiftPressed()) {
2152da0fe556a00773ce2af25eb6dcc5442bd08c7addGrace Kloba                    getTopWindow().pageUp(false);
2153da0fe556a00773ce2af25eb6dcc5442bd08c7addGrace Kloba                } else {
2154da0fe556a00773ce2af25eb6dcc5442bd08c7addGrace Kloba                    getTopWindow().pageDown(false);
2155da0fe556a00773ce2af25eb6dcc5442bd08c7addGrace Kloba                }
21565942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                return true;
21575942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba            case KeyEvent.KEYCODE_BACK:
21585942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                if (event.getRepeatCount() == 0) {
21595942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                    event.startTracking();
21605942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                    return true;
21615942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                } else if (mCustomView == null && mActiveTabsPage == null
21625942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                        && event.isLongPress()) {
21635942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                    bookmarksOrHistoryPicker(true);
21645942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                    return true;
21650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
21665942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                break;
21670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
21685942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba        return super.onKeyDown(keyCode, event);
21690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
21700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
21715942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba    @Override
21725942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba    public boolean onKeyUp(int keyCode, KeyEvent event) {
21735942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba        switch(keyCode) {
21745942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba            case KeyEvent.KEYCODE_MENU:
21755942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                mMenuIsDown = false;
21765942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                break;
21775942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba            case KeyEvent.KEYCODE_BACK:
21785942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                if (event.isTracking() && !event.isCanceled()) {
21795942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                    if (mCustomView != null) {
21805942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                        // if a custom view is showing, hide it
218122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        mTabControl.getCurrentWebView().getWebChromeClient()
218222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                .onHideCustomView();
21835942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                    } else if (mActiveTabsPage != null) {
21845942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                        // if tab page is showing, hide it
21855942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                        removeActiveTabPage(true);
21860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    } else {
21875942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                        WebView subwindow = mTabControl.getCurrentSubWindow();
21885942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                        if (subwindow != null) {
21895942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                            if (subwindow.canGoBack()) {
21905942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                                subwindow.goBack();
21915942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                            } else {
21925942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                                dismissSubWindow(mTabControl.getCurrentTab());
21935942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                            }
21945942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                        } else {
21955942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                            goBackOnePageOrQuit();
21965942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                        }
21970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
21985942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                    return true;
21995942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                }
22005942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                break;
22010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
22025942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba        return super.onKeyUp(keyCode, event);
22030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
22040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
220568579393973f745fc65a2781061af9bb8f2d7020Leon Scroggins    /* package */ void stopLoading() {
2206b7cc8b439dc595dc48e1c2183b35d23ad72dfbe5Ben Murdoch        mDidStopLoad = true;
22070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        resetTitleAndRevertLockIcon();
22080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebView w = getTopWindow();
22090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        w.stopLoading();
221022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // FIXME: before refactor, it is using mWebViewClient. So I keep the
221122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // same logic here. But for subwindow case, should we call into the main
221222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // WebView's onPageFinished as we never call its onPageStarted and if
221322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // the page finishes itself, we don't call onPageFinished.
221422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mTabControl.getCurrentWebView().getWebViewClient().onPageFinished(w,
221522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                w.getUrl());
22160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
22170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        cancelStopToast();
22180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mStopToast = Toast
22190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .makeText(this, R.string.stopping, Toast.LENGTH_SHORT);
22200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mStopToast.show();
22210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
22220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
222322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    boolean didUserStopLoading() {
222422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return mDidStopLoad;
222522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
222622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
22270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void cancelStopToast() {
22280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mStopToast != null) {
22290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mStopToast.cancel();
22300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mStopToast = null;
22310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
22320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
22330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
223422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // called by a UI or non-UI thread to post the message
223522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    public void postMessage(int what, int arg1, int arg2, Object obj,
223622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            long delayMillis) {
223722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mHandler.sendMessageDelayed(mHandler.obtainMessage(what, arg1, arg2,
223822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                obj), delayMillis);
223922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
224022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
224122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // called by a UI or non-UI thread to remove the message
224222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void removeMessages(int what, Object object) {
224322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mHandler.removeMessages(what, object);
22440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
22450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
22460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // public message ids
22470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public final static int LOAD_URL                = 1001;
22480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public final static int STOP_LOAD               = 1002;
22490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
22500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Message Ids
22510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private static final int FOCUS_NODE_HREF         = 102;
225292c18a52ca7a79c114028b5ba22c3dfe443bd1a4Grace Kloba    private static final int RELEASE_WAKELOCK        = 107;
22530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
225422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    static final int UPDATE_BOOKMARK_THUMBNAIL       = 108;
22552694e23a55d5ca526fc29534a80a200e2c58698bBen Murdoch
22560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Private handler for handling javascript and saving passwords
22570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private Handler mHandler = new Handler() {
22580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
22590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public void handleMessage(Message msg) {
22600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            switch (msg.what) {
22610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                case FOCUS_NODE_HREF:
22622694e23a55d5ca526fc29534a80a200e2c58698bBen Murdoch                {
22630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    String url = (String) msg.getData().get("url");
226490d088caeee718f89755ee9c25249ba6da15ab97Ben Murdoch                    String title = (String) msg.getData().get("title");
22650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    if (url == null || url.length() == 0) {
22660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        break;
22670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
22680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    HashMap focusNodeMap = (HashMap) msg.obj;
22690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    WebView view = (WebView) focusNodeMap.get("webview");
22700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // Only apply the action if the top window did not change.
22710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    if (getTopWindow() != view) {
22720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        break;
22730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
22740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    switch (msg.arg1) {
22750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        case R.id.open_context_menu_id:
22760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        case R.id.view_image_context_menu_id:
227792472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins                            loadUrlFromContext(getTopWindow(), url);
22780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            break;
22790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        case R.id.open_newtab_context_menu_id:
228022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            final Tab parent = mTabControl.getCurrentTab();
228122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            final Tab newTab = openTab(url);
2282c9181841c7ed6b9f7dfc953eab8dc7ba1047022cGrace Kloba                            if (newTab != parent) {
2283c9181841c7ed6b9f7dfc953eab8dc7ba1047022cGrace Kloba                                parent.addChildTab(newTab);
2284c9181841c7ed6b9f7dfc953eab8dc7ba1047022cGrace Kloba                            }
22850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            break;
22860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        case R.id.bookmark_context_menu_id:
22870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            Intent intent = new Intent(BrowserActivity.this,
22880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    AddBookmarkPage.class);
22890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            intent.putExtra("url", url);
229090d088caeee718f89755ee9c25249ba6da15ab97Ben Murdoch                            intent.putExtra("title", title);
22910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            startActivity(intent);
22920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            break;
22930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        case R.id.share_link_context_menu_id:
229496afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                            // See if this site has been visited before
229596afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                            StringBuilder sb = new StringBuilder(
229696afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                                    Browser.BookmarkColumns.URL + " = ");
229796afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                            DatabaseUtils.appendEscapedSQLString(sb, url);
229896afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                            Cursor c = mResolver.query(Browser.BOOKMARKS_URI,
229996afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                                    Browser.HISTORY_PROJECTION,
230096afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                                    sb.toString(),
230196afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                                    null,
230296afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                                    null);
230396afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                            if (c.moveToFirst()) {
230496afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                                // The site has been visited before, so grab the
230596afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                                // info from the database.
230696afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                                Bitmap favicon = null;
230796afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                                Bitmap thumbnail = null;
230896afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                                String linkTitle = c.getString(Browser.
230996afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                                        HISTORY_PROJECTION_TITLE_INDEX);
231096afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                                byte[] data = c.getBlob(Browser.
231196afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                                        HISTORY_PROJECTION_FAVICON_INDEX);
231296afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                                if (data != null) {
231396afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                                    favicon = BitmapFactory.decodeByteArray(
231496afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                                            data, 0, data.length);
231596afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                                }
231696afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                                data = c.getBlob(Browser.
231796afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                                        HISTORY_PROJECTION_THUMBNAIL_INDEX);
231896afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                                if (data != null) {
231996afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                                    thumbnail = BitmapFactory.decodeByteArray(
232096afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                                            data, 0, data.length);
232196afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                                }
232296afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                                sharePage(BrowserActivity.this,
232396afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                                        linkTitle, url, favicon, thumbnail);
232496afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                            } else {
232596afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                                Browser.sendString(BrowserActivity.this, url,
232696afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                                        getString(
232796afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                                        R.string.choosertitle_sharevia));
232896afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                            }
23290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            break;
23300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        case R.id.copy_link_context_menu_id:
23310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            copy(url);
23320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            break;
23330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        case R.id.save_link_context_menu_id:
23340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        case R.id.download_context_menu_id:
23350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            onDownloadStartNoStream(url, null, null, null, -1);
23360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            break;
23370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
23380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    break;
23392694e23a55d5ca526fc29534a80a200e2c58698bBen Murdoch                }
23400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
23410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                case LOAD_URL:
234292472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins                    loadUrlFromContext(getTopWindow(), (String) msg.obj);
23430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    break;
23440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
23450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                case STOP_LOAD:
23460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    stopLoading();
23470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    break;
23480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
23490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                case RELEASE_WAKELOCK:
23500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    if (mWakeLock.isHeld()) {
23510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        mWakeLock.release();
23525d0e02e646e46b14289168f75c2a8f6ed43cac54Grace Kloba                        // if we reach here, Browser should be still in the
23535d0e02e646e46b14289168f75c2a8f6ed43cac54Grace Kloba                        // background loading after WAKELOCK_TIMEOUT (5-min).
23545d0e02e646e46b14289168f75c2a8f6ed43cac54Grace Kloba                        // To avoid burning the battery, stop loading.
23555d0e02e646e46b14289168f75c2a8f6ed43cac54Grace Kloba                        mTabControl.stopAllLoading();
23560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
23570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    break;
23582694e23a55d5ca526fc29534a80a200e2c58698bBen Murdoch
23592694e23a55d5ca526fc29534a80a200e2c58698bBen Murdoch                case UPDATE_BOOKMARK_THUMBNAIL:
23602694e23a55d5ca526fc29534a80a200e2c58698bBen Murdoch                    WebView view = (WebView) msg.obj;
23612694e23a55d5ca526fc29534a80a200e2c58698bBen Murdoch                    if (view != null) {
23622694e23a55d5ca526fc29534a80a200e2c58698bBen Murdoch                        updateScreenshot(view);
23632694e23a55d5ca526fc29534a80a200e2c58698bBen Murdoch                    }
23642694e23a55d5ca526fc29534a80a200e2c58698bBen Murdoch                    break;
23650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
23660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
23670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    };
23680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
236996afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins    /**
237096afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins     * Share a page, providing the title, url, favicon, and a screenshot.  Uses
237196afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins     * an {@link Intent} to launch the Activity chooser.
237296afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins     * @param c Context used to launch a new Activity.
237396afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins     * @param title Title of the page.  Stored in the Intent with
237403e6d39560d7de359782485d4c863d600b34fb51Paul Westbrook     *          {@link Intent#EXTRA_SUBJECT}
237596afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins     * @param url URL of the page.  Stored in the Intent with
237696afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins     *          {@link Intent#EXTRA_TEXT}
237796afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins     * @param favicon Bitmap of the favicon for the page.  Stored in the Intent
237896afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins     *          with {@link Browser#EXTRA_SHARE_FAVICON}
237996afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins     * @param screenshot Bitmap of a screenshot of the page.  Stored in the
238096afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins     *          Intent with {@link Browser#EXTRA_SHARE_SCREENSHOT}
238196afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins     */
238296afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins    public static final void sharePage(Context c, String title, String url,
238396afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins            Bitmap favicon, Bitmap screenshot) {
238496afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins        Intent send = new Intent(Intent.ACTION_SEND);
238596afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins        send.setType("text/plain");
238696afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins        send.putExtra(Intent.EXTRA_TEXT, url);
238703e6d39560d7de359782485d4c863d600b34fb51Paul Westbrook        send.putExtra(Intent.EXTRA_SUBJECT, title);
238896afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins        send.putExtra(Browser.EXTRA_SHARE_FAVICON, favicon);
238996afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins        send.putExtra(Browser.EXTRA_SHARE_SCREENSHOT, screenshot);
239096afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins        try {
239196afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins            c.startActivity(Intent.createChooser(send, c.getString(
239296afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                    R.string.choosertitle_sharevia)));
239396afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins        } catch(android.content.ActivityNotFoundException ex) {
239496afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins            // if no app handles it, do nothing
239596afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins        }
239696afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins    }
239796afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins
239889c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins    private void updateScreenshot(WebView view) {
239989c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins        // If this is a bookmarked site, add a screenshot to the database.
240089c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins        // FIXME: When should we update?  Every time?
240189c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins        // FIXME: Would like to make sure there is actually something to
240289c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins        // draw, but the API for that (WebViewCore.pictureReady()) is not
240389c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins        // currently accessible here.
2404aac7aa6fcfcb519755987ec126be066323f589c8Ben Murdoch
2405cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott        final Bitmap bm = createScreenshot(view);
2406cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott        if (bm == null) {
2407cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott            return;
2408cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott        }
2409cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott
2410cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott        final ContentResolver cr = getContentResolver();
2411cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott        final String url = view.getUrl();
2412cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott        final String originalUrl = view.getOriginalUrl();
2413cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott
2414cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott        new AsyncTask<Void, Void, Void>() {
2415cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott            @Override
2416cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott            protected Void doInBackground(Void... unused) {
2417cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott                Cursor c = null;
2418cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott                try {
2419cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott                    c = BrowserBookmarksAdapter.queryBookmarksForUrl(
2420cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott                            cr, originalUrl, url, true);
2421cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott                    if (c != null) {
2422cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott                        if (c.moveToFirst()) {
2423cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott                            ContentValues values = new ContentValues();
2424cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott                            final ByteArrayOutputStream os
2425cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott                                    = new ByteArrayOutputStream();
2426cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott                            bm.compress(Bitmap.CompressFormat.PNG, 100, os);
2427cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott                            values.put(Browser.BookmarkColumns.THUMBNAIL,
2428cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott                                    os.toByteArray());
2429cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott                            do {
2430cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott                                cr.update(ContentUris.withAppendedId(
2431cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott                                        Browser.BOOKMARKS_URI, c.getInt(0)),
2432cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott                                        values, null, null);
2433cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott                            } while (c.moveToNext());
2434cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott                        }
24354580057e772b60433272af5cd691825748892693Leon Scroggins                    }
2436cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott                } catch (IllegalStateException e) {
2437cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott                    // Ignore
2438cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott                } finally {
2439cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott                    if (c != null) c.close();
244089c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins                }
2441cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott                return null;
244289c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins            }
2443cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott        }.execute();
244489c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins    }
244589c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins
244606ec5f2d8735d1ba17b779deb0f8da032e0a62eaLeon Scroggins    /**
2447f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins     * Values for the size of the thumbnail created when taking a screenshot.
2448f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins     * Lazily initialized.  Instead of using these directly, use
2449f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins     * getDesiredThumbnailWidth() or getDesiredThumbnailHeight().
245006ec5f2d8735d1ba17b779deb0f8da032e0a62eaLeon Scroggins     */
2451f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins    private static int THUMBNAIL_WIDTH = 0;
2452f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins    private static int THUMBNAIL_HEIGHT = 0;
2453f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins
2454f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins    /**
2455f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins     * Return the desired width for thumbnail screenshots, which are stored in
2456f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins     * the database, and used on the bookmarks screen.
2457f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins     * @param context Context for finding out the density of the screen.
2458f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins     * @return int desired width for thumbnail screenshot.
2459f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins     */
2460f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins    /* package */ static int getDesiredThumbnailWidth(Context context) {
2461f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins        if (THUMBNAIL_WIDTH == 0) {
2462f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins            float density = context.getResources().getDisplayMetrics().density;
2463f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins            THUMBNAIL_WIDTH = (int) (90 * density);
2464f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins            THUMBNAIL_HEIGHT = (int) (80 * density);
2465f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins        }
2466f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins        return THUMBNAIL_WIDTH;
2467f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins    }
2468f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins
2469f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins    /**
2470f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins     * Return the desired height for thumbnail screenshots, which are stored in
2471f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins     * the database, and used on the bookmarks screen.
2472f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins     * @param context Context for finding out the density of the screen.
2473f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins     * @return int desired height for thumbnail screenshot.
2474f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins     */
2475f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins    /* package */ static int getDesiredThumbnailHeight(Context context) {
2476f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins        // To ensure that they are both initialized.
2477f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins        getDesiredThumbnailWidth(context);
2478f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins        return THUMBNAIL_HEIGHT;
2479f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins    }
248006ec5f2d8735d1ba17b779deb0f8da032e0a62eaLeon Scroggins
2481dcc2b6f08dd5677bc6ba761a9ba6f1c655113051Ben Murdoch    private Bitmap createScreenshot(WebView view) {
2482dcc2b6f08dd5677bc6ba761a9ba6f1c655113051Ben Murdoch        Picture thumbnail = view.capturePicture();
24834580057e772b60433272af5cd691825748892693Leon Scroggins        if (thumbnail == null) {
24844580057e772b60433272af5cd691825748892693Leon Scroggins            return null;
24854580057e772b60433272af5cd691825748892693Leon Scroggins        }
2486f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins        Bitmap bm = Bitmap.createBitmap(getDesiredThumbnailWidth(this),
2487ab168ba86162b4e89e74d0a077b9c618437cbce4Cary Clark                getDesiredThumbnailHeight(this), Bitmap.Config.RGB_565);
2488dcc2b6f08dd5677bc6ba761a9ba6f1c655113051Ben Murdoch        Canvas canvas = new Canvas(bm);
2489dcc2b6f08dd5677bc6ba761a9ba6f1c655113051Ben Murdoch        // May need to tweak these values to determine what is the
2490dcc2b6f08dd5677bc6ba761a9ba6f1c655113051Ben Murdoch        // best scale factor
24912694e23a55d5ca526fc29534a80a200e2c58698bBen Murdoch        int thumbnailWidth = thumbnail.getWidth();
2492ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch        int thumbnailHeight = thumbnail.getHeight();
2493ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch        float scaleFactorX = 1.0f;
2494ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch        float scaleFactorY = 1.0f;
24952694e23a55d5ca526fc29534a80a200e2c58698bBen Murdoch        if (thumbnailWidth > 0) {
2496ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch            scaleFactorX = (float) getDesiredThumbnailWidth(this) /
24972694e23a55d5ca526fc29534a80a200e2c58698bBen Murdoch                    (float)thumbnailWidth;
2498ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch        } else {
2499ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch            return null;
250006ec5f2d8735d1ba17b779deb0f8da032e0a62eaLeon Scroggins        }
2501ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch
2502ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch        if (view.getWidth() > view.getHeight() &&
2503ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch                thumbnailHeight < view.getHeight() && thumbnailHeight > 0) {
2504ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch            // If the device is in landscape and the page is shorter
2505ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch            // than the height of the view, stretch the thumbnail to fill the
2506ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch            // space.
2507ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch            scaleFactorY = (float) getDesiredThumbnailHeight(this) /
2508ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch                    (float)thumbnailHeight;
2509ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch        } else {
2510ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch            // In the portrait case, this looks nice.
2511ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch            scaleFactorY = scaleFactorX;
2512ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch        }
2513ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch
2514ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch        canvas.scale(scaleFactorX, scaleFactorY);
2515ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch
2516dcc2b6f08dd5677bc6ba761a9ba6f1c655113051Ben Murdoch        thumbnail.draw(canvas);
2517dcc2b6f08dd5677bc6ba761a9ba6f1c655113051Ben Murdoch        return bm;
2518dcc2b6f08dd5677bc6ba761a9ba6f1c655113051Ben Murdoch    }
2519dcc2b6f08dd5677bc6ba761a9ba6f1c655113051Ben Murdoch
25200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // -------------------------------------------------------------------------
252122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // Helper function for WebViewClient.
25220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    //-------------------------------------------------------------------------
25230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
25240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Use in overrideUrlLoading
25250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /* package */ final static String SCHEME_WTAI = "wtai://wp/";
25260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /* package */ final static String SCHEME_WTAI_MC = "wtai://wp/mc;";
25270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /* package */ final static String SCHEME_WTAI_SD = "wtai://wp/sd;";
25280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /* package */ final static String SCHEME_WTAI_AP = "wtai://wp/ap;";
25290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
253092472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins    // Keep this initial progress in sync with initialProgressValue (* 100)
253192472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins    // in ProgressTracker.cpp
253292472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins    private final static int INITIAL_PROGRESS = 10;
253392472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins
253422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void onPageStarted(WebView view, String url, Bitmap favicon) {
253522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // when BrowserActivity just starts, onPageStarted may be called before
253622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // onResume as it is triggered from onCreate. Call resumeWebViewTimers
253722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // to start the timer. As we won't switch tabs while an activity is in
253822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // pause state, we can ensure calling resume and pause in pair.
253922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mActivityInPause) resumeWebViewTimers();
254022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
254122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        resetLockIcon(url);
254222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        setUrlTitle(url, null);
254322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        setFavicon(favicon);
25448cf8f682e90f004d4b8028d2f5b74f72c0cf4e19Leon Scroggins        // Show some progress so that the user knows the page is beginning to
25458cf8f682e90f004d4b8028d2f5b74f72c0cf4e19Leon Scroggins        // load
254692472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins        onProgressChanged(view, INITIAL_PROGRESS);
254722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mDidStopLoad = false;
254822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (!mIsNetworkUp) createAndShowNetworkDialog();
25492c326e62316884a20822035c5470168d0e3b89ffCary Clark        closeDialogs();
255022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mSettings.isTracing()) {
255122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            String host;
255222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            try {
255322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                WebAddress uri = new WebAddress(url);
255422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                host = uri.mHost;
255522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            } catch (android.net.ParseException ex) {
255622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                host = "browser";
255722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
255822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            host = host.replace('.', '_');
255922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            host += ".trace";
256022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mInTrace = true;
256122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            Debug.startMethodTracing(host, 20 * 1024 * 1024);
256215525d48024d325c8a52766d8ca727191251a8d4Patrick Scott        }
256315525d48024d325c8a52766d8ca727191251a8d4Patrick Scott
256422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Performance probe
256522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (false) {
256622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mStart = SystemClock.uptimeMillis();
256722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mProcessStart = Process.getElapsedCpuTime();
256822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            long[] sysCpu = new long[7];
256922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (Process.readProcFile("/proc/stat", SYSTEM_CPU_FORMAT, null,
257022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    sysCpu, null)) {
257122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                mUserStart = sysCpu[0] + sysCpu[1];
257222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                mSystemStart = sysCpu[2];
257322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                mIdleStart = sysCpu[3];
257422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                mIrqStart = sysCpu[4] + sysCpu[5] + sysCpu[6];
257522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
257622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mUiStart = SystemClock.currentThreadTimeMillis();
25770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
25780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
25790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
258022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void onPageFinished(WebView view, String url) {
258122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Reset the title and icon in case we stopped a provisional load.
258222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        resetTitleAndIcon(view);
258322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Update the lock icon image only once we are done loading
258422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        updateLockIconToLatest();
258522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // pause the WebView timer and release the wake lock if it is finished
258622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // while BrowserActivity is in pause state.
258722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mActivityInPause && pauseWebViewTimers()) {
258822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (mWakeLock.isHeld()) {
258922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                mHandler.removeMessages(RELEASE_WAKELOCK);
259022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                mWakeLock.release();
259122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
259222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
259322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
259422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Performance probe
259522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (false) {
259622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            long[] sysCpu = new long[7];
259722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (Process.readProcFile("/proc/stat", SYSTEM_CPU_FORMAT, null,
259822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    sysCpu, null)) {
259922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                String uiInfo = "UI thread used "
260022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        + (SystemClock.currentThreadTimeMillis() - mUiStart)
260122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        + " ms";
260222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                if (LOGD_ENABLED) {
260322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    Log.d(LOGTAG, uiInfo);
260422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                }
260522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                //The string that gets written to the log
260622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                String performanceString = "It took total "
260722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        + (SystemClock.uptimeMillis() - mStart)
260822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        + " ms clock time to load the page."
260922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        + "\nbrowser process used "
261022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        + (Process.getElapsedCpuTime() - mProcessStart)
261122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        + " ms, user processes used "
261222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        + (sysCpu[0] + sysCpu[1] - mUserStart) * 10
261322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        + " ms, kernel used "
261422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        + (sysCpu[2] - mSystemStart) * 10
261522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        + " ms, idle took " + (sysCpu[3] - mIdleStart) * 10
261622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        + " ms and irq took "
261722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        + (sysCpu[4] + sysCpu[5] + sysCpu[6] - mIrqStart)
261822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        * 10 + " ms, " + uiInfo;
261922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                if (LOGD_ENABLED) {
262022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    Log.d(LOGTAG, performanceString + "\nWebpage: " + url);
26210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
262222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                if (url != null) {
262322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    // strip the url to maintain consistency
262422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    String newUrl = new String(url);
262522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    if (newUrl.startsWith("http://www.")) {
262622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        newUrl = newUrl.substring(11);
262722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    } else if (newUrl.startsWith("http://")) {
262822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        newUrl = newUrl.substring(7);
262922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    } else if (newUrl.startsWith("https://www.")) {
263022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        newUrl = newUrl.substring(12);
263122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    } else if (newUrl.startsWith("https://")) {
263222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        newUrl = newUrl.substring(8);
26330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
263431a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort                    if (LOGD_ENABLED) {
263522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        Log.d(LOGTAG, newUrl + " loaded");
26360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
26370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
26380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
263922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         }
26400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
264122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mInTrace) {
264222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mInTrace = false;
264322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            Debug.stopMethodTracing();
26440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
264522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
26460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
264722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    boolean shouldOverrideUrlLoading(WebView view, String url) {
264822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (url.startsWith(SCHEME_WTAI)) {
264922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // wtai://wp/mc;number
265022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // number=string(phone-number)
265122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (url.startsWith(SCHEME_WTAI_MC)) {
265222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                Intent intent = new Intent(Intent.ACTION_VIEW,
265322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        Uri.parse(WebView.SCHEME_TEL +
265422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        url.substring(SCHEME_WTAI_MC.length())));
265522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                startActivity(intent);
265622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                return true;
26570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
265822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // wtai://wp/sd;dtmf
265922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // dtmf=string(dialstring)
266022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (url.startsWith(SCHEME_WTAI_SD)) {
266122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                // TODO: only send when there is active voice connection
26629918943559193e3e047a1c18442e2cdb0fe22b15Dianne Hackborn                return false;
26639918943559193e3e047a1c18442e2cdb0fe22b15Dianne Hackborn            }
266422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // wtai://wp/ap;number;name
266522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // number=string(phone-number)
266622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // name=string
266722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (url.startsWith(SCHEME_WTAI_AP)) {
266822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                // TODO
26690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                return false;
26700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
26710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
26720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
267322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // The "about:" schemes are internal to the browser; don't want these to
267422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // be dispatched to other apps.
267522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (url.startsWith("about:")) {
267622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            return false;
26770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
26780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
267922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        Intent intent;
268022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // perform generic parsing of the URI to turn it into an Intent.
268122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        try {
268222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            intent = Intent.parseUri(url, Intent.URI_INTENT_SCHEME);
268322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        } catch (URISyntaxException ex) {
268422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            Log.w("Browser", "Bad URI " + url + ": " + ex.getMessage());
268522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            return false;
26860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
26870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
268822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // check whether the intent can be resolved. If not, we will see
268922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // whether we can download it from the Market.
269022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (getPackageManager().resolveActivity(intent, 0) == null) {
269122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            String packagename = intent.getPackage();
269222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (packagename != null) {
269322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                intent = new Intent(Intent.ACTION_VIEW, Uri
269422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        .parse("market://search?q=pname:" + packagename));
269522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                intent.addCategory(Intent.CATEGORY_BROWSABLE);
269622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                startActivity(intent);
269722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                return true;
26980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } else {
26990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                return false;
27000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
27010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
27020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
270322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // sanitize the Intent, ensuring web pages can not bypass browser
270422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // security (only access to BROWSABLE activities).
270522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        intent.addCategory(Intent.CATEGORY_BROWSABLE);
270622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        intent.setComponent(null);
270722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        try {
270822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (startActivityIfNeeded(intent, -1)) {
27090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                return true;
27100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
271122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        } catch (ActivityNotFoundException ex) {
271222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // ignore the error. If no application can handle the URL,
271322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // eg about:blank, assume the browser can handle it.
271422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
27150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
271622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mMenuIsDown) {
271722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            openTab(url);
271822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            closeOptionsMenu();
27190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return true;
27200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
272122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return false;
272222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
27230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
272422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // -------------------------------------------------------------------------
272522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // Helper function for WebChromeClient
272622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // -------------------------------------------------------------------------
27270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
272822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void onProgressChanged(WebView view, int newProgress) {
272922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mFakeTitleBar.setProgress(newProgress);
273022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
273122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (newProgress == 100) {
273222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // onProgressChanged() may continue to be called after the main
273322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // frame has finished loading, as any remaining sub frames continue
273422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // to load. We'll only get called once though with newProgress as
273522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // 100 when everything is loaded. (onPageFinished is called once
273622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // when the main frame completes loading regardless of the state of
273722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // any sub frames so calls to onProgressChanges may continue after
273822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // onPageFinished has executed)
273922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (mInLoad) {
274022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                mInLoad = false;
2741a27ff19e24cb1c9fef5624dbc4554548349b5b31Leon Scroggins                updateInLoadMenuItems();
274222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                // If the options menu is open, leave the title bar
274322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                if (!mOptionsMenuOpen || !mIconView) {
274422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    hideFakeTitleBar();
27450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
27460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
2747aa37e7fdb52d0180b8eea25d53950c5c0791f968Leon Scroggins        } else {
2748aa37e7fdb52d0180b8eea25d53950c5c0791f968Leon Scroggins            if (!mInLoad) {
2749aa37e7fdb52d0180b8eea25d53950c5c0791f968Leon Scroggins                // onPageFinished may have already been called but a subframe is
2750aa37e7fdb52d0180b8eea25d53950c5c0791f968Leon Scroggins                // still loading and updating the progress. Reset mInLoad and
2751aa37e7fdb52d0180b8eea25d53950c5c0791f968Leon Scroggins                // update the menu items.
2752aa37e7fdb52d0180b8eea25d53950c5c0791f968Leon Scroggins                mInLoad = true;
2753aa37e7fdb52d0180b8eea25d53950c5c0791f968Leon Scroggins                updateInLoadMenuItems();
2754aa37e7fdb52d0180b8eea25d53950c5c0791f968Leon Scroggins            }
2755aa37e7fdb52d0180b8eea25d53950c5c0791f968Leon Scroggins            // When the page first begins to load, the Activity may still be
2756aa37e7fdb52d0180b8eea25d53950c5c0791f968Leon Scroggins            // paused, in which case showFakeTitleBar will do nothing.  Call
2757aa37e7fdb52d0180b8eea25d53950c5c0791f968Leon Scroggins            // again as the page continues to load so that it will be shown.
2758aa37e7fdb52d0180b8eea25d53950c5c0791f968Leon Scroggins            // (Calling it will the fake title bar is already showing will also
2759aa37e7fdb52d0180b8eea25d53950c5c0791f968Leon Scroggins            // do nothing.
276022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (!mOptionsMenuOpen || mIconView) {
276122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                // This page has begun to load, so show the title bar
276222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                showFakeTitleBar();
27633918d4443ff38ef1870e02aa51a8b29f8352bb1aPatrick Scott            }
27640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
276522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
2766092dd5d22d7f2ee0efcc68bd6e5a3afd1ea98953Ben Murdoch
276722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void onShowCustomView(View view, WebChromeClient.CustomViewCallback callback) {
27688ff57db0a8dc8eb659fbcdcd4a856208609e6070Derek Sollenberger        // if a view already exists then immediately terminate the new one
27698ff57db0a8dc8eb659fbcdcd4a856208609e6070Derek Sollenberger        if (mCustomView != null) {
27708ff57db0a8dc8eb659fbcdcd4a856208609e6070Derek Sollenberger            callback.onCustomViewHidden();
277122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            return;
27728ff57db0a8dc8eb659fbcdcd4a856208609e6070Derek Sollenberger        }
27732bc69918d97a767a02132090e58718077381ba1aSteve Block
277422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Add the custom view to its container.
277522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mCustomViewContainer.addView(view, COVER_SCREEN_GRAVITY_CENTER);
277622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mCustomView = view;
277722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mCustomViewCallback = callback;
277822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Save the menu state and set it to empty while the custom
277922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // view is showing.
278022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mOldMenuState = mMenuState;
278122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mMenuState = EMPTY_MENU;
278222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Hide the content view.
278322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mContentView.setVisibility(View.GONE);
278422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Finally show the custom view container.
2785163ab74e2f85b53a1a374c49677073fb64d35f28Andrei Popescu        setStatusBarVisibility(false);
278622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mCustomViewContainer.setVisibility(View.VISIBLE);
278722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mCustomViewContainer.bringToFront();
278822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
278922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
279022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void onHideCustomView() {
279122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mCustomView == null)
279222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            return;
27932bc69918d97a767a02132090e58718077381ba1aSteve Block
279422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Hide the custom view.
279522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mCustomView.setVisibility(View.GONE);
279622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Remove the custom view from its container.
279722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mCustomViewContainer.removeView(mCustomView);
279822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mCustomView = null;
279922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Reset the old menu state.
280022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mMenuState = mOldMenuState;
280122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mOldMenuState = EMPTY_MENU;
280222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mCustomViewContainer.setVisibility(View.GONE);
280322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mCustomViewCallback.onCustomViewHidden();
280422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Show the content view.
2805163ab74e2f85b53a1a374c49677073fb64d35f28Andrei Popescu        setStatusBarVisibility(true);
280622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mContentView.setVisibility(View.VISIBLE);
280722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
2808540035dfd1347c78eeec10ec0847e18fcc50ef36Andrei Popescu
280922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    Bitmap getDefaultVideoPoster() {
281022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mDefaultVideoPoster == null) {
281122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mDefaultVideoPoster = BitmapFactory.decodeResource(
281222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    getResources(), R.drawable.default_video_poster);
2813540035dfd1347c78eeec10ec0847e18fcc50ef36Andrei Popescu        }
281422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return mDefaultVideoPoster;
281522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
2816540035dfd1347c78eeec10ec0847e18fcc50ef36Andrei Popescu
281722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    View getVideoLoadingProgressView() {
281822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mVideoProgressView == null) {
281922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            LayoutInflater inflater = LayoutInflater.from(BrowserActivity.this);
282022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mVideoProgressView = inflater.inflate(
282122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    R.layout.video_loading_progress, null);
2822540035dfd1347c78eeec10ec0847e18fcc50ef36Andrei Popescu        }
282322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return mVideoProgressView;
282422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
28250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
28268d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins    /*
28278d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins     * The Object used to inform the WebView of the file to upload.
28288d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins     */
28298d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins    private ValueCallback<Uri> mUploadMessage;
28308d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins
283122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void openFileChooser(ValueCallback<Uri> uploadMsg) {
283222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mUploadMessage != null) return;
283322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mUploadMessage = uploadMsg;
283422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        Intent i = new Intent(Intent.ACTION_GET_CONTENT);
283522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        i.addCategory(Intent.CATEGORY_OPENABLE);
283622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        i.setType("*/*");
283722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        BrowserActivity.this.startActivityForResult(Intent.createChooser(i,
283822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                getString(R.string.choose_upload)), FILE_SELECTED);
283922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
284022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
284122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // -------------------------------------------------------------------------
284222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // Implement functions for DownloadListener
284322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // -------------------------------------------------------------------------
284422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
28450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
28460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Notify the host application a download should be done, or that
28470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * the data should be streamed if a streaming viewer is available.
28480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param url The full url to the content that should be downloaded
28490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param contentDisposition Content-disposition http header, if
28500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *                           present.
28510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param mimetype The mimetype of the content reported by the server
28520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param contentLength The file size reported by the server
28530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
28540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public void onDownloadStart(String url, String userAgent,
28550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            String contentDisposition, String mimetype, long contentLength) {
28560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // if we're dealing wih A/V content that's not explicitly marked
28570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        //     for download, check if it's streamable.
28580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (contentDisposition == null
2859e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                || !contentDisposition.regionMatches(
2860e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                        true, 0, "attachment", 0, 10)) {
28610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // query the package manager to see if there's a registered handler
28620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            //     that matches.
28630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Intent intent = new Intent(Intent.ACTION_VIEW);
28640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            intent.setDataAndType(Uri.parse(url), mimetype);
2865e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott            ResolveInfo info = getPackageManager().resolveActivity(intent,
2866e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                    PackageManager.MATCH_DEFAULT_ONLY);
2867e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott            if (info != null) {
2868e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                ComponentName myName = getComponentName();
2869e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                // If we resolved to ourselves, we don't want to attempt to
2870e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                // load the url only to try and download it again.
2871e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                if (!myName.getPackageName().equals(
2872e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                        info.activityInfo.packageName)
2873e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                        || !myName.getClassName().equals(
2874e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                                info.activityInfo.name)) {
2875e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                    // someone (other than us) knows how to handle this mime
2876e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                    // type with this scheme, don't download.
2877e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                    try {
2878e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                        startActivity(intent);
2879e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                        return;
2880e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                    } catch (ActivityNotFoundException ex) {
2881e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                        if (LOGD_ENABLED) {
2882e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                            Log.d(LOGTAG, "activity not found for " + mimetype
2883e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                                    + " over " + Uri.parse(url).getScheme(),
2884e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                                    ex);
2885e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                        }
2886e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                        // Best behavior is to fall back to a download in this
2887e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                        // case
28880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
28890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
28900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
28910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
28920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        onDownloadStartNoStream(url, userAgent, contentDisposition, mimetype, contentLength);
28930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
28940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
2895fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen    // This is to work around the fact that java.net.URI throws Exceptions
2896fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen    // instead of just encoding URL's properly
2897fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen    // Helper method for onDownloadStartNoStream
2898fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen    private static String encodePath(String path) {
2899fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen        char[] chars = path.toCharArray();
2900fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen
2901fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen        boolean needed = false;
2902fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen        for (char c : chars) {
2903fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen            if (c == '[' || c == ']') {
2904fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen                needed = true;
2905fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen                break;
2906fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen            }
2907fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen        }
2908fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen        if (needed == false) {
2909fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen            return path;
2910fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen        }
2911fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen
2912fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen        StringBuilder sb = new StringBuilder("");
2913fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen        for (char c : chars) {
2914fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen            if (c == '[' || c == ']') {
2915fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen                sb.append('%');
2916fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen                sb.append(Integer.toHexString(c));
2917fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen            } else {
2918fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen                sb.append(c);
2919fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen            }
2920fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen        }
2921fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen
2922fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen        return sb.toString();
2923fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen    }
2924fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen
29250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
29260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Notify the host application a download should be done, even if there
29270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * is a streaming viewer available for thise type.
29280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param url The full url to the content that should be downloaded
29290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param contentDisposition Content-disposition http header, if
29300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *                           present.
29310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param mimetype The mimetype of the content reported by the server
29320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param contentLength The file size reported by the server
29330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
29340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /*package */ void onDownloadStartNoStream(String url, String userAgent,
29350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            String contentDisposition, String mimetype, long contentLength) {
29360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
29370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String filename = URLUtil.guessFileName(url,
29380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                contentDisposition, mimetype);
29390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
29400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Check to see if we have an SDCard
29410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String status = Environment.getExternalStorageState();
29420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (!status.equals(Environment.MEDIA_MOUNTED)) {
29430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            int title;
29440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            String msg;
29450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
29460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Check to see if the SDCard is busy, same as the music app
29470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (status.equals(Environment.MEDIA_SHARED)) {
29480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                msg = getString(R.string.download_sdcard_busy_dlg_msg);
29490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                title = R.string.download_sdcard_busy_dlg_title;
29500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } else {
29510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                msg = getString(R.string.download_no_sdcard_dlg_msg, filename);
29520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                title = R.string.download_no_sdcard_dlg_title;
29530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
29540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
29550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            new AlertDialog.Builder(this)
29560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setTitle(title)
29570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setIcon(android.R.drawable.ic_dialog_alert)
29580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setMessage(msg)
29590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setPositiveButton(R.string.ok, null)
29600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .show();
29610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
29620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
29630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
2964fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen        // java.net.URI is a lot stricter than KURL so we have to encode some
2965fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen        // extra characters. Fix for b 2538060 and b 1634719
2966fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen        WebAddress webAddress;
29670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        try {
2968fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen            webAddress = new WebAddress(url);
2969fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen            webAddress.mPath = encodePath(webAddress.mPath);
29700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } catch (Exception e) {
2971fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen            // This only happens for very bad urls, we want to chatch the
2972fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen            // exception here
2973fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen            Log.e(LOGTAG, "Exception trying to parse url:" + url);
29740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
29750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
29760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
29770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // XXX: Have to use the old url since the cookies were stored using the
29780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // old percent-encoded url.
29790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String cookies = CookieManager.getInstance().getCookie(url);
29800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
29810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        ContentValues values = new ContentValues();
2982fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen        values.put(Downloads.Impl.COLUMN_URI, webAddress.toString());
29831e5bad97ca8fb9b12501f4f747941d02f03e1362Jean-Baptiste Queru        values.put(Downloads.Impl.COLUMN_COOKIE_DATA, cookies);
29841e5bad97ca8fb9b12501f4f747941d02f03e1362Jean-Baptiste Queru        values.put(Downloads.Impl.COLUMN_USER_AGENT, userAgent);
29851e5bad97ca8fb9b12501f4f747941d02f03e1362Jean-Baptiste Queru        values.put(Downloads.Impl.COLUMN_NOTIFICATION_PACKAGE,
29860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                getPackageName());
29871e5bad97ca8fb9b12501f4f747941d02f03e1362Jean-Baptiste Queru        values.put(Downloads.Impl.COLUMN_NOTIFICATION_CLASS,
2988a563d09392905140893d7a017dd63721577e1953Leon Scroggins                OpenDownloadReceiver.class.getCanonicalName());
29891e5bad97ca8fb9b12501f4f747941d02f03e1362Jean-Baptiste Queru        values.put(Downloads.Impl.COLUMN_VISIBILITY,
29901e5bad97ca8fb9b12501f4f747941d02f03e1362Jean-Baptiste Queru                Downloads.Impl.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
29911e5bad97ca8fb9b12501f4f747941d02f03e1362Jean-Baptiste Queru        values.put(Downloads.Impl.COLUMN_MIME_TYPE, mimetype);
29921e5bad97ca8fb9b12501f4f747941d02f03e1362Jean-Baptiste Queru        values.put(Downloads.Impl.COLUMN_FILE_NAME_HINT, filename);
2993fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen        values.put(Downloads.Impl.COLUMN_DESCRIPTION, webAddress.mHost);
29940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (contentLength > 0) {
29951e5bad97ca8fb9b12501f4f747941d02f03e1362Jean-Baptiste Queru            values.put(Downloads.Impl.COLUMN_TOTAL_BYTES, contentLength);
29960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
29970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mimetype == null) {
29980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // We must have long pressed on a link or image to download it. We
29990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // are not sure of the mimetype in this case, so do a head request
30000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            new FetchUrlMimeType(this).execute(values);
30010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
30020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            final Uri contentUri =
30031e5bad97ca8fb9b12501f4f747941d02f03e1362Jean-Baptiste Queru                    getContentResolver().insert(Downloads.Impl.CONTENT_URI, values);
30040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
30059191a7f745c965cf57df94d0628890b413c710c9Leon Scroggins        Toast.makeText(this, R.string.download_pending, Toast.LENGTH_SHORT)
30069191a7f745c965cf57df94d0628890b413c710c9Leon Scroggins                .show();
30070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
30080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
300922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // -------------------------------------------------------------------------
301022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
30110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
30120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Resets the lock icon. This method is called when we start a new load and
30130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * know the url to be loaded.
30140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
30150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void resetLockIcon(String url) {
30160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Save the lock-icon state (we revert to it if the load gets cancelled)
301722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mTabControl.getCurrentTab().resetLockIcon(url);
30180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        updateLockIconImage(LOCK_ICON_UNSECURE);
30190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
30200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
30210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
30223bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     * Update the lock icon to correspond to our latest state.
30233bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     */
302422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private void updateLockIconToLatest() {
302522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        updateLockIconImage(mTabControl.getCurrentTab().getLockIconType());
30263bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    }
30273bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins
30283bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    /**
30290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Updates the lock-icon image in the title-bar.
30300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
30310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void updateLockIconImage(int lockIconType) {
30320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        Drawable d = null;
30330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (lockIconType == LOCK_ICON_SECURE) {
30340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            d = mSecLockIcon;
30350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else if (lockIconType == LOCK_ICON_MIXED) {
30360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            d = mMixLockIcon;
30370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
303868579393973f745fc65a2781061af9bb8f2d7020Leon Scroggins        mTitleBar.setLock(d);
3039fe87bd3a3897e4bad65bb3d284659ae2f4e57570Leon Scroggins        mFakeTitleBar.setLock(d);
30400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
30410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
30420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
30430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Displays a page-info dialog.
30440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param tab The tab to show info about
30450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param fromShowSSLCertificateOnError The flag that indicates whether
30460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * this dialog was opened from the SSL-certificate-on-error dialog or
30470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * not. This is important, since we need to know whether to return to
30480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * the parent dialog or simply dismiss.
30490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
305022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private void showPageInfo(final Tab tab,
30510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                              final boolean fromShowSSLCertificateOnError) {
30520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final LayoutInflater factory = LayoutInflater
30530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .from(this);
30540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
30550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final View pageInfoView = factory.inflate(R.layout.page_info, null);
30560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
30570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final WebView view = tab.getWebView();
30580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
30590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String url = null;
30600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String title = null;
30610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
30620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (view == null) {
30630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            url = tab.getUrl();
30640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            title = tab.getTitle();
30650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else if (view == mTabControl.getCurrentWebView()) {
30660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project             // Use the cached title and url if this is the current WebView
30670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            url = mUrl;
30680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            title = mTitle;
30690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
30700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            url = view.getUrl();
30710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            title = view.getTitle();
30720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
30730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
30740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (url == null) {
30750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            url = "";
30760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
30770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (title == null) {
30780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            title = "";
30790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
30800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
30810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        ((TextView) pageInfoView.findViewById(R.id.address)).setText(url);
30820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        ((TextView) pageInfoView.findViewById(R.id.title)).setText(title);
30830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
30840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mPageInfoView = tab;
3085c7b92f811dfa3572578ddc6714c98a03936d9ce5Leon Scroggins        mPageInfoFromShowSSLCertificateOnError = fromShowSSLCertificateOnError;
30860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
30870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        AlertDialog.Builder alertDialogBuilder =
30880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            new AlertDialog.Builder(this)
30890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            .setTitle(R.string.page_info).setIcon(android.R.drawable.ic_dialog_info)
30900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            .setView(pageInfoView)
30910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            .setPositiveButton(
30920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                R.string.ok,
30930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                new DialogInterface.OnClickListener() {
30940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    public void onClick(DialogInterface dialog,
30950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        int whichButton) {
30960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        mPageInfoDialog = null;
30970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        mPageInfoView = null;
30980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
30990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        // if we came here from the SSL error dialog
31000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        if (fromShowSSLCertificateOnError) {
31010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            // go back to the SSL error dialog
31020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            showSSLCertificateOnError(
31030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorView,
31040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorHandler,
31050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorError);
31060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }
31070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
31080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                })
31090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            .setOnCancelListener(
31100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                new DialogInterface.OnCancelListener() {
31110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    public void onCancel(DialogInterface dialog) {
31120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        mPageInfoDialog = null;
31130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        mPageInfoView = null;
31140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
31150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        // if we came here from the SSL error dialog
31160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        if (fromShowSSLCertificateOnError) {
31170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            // go back to the SSL error dialog
31180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            showSSLCertificateOnError(
31190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorView,
31200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorHandler,
31210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorError);
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        // if we have a main top-level page SSL certificate set or a certificate
31270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // error
31280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (fromShowSSLCertificateOnError ||
31290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                (view != null && view.getCertificate() != null)) {
31300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // add a 'View Certificate' button
31310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            alertDialogBuilder.setNeutralButton(
31320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                R.string.view_certificate,
31330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                new DialogInterface.OnClickListener() {
31340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    public void onClick(DialogInterface dialog,
31350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        int whichButton) {
31360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        mPageInfoDialog = null;
31370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        mPageInfoView = null;
31380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
31390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        // if we came here from the SSL error dialog
31400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        if (fromShowSSLCertificateOnError) {
31410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            // go back to the SSL error dialog
31420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            showSSLCertificateOnError(
31430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorView,
31440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorHandler,
31450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorError);
31460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        } else {
31470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            // otherwise, display the top-most certificate from
31480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            // the chain
31490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            if (view.getCertificate() != null) {
31500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                showSSLCertificate(tab);
31510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            }
31520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }
31530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
31540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                });
31550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
31560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
31570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mPageInfoDialog = alertDialogBuilder.show();
31580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
31590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
31600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project       /**
31610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Displays the main top-level page SSL certificate dialog
31620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * (accessible from the Page-Info dialog).
31630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param tab The tab to show certificate for.
31640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
316522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private void showSSLCertificate(final Tab tab) {
31660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final View certificateView =
31670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                inflateCertificateView(tab.getWebView().getCertificate());
31680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (certificateView == null) {
31690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
31700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
31710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
31720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        LayoutInflater factory = LayoutInflater.from(this);
31730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
31740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final LinearLayout placeholder =
31750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                (LinearLayout)certificateView.findViewById(R.id.placeholder);
31760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
31770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        LinearLayout ll = (LinearLayout) factory.inflate(
31780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            R.layout.ssl_success, placeholder);
31790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        ((TextView)ll.findViewById(R.id.success))
31800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            .setText(R.string.ssl_certificate_is_valid);
31810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
31820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mSSLCertificateView = tab;
31830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mSSLCertificateDialog =
31840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            new AlertDialog.Builder(this)
31850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setTitle(R.string.ssl_certificate).setIcon(
31860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    R.drawable.ic_dialog_browser_certificate_secure)
31870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setView(certificateView)
31880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setPositiveButton(R.string.ok,
31890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new DialogInterface.OnClickListener() {
31900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            public void onClick(DialogInterface dialog,
31910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    int whichButton) {
31920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateDialog = null;
31930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateView = null;
31940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
31950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                showPageInfo(tab, false);
31960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            }
31970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        })
31980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setOnCancelListener(
31990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new DialogInterface.OnCancelListener() {
32000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            public void onCancel(DialogInterface dialog) {
32010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateDialog = null;
32020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateView = null;
32030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
32040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                showPageInfo(tab, false);
32050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            }
32060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        })
32070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .show();
32080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
32090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
32100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
32110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Displays the SSL error certificate dialog.
32120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param view The target web-view.
32130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param handler The SSL error handler responsible for cancelling the
32140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * connection that resulted in an SSL error or proceeding per user request.
32150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param error The SSL error object.
32160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
321722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void showSSLCertificateOnError(
32180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final WebView view, final SslErrorHandler handler, final SslError error) {
32190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
32200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final View certificateView =
32210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            inflateCertificateView(error.getCertificate());
32220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (certificateView == null) {
32230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
32240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
32250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
32260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        LayoutInflater factory = LayoutInflater.from(this);
32270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
32280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final LinearLayout placeholder =
32290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                (LinearLayout)certificateView.findViewById(R.id.placeholder);
32300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
32310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (error.hasError(SslError.SSL_UNTRUSTED)) {
32320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            LinearLayout ll = (LinearLayout)factory
32330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .inflate(R.layout.ssl_warning, placeholder);
32340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((TextView)ll.findViewById(R.id.warning))
32350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setText(R.string.ssl_untrusted);
32360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
32370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
32380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (error.hasError(SslError.SSL_IDMISMATCH)) {
32390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            LinearLayout ll = (LinearLayout)factory
32400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .inflate(R.layout.ssl_warning, placeholder);
32410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((TextView)ll.findViewById(R.id.warning))
32420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setText(R.string.ssl_mismatch);
32430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
32440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
32450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (error.hasError(SslError.SSL_EXPIRED)) {
32460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            LinearLayout ll = (LinearLayout)factory
32470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .inflate(R.layout.ssl_warning, placeholder);
32480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((TextView)ll.findViewById(R.id.warning))
32490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setText(R.string.ssl_expired);
32500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
32510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
32520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (error.hasError(SslError.SSL_NOTYETVALID)) {
32530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            LinearLayout ll = (LinearLayout)factory
32540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .inflate(R.layout.ssl_warning, placeholder);
32550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((TextView)ll.findViewById(R.id.warning))
32560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setText(R.string.ssl_not_yet_valid);
32570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
32580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
32590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mSSLCertificateOnErrorHandler = handler;
32600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mSSLCertificateOnErrorView = view;
32610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mSSLCertificateOnErrorError = error;
32620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mSSLCertificateOnErrorDialog =
32630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            new AlertDialog.Builder(this)
32640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setTitle(R.string.ssl_certificate).setIcon(
32650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    R.drawable.ic_dialog_browser_certificate_partially_secure)
32660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setView(certificateView)
32670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setPositiveButton(R.string.ok,
32680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new DialogInterface.OnClickListener() {
32690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            public void onClick(DialogInterface dialog,
32700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    int whichButton) {
32710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorDialog = null;
32720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorView = null;
32730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorHandler = null;
32740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorError = null;
32750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
327622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                view.getWebViewClient().onReceivedSslError(
327722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                                view, handler, error);
32780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            }
32790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        })
32800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                 .setNeutralButton(R.string.page_info_view,
32810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new DialogInterface.OnClickListener() {
32820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            public void onClick(DialogInterface dialog,
32830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    int whichButton) {
32840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorDialog = null;
32850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
32860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                // do not clear the dialog state: we will
32870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                // need to show the dialog again once the
32880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                // user is done exploring the page-info details
32890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
32900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                showPageInfo(mTabControl.getTabFromView(view),
32910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        true);
32920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            }
32930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        })
32940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setOnCancelListener(
32950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new DialogInterface.OnCancelListener() {
32960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            public void onCancel(DialogInterface dialog) {
32970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorDialog = null;
32980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorView = null;
32990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorHandler = null;
33000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorError = null;
33010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
330222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                view.getWebViewClient().onReceivedSslError(
330322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                                view, handler, error);
33040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            }
33050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        })
33060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .show();
33070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
33080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
33090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
33100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Inflates the SSL certificate view (helper method).
33110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param certificate The SSL certificate.
33120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @return The resultant certificate view with issued-to, issued-by,
33130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * issued-on, expires-on, and possibly other fields set.
33140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * If the input certificate is null, returns null.
33150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
33160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private View inflateCertificateView(SslCertificate certificate) {
33170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (certificate == null) {
33180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return null;
33190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
33200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
33210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        LayoutInflater factory = LayoutInflater.from(this);
33220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
33230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        View certificateView = factory.inflate(
33240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            R.layout.ssl_certificate, null);
33250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
33260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // issued to:
33270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        SslCertificate.DName issuedTo = certificate.getIssuedTo();
33280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (issuedTo != null) {
33290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((TextView) certificateView.findViewById(R.id.to_common))
33300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setText(issuedTo.getCName());
33310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((TextView) certificateView.findViewById(R.id.to_org))
33320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setText(issuedTo.getOName());
33330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((TextView) certificateView.findViewById(R.id.to_org_unit))
33340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setText(issuedTo.getUName());
33350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
33360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
33370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // issued by:
33380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        SslCertificate.DName issuedBy = certificate.getIssuedBy();
33390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (issuedBy != null) {
33400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((TextView) certificateView.findViewById(R.id.by_common))
33410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setText(issuedBy.getCName());
33420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((TextView) certificateView.findViewById(R.id.by_org))
33430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setText(issuedBy.getOName());
33440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((TextView) certificateView.findViewById(R.id.by_org_unit))
33450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setText(issuedBy.getUName());
33460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
33470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
33480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // issued on:
334995a2e4ab94514e4e41033b0d27a0e66855cff8ebBrian Carlstrom        String issuedOn = formatCertificateDate(
335095a2e4ab94514e4e41033b0d27a0e66855cff8ebBrian Carlstrom            certificate.getValidNotBeforeDate());
33510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        ((TextView) certificateView.findViewById(R.id.issued_on))
33520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            .setText(issuedOn);
33530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
33540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // expires on:
335595a2e4ab94514e4e41033b0d27a0e66855cff8ebBrian Carlstrom        String expiresOn = formatCertificateDate(
335695a2e4ab94514e4e41033b0d27a0e66855cff8ebBrian Carlstrom            certificate.getValidNotAfterDate());
33570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        ((TextView) certificateView.findViewById(R.id.expires_on))
33580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            .setText(expiresOn);
33590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
33600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return certificateView;
33610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
33620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
33630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
336495a2e4ab94514e4e41033b0d27a0e66855cff8ebBrian Carlstrom     * Formats the certificate date to a properly localized date string.
33650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @return Properly localized version of the certificate date string and
336695a2e4ab94514e4e41033b0d27a0e66855cff8ebBrian Carlstrom     * the "" if it fails to localize.
33670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
336895a2e4ab94514e4e41033b0d27a0e66855cff8ebBrian Carlstrom    private String formatCertificateDate(Date certificateDate) {
336995a2e4ab94514e4e41033b0d27a0e66855cff8ebBrian Carlstrom      if (certificateDate == null) {
337095a2e4ab94514e4e41033b0d27a0e66855cff8ebBrian Carlstrom          return "";
33710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project      }
337295a2e4ab94514e4e41033b0d27a0e66855cff8ebBrian Carlstrom      String formattedDate = DateFormat.getDateFormat(this).format(certificateDate);
337395a2e4ab94514e4e41033b0d27a0e66855cff8ebBrian Carlstrom      if (formattedDate == null) {
337495a2e4ab94514e4e41033b0d27a0e66855cff8ebBrian Carlstrom          return "";
337595a2e4ab94514e4e41033b0d27a0e66855cff8ebBrian Carlstrom      }
337695a2e4ab94514e4e41033b0d27a0e66855cff8ebBrian Carlstrom      return formattedDate;
33770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
33780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
33790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
33800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Displays an http-authentication dialog.
33810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
338222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void showHttpAuthentication(final HttpAuthHandler handler,
33830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            final String host, final String realm, final String title,
33840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            final String name, final String password, int focusId) {
33850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        LayoutInflater factory = LayoutInflater.from(this);
33860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final View v = factory
33870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .inflate(R.layout.http_authentication, null);
33880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (name != null) {
33890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((EditText) v.findViewById(R.id.username_edit)).setText(name);
33900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
33910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (password != null) {
33920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((EditText) v.findViewById(R.id.password_edit)).setText(password);
33930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
33940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
33950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String titleText = title;
33960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (titleText == null) {
33970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            titleText = getText(R.string.sign_in_to).toString().replace(
33980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    "%s1", host).replace("%s2", realm);
33990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
34000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
34010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mHttpAuthHandler = handler;
34020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        AlertDialog dialog = new AlertDialog.Builder(this)
34030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setTitle(titleText)
34040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setIcon(android.R.drawable.ic_dialog_alert)
34050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setView(v)
34060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setPositiveButton(R.string.action,
34070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new DialogInterface.OnClickListener() {
34080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                             public void onClick(DialogInterface dialog,
34090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                     int whichButton) {
34100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                String nm = ((EditText) v
34110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        .findViewById(R.id.username_edit))
34120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        .getText().toString();
34130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                String pw = ((EditText) v
34140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        .findViewById(R.id.password_edit))
34150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        .getText().toString();
34160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                BrowserActivity.this.setHttpAuthUsernamePassword
34170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        (host, realm, nm, pw);
34180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                handler.proceed(nm, pw);
34190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mHttpAuthenticationDialog = null;
34200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mHttpAuthHandler = null;
34210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            }})
34220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setNegativeButton(R.string.cancel,
34230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new DialogInterface.OnClickListener() {
34240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            public void onClick(DialogInterface dialog,
34250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    int whichButton) {
34260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                handler.cancel();
34270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                BrowserActivity.this.resetTitleAndRevertLockIcon();
34280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mHttpAuthenticationDialog = null;
34290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mHttpAuthHandler = null;
34300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            }})
34310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setOnCancelListener(new DialogInterface.OnCancelListener() {
34320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        public void onCancel(DialogInterface dialog) {
34330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            handler.cancel();
34340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            BrowserActivity.this.resetTitleAndRevertLockIcon();
34350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            mHttpAuthenticationDialog = null;
34360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            mHttpAuthHandler = null;
34370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }})
34380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .create();
34390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Make the IME appear when the dialog is displayed if applicable.
34400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        dialog.getWindow().setSoftInputMode(
34410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);
34420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        dialog.show();
34430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (focusId != 0) {
34440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            dialog.findViewById(focusId).requestFocus();
34450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
34460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            v.findViewById(R.id.username_edit).requestFocus();
34470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
34480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mHttpAuthenticationDialog = dialog;
34490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
34500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
34510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public int getProgress() {
34520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebView w = mTabControl.getCurrentWebView();
34530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (w != null) {
34540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return w.getProgress();
34550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
34560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return 100;
34570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
34580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
34590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
34600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
34610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Set HTTP authentication password.
34620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *
34630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param host The host for the password
34640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param realm The realm for the password
34650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param username The username for the password. If it is null, it means
34660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *            password can't be saved.
34670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param password The password
34680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
34690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public void setHttpAuthUsernamePassword(String host, String realm,
34700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                            String username,
34710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                            String password) {
347295a53b25504f12c3a5f8ecbbfcff7ac1dc047e4fSteve Block        WebView w = getTopWindow();
34730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (w != null) {
34740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            w.setHttpAuthUsernamePassword(host, realm, username, password);
34750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
34760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
34770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
34780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
34790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * connectivity manager says net has come or gone... inform the user
34800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param up true if net has come up, false if net has gone down
34810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
34820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public void onNetworkToggle(boolean up) {
34830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (up == mIsNetworkUp) {
34840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
34850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else if (up) {
34860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mIsNetworkUp = true;
34870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (mAlertDialog != null) {
34880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mAlertDialog.cancel();
34890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mAlertDialog = null;
34900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
34910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
34920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mIsNetworkUp = false;
3493eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott            if (mInLoad) {
3494eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott                createAndShowNetworkDialog();
3495eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott           }
34960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
34970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebView w = mTabControl.getCurrentWebView();
34980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (w != null) {
34990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            w.setNetworkAvailable(up);
35000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
35010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
35020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
350322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    boolean isNetworkUp() {
350422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return mIsNetworkUp;
350522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
350622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
3507eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott    // This method shows the network dialog alerting the user that the net is
3508eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott    // down. It will only show the dialog if mAlertDialog is null.
3509eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott    private void createAndShowNetworkDialog() {
3510eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott        if (mAlertDialog == null) {
3511eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott            mAlertDialog = new AlertDialog.Builder(this)
3512eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott                    .setTitle(R.string.loadSuspendedTitle)
3513eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott                    .setMessage(R.string.loadSuspended)
3514eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott                    .setPositiveButton(R.string.ok, null)
3515eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott                    .show();
3516eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott        }
3517eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott    }
3518eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott
35190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    @Override
35200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    protected void onActivityResult(int requestCode, int resultCode,
35210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    Intent intent) {
3522bb394f3e134b6e5898ef7ae861b75e95e618688fGrace Kloba        if (getTopWindow() == null) return;
3523bb394f3e134b6e5898ef7ae861b75e95e618688fGrace Kloba
35240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        switch (requestCode) {
35250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case COMBO_PAGE:
35260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (resultCode == RESULT_OK && intent != null) {
35270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    String data = intent.getAction();
35280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    Bundle extras = intent.getExtras();
35290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    if (extras != null && extras.getBoolean("new_window", false)) {
353025d3547e0df084f963e38c6a93c99b02bd619de3Leon Scroggins                        openTab(data);
35310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    } else {
353222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        final Tab currentTab =
35330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mTabControl.getCurrentTab();
35341f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                        dismissSubWindow(currentTab);
35351f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                        if (data != null && data.length() != 0) {
353692472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins                            loadUrl(getTopWindow(), data);
35370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }
35380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
35390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
3540fde9746ac3055848e110c35f19ec5893c621f766Leon Scroggins                // Deliberately fall through to PREFERENCES_PAGE, since the
3541fde9746ac3055848e110c35f19ec5893c621f766Leon Scroggins                // same extra may be attached to the COMBO_PAGE
3542fde9746ac3055848e110c35f19ec5893c621f766Leon Scroggins            case PREFERENCES_PAGE:
3543fde9746ac3055848e110c35f19ec5893c621f766Leon Scroggins                if (resultCode == RESULT_OK && intent != null) {
3544fde9746ac3055848e110c35f19ec5893c621f766Leon Scroggins                    String action = intent.getStringExtra(Intent.EXTRA_TEXT);
3545fde9746ac3055848e110c35f19ec5893c621f766Leon Scroggins                    if (BrowserSettings.PREF_CLEAR_HISTORY.equals(action)) {
3546fde9746ac3055848e110c35f19ec5893c621f766Leon Scroggins                        mTabControl.removeParentChildRelationShips();
3547fde9746ac3055848e110c35f19ec5893c621f766Leon Scroggins                    }
3548fde9746ac3055848e110c35f19ec5893c621f766Leon Scroggins                }
35490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
35508d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins            // Choose a file from the file picker.
35518d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins            case FILE_SELECTED:
35528d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins                if (null == mUploadMessage) break;
35538d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins                Uri result = intent == null || resultCode != RESULT_OK ? null
35548d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins                        : intent.getData();
35558d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins                mUploadMessage.onReceiveValue(result);
35568d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins                mUploadMessage = null;
35578d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins                break;
35580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            default:
35590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
35600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
3561304442375719effd41dbd53ae62de7a8d0cec7d9Leon Scroggins        getTopWindow().requestFocus();
35620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
35630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
35640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /*
35650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * This method is called as a result of the user selecting the options
3566f08809b2cf7e502fef5965691a7fb6d7cf0322afLeon Scroggins     * menu to see the download window. It shows the download window on top of
3567f08809b2cf7e502fef5965691a7fb6d7cf0322afLeon Scroggins     * the current window.
35680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
3569f08809b2cf7e502fef5965691a7fb6d7cf0322afLeon Scroggins    private void viewDownloads(Uri downloadRecord) {
35700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        Intent intent = new Intent(this,
35710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                BrowserDownloadPage.class);
35720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        intent.setData(downloadRecord);
357322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        startActivityForResult(intent, BrowserActivity.DOWNLOAD_PAGE);
35740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
35750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
35760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
3577160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins    /**
3578160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins     * Open the Go page.
3579160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins     * @param startWithHistory If true, open starting on the history tab.
3580160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins     *                         Otherwise, start with the bookmarks tab.
3581160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins     */
3582304442375719effd41dbd53ae62de7a8d0cec7d9Leon Scroggins    /* package */ void bookmarksOrHistoryPicker(boolean startWithHistory) {
35830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebView current = mTabControl.getCurrentWebView();
35840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (current == null) {
35850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
35860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
35870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        Intent intent = new Intent(this,
35880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                CombinedBookmarkHistoryActivity.class);
35890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String title = current.getTitle();
35900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String url = current.getUrl();
3591dcc2b6f08dd5677bc6ba761a9ba6f1c655113051Ben Murdoch        Bitmap thumbnail = createScreenshot(current);
3592dcc2b6f08dd5677bc6ba761a9ba6f1c655113051Ben Murdoch
35930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Just in case the user opens bookmarks before a page finishes loading
35940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // so the current history item, and therefore the page, is null.
35950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (null == url) {
35960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            url = mLastEnteredUrl;
35970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // This can happen.
35980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (null == url) {
35990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                url = mSettings.getHomePage();
36000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
36010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
36020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // In case the web page has not yet received its associated title.
36030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (title == null) {
36040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            title = url;
36050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
36060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        intent.putExtra("title", title);
36070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        intent.putExtra("url", url);
3608dcc2b6f08dd5677bc6ba761a9ba6f1c655113051Ben Murdoch        intent.putExtra("thumbnail", thumbnail);
3609304442375719effd41dbd53ae62de7a8d0cec7d9Leon Scroggins        // Disable opening in a new window if we have maxed out the windows
361022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        intent.putExtra("disable_new_window", !mTabControl.canCreateNewTab());
36113918d4443ff38ef1870e02aa51a8b29f8352bb1aPatrick Scott        intent.putExtra("touch_icon_url", current.getTouchIconUrl());
36120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (startWithHistory) {
36130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            intent.putExtra(CombinedBookmarkHistoryActivity.STARTING_TAB,
36140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    CombinedBookmarkHistoryActivity.HISTORY_TAB);
36150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
36160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        startActivityForResult(intent, COMBO_PAGE);
36170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
36180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
36190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Called when loading from context menu or LOAD_URL message
362092472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins    private void loadUrlFromContext(WebView view, String url) {
36210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // In case the user enters nothing.
36220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (url != null && url.length() != 0 && view != null) {
36230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            url = smartUrlFilter(url);
362422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (!view.getWebViewClient().shouldOverrideUrlLoading(view, url)) {
362592472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins                loadUrl(view, url);
36260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
36270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
36280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
36290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
363092472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins    /**
363192472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins     * Load the URL into the given WebView and update the title bar
363292472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins     * to reflect the new load.  Call this instead of WebView.loadUrl
363392472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins     * directly.
363492472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins     * @param view The WebView used to load url.
363592472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins     * @param url The URL to load.
363692472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins     */
363792472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins    private void loadUrl(WebView view, String url) {
363892472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins        updateTitleBarForNewLoad(view, url);
363992472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins        view.loadUrl(url);
364092472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins    }
364192472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins
364292472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins    /**
364392472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins     * Load UrlData into a Tab and update the title bar to reflect the new
364492472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins     * load.  Call this instead of UrlData.loadIn directly.
364592472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins     * @param t The Tab used to load.
364692472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins     * @param data The UrlData being loaded.
364792472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins     */
364892472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins    private void loadUrlDataIn(Tab t, UrlData data) {
364992472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins        updateTitleBarForNewLoad(t.getWebView(), data.mUrl);
365092472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins        data.loadIn(t);
365192472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins    }
365292472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins
365392472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins    /**
365492472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins     * If the WebView is the top window, update the title bar to reflect
365592472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins     * loading the new URL.  i.e. set its text, clear the favicon (which
365692472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins     * will be set once the page begins loading), and set the progress to
365792472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins     * INITIAL_PROGRESS to show that the page has begun to load. Called
365892472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins     * by loadUrl and loadUrlDataIn.
365992472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins     * @param view The WebView that is starting a load.
366092472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins     * @param url The URL that is being loaded.
366192472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins     */
366292472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins    private void updateTitleBarForNewLoad(WebView view, String url) {
366392472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins        if (view == getTopWindow()) {
366492472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins            setUrlTitle(url, null);
366592472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins            setFavicon(null);
366692472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins            onProgressChanged(view, INITIAL_PROGRESS);
366792472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins        }
366892472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins    }
366992472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins
36700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private String smartUrlFilter(Uri inUri) {
36710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (inUri != null) {
36720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return smartUrlFilter(inUri.toString());
36730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
36740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return null;
36750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
36760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
3677b34f87a2e13af13d697130482af01b537ab7c5fdFeng Qian    protected static final Pattern ACCEPTED_URI_SCHEMA = Pattern.compile(
36780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            "(?i)" + // switch on case insensitive matching
36790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            "(" +    // begin group for schema
36800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            "(?:http|https|file):\\/\\/" +
368125ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima            "|(?:inline|data|about|content|javascript):" +
36820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ")" +
36830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            "(.*)" );
36840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
36850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
36860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Attempts to determine whether user input is a URL or search
36870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * terms.  Anything with a space is passed to search.
36880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *
36890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Converts to lowercase any mistakenly uppercased schema (i.e.,
36900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * "Http://" converts to "http://"
36910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *
36920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @return Original or modified URL
36930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *
36940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
36950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    String smartUrlFilter(String url) {
36960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
36970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String inUrl = url.trim();
36980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        boolean hasSpace = inUrl.indexOf(' ') != -1;
36990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
37000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        Matcher matcher = ACCEPTED_URI_SCHEMA.matcher(inUrl);
37010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (matcher.matches()) {
37020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // force scheme to lowercase
37030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            String scheme = matcher.group(1);
37040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            String lcScheme = scheme.toLowerCase();
37050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (!lcScheme.equals(scheme)) {
3706123ecfb21e7ca670e3d04efe58780b3bac54a9a1Mitsuru Oshima                inUrl = lcScheme + matcher.group(2);
3707123ecfb21e7ca670e3d04efe58780b3bac54a9a1Mitsuru Oshima            }
3708123ecfb21e7ca670e3d04efe58780b3bac54a9a1Mitsuru Oshima            if (hasSpace) {
3709123ecfb21e7ca670e3d04efe58780b3bac54a9a1Mitsuru Oshima                inUrl = inUrl.replace(" ", "%20");
37100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
37110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return inUrl;
37120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
37130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (hasSpace) {
3714565505b1a2c1d3099496af5910760087602e994aSatish Sampath            // FIXME: Is this the correct place to add to searches?
3715565505b1a2c1d3099496af5910760087602e994aSatish Sampath            // what if someone else calls this function?
3716565505b1a2c1d3099496af5910760087602e994aSatish Sampath            int shortcut = parseUrlShortcut(inUrl);
3717565505b1a2c1d3099496af5910760087602e994aSatish Sampath            if (shortcut != SHORTCUT_INVALID) {
3718565505b1a2c1d3099496af5910760087602e994aSatish Sampath                Browser.addSearchUrl(mResolver, inUrl);
3719565505b1a2c1d3099496af5910760087602e994aSatish Sampath                String query = inUrl.substring(2);
3720565505b1a2c1d3099496af5910760087602e994aSatish Sampath                switch (shortcut) {
3721565505b1a2c1d3099496af5910760087602e994aSatish Sampath                case SHORTCUT_GOOGLE_SEARCH:
372247fdfdb989ffb79590a39c40792be995de32e521Grace Kloba                    return URLUtil.composeSearchUrl(query, QuickSearch_G, QUERY_PLACE_HOLDER);
3723565505b1a2c1d3099496af5910760087602e994aSatish Sampath                case SHORTCUT_WIKIPEDIA_SEARCH:
3724565505b1a2c1d3099496af5910760087602e994aSatish Sampath                    return URLUtil.composeSearchUrl(query, QuickSearch_W, QUERY_PLACE_HOLDER);
3725565505b1a2c1d3099496af5910760087602e994aSatish Sampath                case SHORTCUT_DICTIONARY_SEARCH:
3726565505b1a2c1d3099496af5910760087602e994aSatish Sampath                    return URLUtil.composeSearchUrl(query, QuickSearch_D, QUERY_PLACE_HOLDER);
3727565505b1a2c1d3099496af5910760087602e994aSatish Sampath                case SHORTCUT_GOOGLE_MOBILE_LOCAL_SEARCH:
37280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // FIXME: we need location in this case
3729565505b1a2c1d3099496af5910760087602e994aSatish Sampath                    return URLUtil.composeSearchUrl(query, QuickSearch_L, QUERY_PLACE_HOLDER);
37300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
37310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
37320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
37335ee906c089567bca705e18561357510d7b55cb5aDan Egnor            if (Patterns.WEB_URL.matcher(inUrl).matches()) {
37340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                return URLUtil.guessUrl(inUrl);
37350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
37360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
37370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
37380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        Browser.addSearchUrl(mResolver, inUrl);
373947fdfdb989ffb79590a39c40792be995de32e521Grace Kloba        return URLUtil.composeSearchUrl(inUrl, QuickSearch_G, QUERY_PLACE_HOLDER);
37400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
37410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
3742bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch    /* package */ void setShouldShowErrorConsole(boolean flag) {
3743bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch        if (flag == mShouldShowErrorConsole) {
3744bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch            // Nothing to do.
3745bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch            return;
3746bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch        }
3747a9e35b6e3101fafb07e6bb4282e7dfc4dcfdc193Leon Scroggins III        Tab t = mTabControl.getCurrentTab();
3748a9e35b6e3101fafb07e6bb4282e7dfc4dcfdc193Leon Scroggins III        if (t == null) {
3749a9e35b6e3101fafb07e6bb4282e7dfc4dcfdc193Leon Scroggins III            // There is no current tab so we cannot toggle the error console
3750a9e35b6e3101fafb07e6bb4282e7dfc4dcfdc193Leon Scroggins III            return;
3751a9e35b6e3101fafb07e6bb4282e7dfc4dcfdc193Leon Scroggins III        }
3752bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch
3753bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch        mShouldShowErrorConsole = flag;
3754bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch
3755a9e35b6e3101fafb07e6bb4282e7dfc4dcfdc193Leon Scroggins III        ErrorConsoleView errorConsole = t.getErrorConsole(true);
3756bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch
3757bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch        if (flag) {
3758bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch            // Setting the show state of the console will cause it's the layout to be inflated.
3759bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch            if (errorConsole.numberOfErrors() > 0) {
3760bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch                errorConsole.showConsole(ErrorConsoleView.SHOW_MINIMIZED);
3761bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch            } else {
3762bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch                errorConsole.showConsole(ErrorConsoleView.SHOW_NONE);
3763bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch            }
3764bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch
3765bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch            // Now we can add it to the main view.
3766bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch            mErrorConsoleContainer.addView(errorConsole,
376715b8ec6b226f4d57307716e1f495e10a91f8cbf4Romain Guy                    new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
3768bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch                                                  ViewGroup.LayoutParams.WRAP_CONTENT));
3769bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch        } else {
3770bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch            mErrorConsoleContainer.removeView(errorConsole);
3771bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch        }
3772bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch
3773bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch    }
3774bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch
377522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    boolean shouldShowErrorConsole() {
377622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return mShouldShowErrorConsole;
377722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
377822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
3779163ab74e2f85b53a1a374c49677073fb64d35f28Andrei Popescu    private void setStatusBarVisibility(boolean visible) {
3780163ab74e2f85b53a1a374c49677073fb64d35f28Andrei Popescu        int flag = visible ? 0 : WindowManager.LayoutParams.FLAG_FULLSCREEN;
3781163ab74e2f85b53a1a374c49677073fb64d35f28Andrei Popescu        getWindow().setFlags(flag, WindowManager.LayoutParams.FLAG_FULLSCREEN);
3782163ab74e2f85b53a1a374c49677073fb64d35f28Andrei Popescu    }
3783163ab74e2f85b53a1a374c49677073fb64d35f28Andrei Popescu
378456199cc25e7ee0455ec2a8099098b66b8554f677Andrei Popescu
378556199cc25e7ee0455ec2a8099098b66b8554f677Andrei Popescu    private void sendNetworkType(String type, String subtype) {
378656199cc25e7ee0455ec2a8099098b66b8554f677Andrei Popescu        WebView w = mTabControl.getCurrentWebView();
378756199cc25e7ee0455ec2a8099098b66b8554f677Andrei Popescu        if (w != null) {
378856199cc25e7ee0455ec2a8099098b66b8554f677Andrei Popescu            w.setNetworkType(type, subtype);
378956199cc25e7ee0455ec2a8099098b66b8554f677Andrei Popescu        }
379056199cc25e7ee0455ec2a8099098b66b8554f677Andrei Popescu    }
379156199cc25e7ee0455ec2a8099098b66b8554f677Andrei Popescu
379230995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu    private void packageChanged(String packageName, boolean wasAdded) {
379330995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu        WebView w = mTabControl.getCurrentWebView();
379430995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu        if (w == null) {
379530995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu            return;
379630995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu        }
379730995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu
379830995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu        if (wasAdded) {
379930995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu            w.addPackageName(packageName);
380030995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu        } else {
380130995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu            w.removePackageName(packageName);
380230995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu        }
380330995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu    }
380430995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu
380530995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu    private void addPackageNames(Set<String> packageNames) {
380630995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu        WebView w = mTabControl.getCurrentWebView();
380730995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu        if (w == null) {
380830995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu            return;
380930995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu        }
381030995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu
381130995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu        w.addPackageNames(packageNames);
381230995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu    }
381330995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu
381430995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu    private void getInstalledPackages() {
381530995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu        AsyncTask<Void, Void, Set<String> > task =
381630995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu            new AsyncTask<Void, Void, Set<String> >() {
381730995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu            protected Set<String> doInBackground(Void... unused) {
381830995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu                Set<String> installedPackages = new HashSet<String>();
381930995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu                PackageManager pm = BrowserActivity.this.getPackageManager();
382030995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu                if (pm != null) {
382130995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu                    List<PackageInfo> packages = pm.getInstalledPackages(0);
382230995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu                    for (PackageInfo p : packages) {
382330995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu                        if (BrowserActivity.this.sGoogleApps.contains(p.packageName)) {
382430995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu                            installedPackages.add(p.packageName);
382530995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu                        }
382630995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu                    }
382730995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu                }
382830995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu
382930995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu                return installedPackages;
383030995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu            }
383130995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu
383230995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu            // Executes on the UI thread
383330995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu            protected void onPostExecute(Set<String> installedPackages) {
383430995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu                addPackageNames(installedPackages);
383530995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu            }
383630995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu        };
383730995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu        task.execute();
383830995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu    }
383930995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu
3840eb6eef4c45df2d65c3e70660493a147a2be405e3Grace Kloba    final static int LOCK_ICON_UNSECURE = 0;
3841eb6eef4c45df2d65c3e70660493a147a2be405e3Grace Kloba    final static int LOCK_ICON_SECURE   = 1;
3842eb6eef4c45df2d65c3e70660493a147a2be405e3Grace Kloba    final static int LOCK_ICON_MIXED    = 2;
38430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
38440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private BrowserSettings mSettings;
38450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private TabControl      mTabControl;
38460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private ContentResolver mResolver;
38470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private FrameLayout     mContentView;
3848adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu    private View            mCustomView;
3849adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu    private FrameLayout     mCustomViewContainer;
3850c9b5556351b59caec77b4eec1ad30652fec6a4d9Andrei Popescu    private WebChromeClient.CustomViewCallback mCustomViewCallback;
38510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
38520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // FIXME, temp address onPrepareMenu performance problem. When we move everything out of
38530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // view, we should rewrite this.
38540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private int mCurrentMenuState = 0;
38550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private int mMenuState = R.id.MAIN_MENU;
3856adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu    private int mOldMenuState = EMPTY_MENU;
38570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private static final int EMPTY_MENU = -1;
38580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private Menu mMenu;
38590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
38600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private FindDialog mFindDialog;
38612c326e62316884a20822035c5470168d0e3b89ffCary Clark    private SelectDialog mSelectDialog;
38620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Used to prevent chording to result in firing two shortcuts immediately
38630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // one after another.  Fixes bug 1211714.
38640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    boolean mCanChord;
38650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
38660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private boolean mInLoad;
38670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private boolean mIsNetworkUp;
3868b7cc8b439dc595dc48e1c2183b35d23ad72dfbe5Ben Murdoch    private boolean mDidStopLoad;
38690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
38701f10cbfca5bf96e1466e0ed3ce1dbcd6fcfd0608Cary Clark    /* package */ boolean mActivityInPause = true;
38710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
38720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private boolean mMenuIsDown;
38730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
38740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private static boolean mInTrace;
38750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
38760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Performance probe
38770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private static final int[] SYSTEM_CPU_FORMAT = new int[] {
38780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Process.PROC_SPACE_TERM | Process.PROC_COMBINE,
38790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Process.PROC_SPACE_TERM | Process.PROC_OUT_LONG, // 1: user time
38800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Process.PROC_SPACE_TERM | Process.PROC_OUT_LONG, // 2: nice time
38810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Process.PROC_SPACE_TERM | Process.PROC_OUT_LONG, // 3: sys time
38820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Process.PROC_SPACE_TERM | Process.PROC_OUT_LONG, // 4: idle time
38830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Process.PROC_SPACE_TERM | Process.PROC_OUT_LONG, // 5: iowait time
38840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Process.PROC_SPACE_TERM | Process.PROC_OUT_LONG, // 6: irq time
38850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Process.PROC_SPACE_TERM | Process.PROC_OUT_LONG  // 7: softirq time
38860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    };
38870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
38880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private long mStart;
38890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private long mProcessStart;
38900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private long mUserStart;
38910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private long mSystemStart;
38920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private long mIdleStart;
38930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private long mIrqStart;
38940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
38950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private long mUiStart;
38960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
38970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private Drawable    mMixLockIcon;
38980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private Drawable    mSecLockIcon;
38990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
39000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /* hold a ref so we can auto-cancel if necessary */
39010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private AlertDialog mAlertDialog;
39020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
39030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // The up-to-date URL and title (these can be different from those stored
39040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // in WebView, since it takes some time for the information in WebView to
39050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // get updated)
39060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private String mUrl;
39070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private String mTitle;
39080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
39090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // As PageInfo has different style for landscape / portrait, we have
39100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // to re-open it when configuration changed
39110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private AlertDialog mPageInfoDialog;
391222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private Tab mPageInfoView;
39130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // If the Page-Info dialog is launched from the SSL-certificate-on-error
39140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // dialog, we should not just dismiss it, but should get back to the
39150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // SSL-certificate-on-error dialog. This flag is used to store this state
3916c7b92f811dfa3572578ddc6714c98a03936d9ce5Leon Scroggins    private boolean mPageInfoFromShowSSLCertificateOnError;
39170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
39180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // as SSLCertificateOnError has different style for landscape / portrait,
39190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // we have to re-open it when configuration changed
39200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private AlertDialog mSSLCertificateOnErrorDialog;
39210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private WebView mSSLCertificateOnErrorView;
39220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private SslErrorHandler mSSLCertificateOnErrorHandler;
39230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private SslError mSSLCertificateOnErrorError;
39240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
39250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // as SSLCertificate has different style for landscape / portrait, we
39260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // have to re-open it when configuration changed
39270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private AlertDialog mSSLCertificateDialog;
392822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private Tab mSSLCertificateView;
39290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
39300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // as HttpAuthentication has different style for landscape / portrait, we
39310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // have to re-open it when configuration changed
39320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private AlertDialog mHttpAuthenticationDialog;
39330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private HttpAuthHandler mHttpAuthHandler;
39340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
39350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /*package*/ static final FrameLayout.LayoutParams COVER_SCREEN_PARAMS =
39360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                            new FrameLayout.LayoutParams(
393715b8ec6b226f4d57307716e1f495e10a91f8cbf4Romain Guy                                            ViewGroup.LayoutParams.MATCH_PARENT,
393815b8ec6b226f4d57307716e1f495e10a91f8cbf4Romain Guy                                            ViewGroup.LayoutParams.MATCH_PARENT);
3939adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu    /*package*/ static final FrameLayout.LayoutParams COVER_SCREEN_GRAVITY_CENTER =
3940adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu                                            new FrameLayout.LayoutParams(
394115b8ec6b226f4d57307716e1f495e10a91f8cbf4Romain Guy                                            ViewGroup.LayoutParams.MATCH_PARENT,
394215b8ec6b226f4d57307716e1f495e10a91f8cbf4Romain Guy                                            ViewGroup.LayoutParams.MATCH_PARENT,
3943adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu                                            Gravity.CENTER);
394447fdfdb989ffb79590a39c40792be995de32e521Grace Kloba    // Google search
394547fdfdb989ffb79590a39c40792be995de32e521Grace Kloba    final static String QuickSearch_G = "http://www.google.com/m?q=%s";
39460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Wikipedia search
39470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    final static String QuickSearch_W = "http://en.wikipedia.org/w/index.php?search=%s&go=Go";
39480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Dictionary search
39490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    final static String QuickSearch_D = "http://dictionary.reference.com/search?q=%s";
39500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Google Mobile Local search
39510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    final static String QuickSearch_L = "http://www.google.com/m/search?site=local&q=%s&near=mountain+view";
39520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
39530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    final static String QUERY_PLACE_HOLDER = "%s";
39540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
39550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // "source" parameter for Google search through search key
39560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    final static String GOOGLE_SEARCH_SOURCE_SEARCHKEY = "browser-key";
39570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // "source" parameter for Google search through goto menu
39580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    final static String GOOGLE_SEARCH_SOURCE_GOTO = "browser-goto";
39590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // "source" parameter for Google search through simplily type
39600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    final static String GOOGLE_SEARCH_SOURCE_TYPE = "browser-type";
39610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // "source" parameter for Google search suggested by the browser
39620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    final static String GOOGLE_SEARCH_SOURCE_SUGGEST = "browser-suggest";
39630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // "source" parameter for Google search from unknown source
39640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    final static String GOOGLE_SEARCH_SOURCE_UNKNOWN = "unknown";
39650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
39660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private final static String LOGTAG = "browser";
39670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
39680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private String mLastEnteredUrl;
39690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
39700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private PowerManager.WakeLock mWakeLock;
39710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private final static int WAKELOCK_TIMEOUT = 5 * 60 * 1000; // 5 minutes
39720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
39730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private Toast mStopToast;
39740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
397568579393973f745fc65a2781061af9bb8f2d7020Leon Scroggins    private TitleBar mTitleBar;
397681db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins
3977bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch    private LinearLayout mErrorConsoleContainer = null;
3978bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch    private boolean mShouldShowErrorConsole = false;
3979bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch
39800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // As the ids are dynamically created, we can't guarantee that they will
39810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // be in sequence, so this static array maps ids to a window number.
39820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    final static private int[] WINDOW_SHORTCUT_ID_ARRAY =
39830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    { R.id.window_one_menu_id, R.id.window_two_menu_id, R.id.window_three_menu_id,
39840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project      R.id.window_four_menu_id, R.id.window_five_menu_id, R.id.window_six_menu_id,
39850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project      R.id.window_seven_menu_id, R.id.window_eight_menu_id };
39860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
39870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // monitor platform changes
39880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private IntentFilter mNetworkStateChangedFilter;
39890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private BroadcastReceiver mNetworkStateIntentReceiver;
39900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
3991b4da0ad0351996f639b50f9f29b123a9b5c24fd0Grace Kloba    private BroadcastReceiver mPackageInstallationReceiver;
3992b4da0ad0351996f639b50f9f29b123a9b5c24fd0Grace Kloba
3993a7611811e0d744a7220b7bf80c8f795af5ea53edBjorn Bringert    private SystemAllowGeolocationOrigins mSystemAllowGeolocationOrigins;
3994a7611811e0d744a7220b7bf80c8f795af5ea53edBjorn Bringert
39950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // activity requestCode
399678a98e459323f938e97789a6131beddbebb459ceNicolas Roard    final static int COMBO_PAGE                 = 1;
399778a98e459323f938e97789a6131beddbebb459ceNicolas Roard    final static int DOWNLOAD_PAGE              = 2;
399878a98e459323f938e97789a6131beddbebb459ceNicolas Roard    final static int PREFERENCES_PAGE           = 3;
39998d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins    final static int FILE_SELECTED              = 4;
40000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
4001540035dfd1347c78eeec10ec0847e18fcc50ef36Andrei Popescu    // the default <video> poster
4002540035dfd1347c78eeec10ec0847e18fcc50ef36Andrei Popescu    private Bitmap mDefaultVideoPoster;
4003540035dfd1347c78eeec10ec0847e18fcc50ef36Andrei Popescu    // the video progress view
4004540035dfd1347c78eeec10ec0847e18fcc50ef36Andrei Popescu    private View mVideoProgressView;
4005540035dfd1347c78eeec10ec0847e18fcc50ef36Andrei Popescu
400630995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu    // The Google packages we monitor for the navigator.isApplicationInstalled()
400730995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu    // API. Add as needed.
400830995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu    private static Set<String> sGoogleApps;
400930995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu    static {
401030995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu        sGoogleApps = new HashSet<String>();
401130995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu        sGoogleApps.add("com.google.android.youtube");
401230995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu    }
401330995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu
401425ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima    /**
401525ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima     * A UrlData class to abstract how the content will be set to WebView.
401625ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima     * This base class uses loadUrl to show the content.
401725ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima     */
40186eac63e78d43d04e31c4d16830c44c4d9df82639Leon Scroggins    /* package */ static class UrlData {
4019068e48b469f5abca53ee3da38f933cf2c25c93b8Grace Kloba        final String mUrl;
4020068e48b469f5abca53ee3da38f933cf2c25c93b8Grace Kloba        final Map<String, String> mHeaders;
402158d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        final Intent mVoiceIntent;
402260e095c190496d42327f8ec2ef990c044d15a76fGrace Kloba
402325ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima        UrlData(String url) {
402425ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima            this.mUrl = url;
4025068e48b469f5abca53ee3da38f933cf2c25c93b8Grace Kloba            this.mHeaders = null;
402658d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins            this.mVoiceIntent = null;
402725ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima        }
402860e095c190496d42327f8ec2ef990c044d15a76fGrace Kloba
402958d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        UrlData(String url, Map<String, String> headers, Intent intent) {
4030068e48b469f5abca53ee3da38f933cf2c25c93b8Grace Kloba            this.mUrl = url;
4031068e48b469f5abca53ee3da38f933cf2c25c93b8Grace Kloba            this.mHeaders = headers;
4032a1cc3fdce19a336c251297c61cd83ac6cf767cd1Leon Scroggins            if (RecognizerResultsIntent.ACTION_VOICE_SEARCH_RESULTS
4033a1cc3fdce19a336c251297c61cd83ac6cf767cd1Leon Scroggins                    .equals(intent.getAction())) {
403458d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins                this.mVoiceIntent = intent;
403558d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins            } else {
403658d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins                this.mVoiceIntent = null;
403758d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins            }
403860e095c190496d42327f8ec2ef990c044d15a76fGrace Kloba        }
403960e095c190496d42327f8ec2ef990c044d15a76fGrace Kloba
404025ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima        boolean isEmpty() {
404158d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins            return mVoiceIntent == null && (mUrl == null || mUrl.length() == 0);
404225ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima        }
404325ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima
404492472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins        /**
404592472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins         * Load this UrlData into the given Tab.  Use loadUrlDataIn to update
404692472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins         * the title bar as well.
404792472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins         */
404858d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        public void loadIn(Tab t) {
404958d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins            if (mVoiceIntent != null) {
405058d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins                t.activateVoiceSearchMode(mVoiceIntent);
405158d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins            } else {
405258d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins                t.getWebView().loadUrl(mUrl, mHeaders);
405358d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins            }
405425ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima        }
405525ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima    };
405625ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima
40571f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins    /* package */ static final UrlData EMPTY_URL_DATA = new UrlData(null);
40580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project}
4059