BrowserActivity.java revision 79e36d97b67bf06b1e0c0edf773882e93a3293e4
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
11410d1cca0c208d1f9db23893a8515685e04cfe224Bjorn Bringertimport com.android.common.Search;
1151fe13a5230e319df42b21939a14d127bd9bf3856Leon Scrogginsimport com.android.common.speech.LoggingEvents;
1165ee906c089567bca705e18561357510d7b55cb5aDan Egnor
117b6b7f9ef3b4ed220063f555d8b7c205210a61a04Leon Scrogginsimport java.io.ByteArrayOutputStream;
1180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport java.io.File;
1194f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdochimport java.io.IOException;
1204f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdochimport java.io.InputStream;
1210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport java.net.MalformedURLException;
1220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport java.net.URI;
1239918943559193e3e047a1c18442e2cdb0fe22b15Dianne Hackbornimport java.net.URISyntaxException;
1240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport java.net.URL;
1250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport java.net.URLEncoder;
1260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport java.text.ParseException;
1270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport java.util.Date;
1280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport java.util.HashMap;
12930995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescuimport java.util.HashSet;
13000f54c589fd38431efd42ea2a551a49e64d595d5Grace Klobaimport java.util.Iterator;
13130995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescuimport java.util.List;
132068e48b469f5abca53ee3da38f933cf2c25c93b8Grace Klobaimport java.util.Map;
13330995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescuimport java.util.Set;
1340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport java.util.regex.Matcher;
1350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport java.util.regex.Pattern;
1360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
1370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectpublic class BrowserActivity extends Activity
13898d5fce7c687cfcc956b10d44946d31f39b6dc15Shimeng (Simon) Wang    implements View.OnCreateContextMenuListener, DownloadListener {
1390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
14031a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort    /* Define some aliases to make these debugging flags easier to refer to.
14131a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort     * This file imports android.provider.Browser, so we can't just refer to "Browser.DEBUG".
14231a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort     */
14331a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort    private final static boolean DEBUG = com.android.browser.Browser.DEBUG;
14431a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort    private final static boolean LOGV_ENABLED = com.android.browser.Browser.LOGV_ENABLED;
14531a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort    private final static boolean LOGD_ENABLED = com.android.browser.Browser.LOGD_ENABLED;
14631a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort
147565505b1a2c1d3099496af5910760087602e994aSatish Sampath    // These are single-character shortcuts for searching popular sources.
148565505b1a2c1d3099496af5910760087602e994aSatish Sampath    private static final int SHORTCUT_INVALID = 0;
149565505b1a2c1d3099496af5910760087602e994aSatish Sampath    private static final int SHORTCUT_GOOGLE_SEARCH = 1;
150565505b1a2c1d3099496af5910760087602e994aSatish Sampath    private static final int SHORTCUT_WIKIPEDIA_SEARCH = 2;
151565505b1a2c1d3099496af5910760087602e994aSatish Sampath    private static final int SHORTCUT_DICTIONARY_SEARCH = 3;
152565505b1a2c1d3099496af5910760087602e994aSatish Sampath    private static final int SHORTCUT_GOOGLE_MOBILE_LOCAL_SEARCH = 4;
153565505b1a2c1d3099496af5910760087602e994aSatish Sampath
154a977124eb29b195127fd161120ebbc58b255fb48Cary Clark    private static class ClearThumbnails extends AsyncTask<File, Void, Void> {
1550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        @Override
1560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public Void doInBackground(File... files) {
1570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (files != null) {
1580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                for (File f : files) {
159d6be1758b38d5b066ff10b6af906aa66c63670cdCary Clark                    if (!f.delete()) {
160d6be1758b38d5b066ff10b6af906aa66c63670cdCary Clark                      Log.e(LOGTAG, f.getPath() + " was not deleted");
161d6be1758b38d5b066ff10b6af906aa66c63670cdCary Clark                    }
1620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
1630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
1640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return null;
1650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
1660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
1670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
1683bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    /**
1693bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     * This layout holds everything you see below the status bar, including the
1703bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     * error console, the custom view container, and the webviews.
1713bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     */
1723bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    private FrameLayout mBrowserFrameLayout;
17381db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins
17422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    @Override
17522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    public void onCreate(Bundle icicle) {
17631a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort        if (LOGV_ENABLED) {
1770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Log.v(LOGTAG, this + " onStart");
1780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
1790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        super.onCreate(icicle);
1800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // test the browser in OpenGL
1810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // requestWindowFeature(Window.FEATURE_OPENGL);
1820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
183d334bf564b72416e77e707d25f8c55cfe1d85709Mike Reed        // enable this to test the browser in 32bit
184d334bf564b72416e77e707d25f8c55cfe1d85709Mike Reed        if (false) {
185d334bf564b72416e77e707d25f8c55cfe1d85709Mike Reed            getWindow().setFormat(PixelFormat.RGBX_8888);
186d334bf564b72416e77e707d25f8c55cfe1d85709Mike Reed            BitmapFactory.setDefaultConfig(Bitmap.Config.ARGB_8888);
187d334bf564b72416e77e707d25f8c55cfe1d85709Mike Reed        }
188d334bf564b72416e77e707d25f8c55cfe1d85709Mike Reed
1890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        setDefaultKeyMode(DEFAULT_KEYS_SEARCH_LOCAL);
1900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
1910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mResolver = getContentResolver();
1920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
1930923d69a8ca45222cabd82a80eaa88da9f132e9aGrace Kloba        // If this was a web search request, pass it on to the default web
1940923d69a8ca45222cabd82a80eaa88da9f132e9aGrace Kloba        // search provider and finish this activity.
1950923d69a8ca45222cabd82a80eaa88da9f132e9aGrace Kloba        if (handleWebSearchIntent(getIntent())) {
1960923d69a8ca45222cabd82a80eaa88da9f132e9aGrace Kloba            finish();
1970923d69a8ca45222cabd82a80eaa88da9f132e9aGrace Kloba            return;
1980923d69a8ca45222cabd82a80eaa88da9f132e9aGrace Kloba        }
1990923d69a8ca45222cabd82a80eaa88da9f132e9aGrace Kloba
2000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mSecLockIcon = Resources.getSystem().getDrawable(
2010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                android.R.drawable.ic_secure);
2020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mMixLockIcon = Resources.getSystem().getDrawable(
2030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                android.R.drawable.ic_partial_secure);
2040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
20581db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins        FrameLayout frameLayout = (FrameLayout) getWindow().getDecorView()
20681db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins                .findViewById(com.android.internal.R.id.content);
2073bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins        mBrowserFrameLayout = (FrameLayout) LayoutInflater.from(this)
2083bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                .inflate(R.layout.custom_screen, null);
2093bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins        mContentView = (FrameLayout) mBrowserFrameLayout.findViewById(
2103bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                R.id.main_content);
2113bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins        mErrorConsoleContainer = (LinearLayout) mBrowserFrameLayout
2123bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                .findViewById(R.id.error_console);
2133bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins        mCustomViewContainer = (FrameLayout) mBrowserFrameLayout
2143bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                .findViewById(R.id.fullscreen_custom_content);
2153bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins        frameLayout.addView(mBrowserFrameLayout, COVER_SCREEN_PARAMS);
21668579393973f745fc65a2781061af9bb8f2d7020Leon Scroggins        mTitleBar = new TitleBar(this);
2171542f74d866056aac0cc5ffc328940a4b8ba626cGrace Kloba        // mTitleBar will be always shown in the fully loaded mode
2181542f74d866056aac0cc5ffc328940a4b8ba626cGrace Kloba        mTitleBar.setProgress(100);
219fe87bd3a3897e4bad65bb3d284659ae2f4e57570Leon Scroggins        mFakeTitleBar = new TitleBar(this);
2200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
2210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Create the tab control and our initial tab
2220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mTabControl = new TabControl(this);
2230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
2240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Open the icon database and retain all the bookmark urls for favicons
2250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        retainIconsOnStartup();
2260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
2270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Keep a settings instance handy.
2280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mSettings = BrowserSettings.getInstance();
2290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mSettings.setTabControl(mTabControl);
2300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
2310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
2320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "Browser");
2330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
2346adacc90222a3293bc631ef88ee5613e23b2d4c0Patrick Scott        // Find out if the network is currently up.
2356adacc90222a3293bc631ef88ee5613e23b2d4c0Patrick Scott        ConnectivityManager cm = (ConnectivityManager) getSystemService(
2366adacc90222a3293bc631ef88ee5613e23b2d4c0Patrick Scott                Context.CONNECTIVITY_SERVICE);
2376adacc90222a3293bc631ef88ee5613e23b2d4c0Patrick Scott        NetworkInfo info = cm.getActiveNetworkInfo();
2386adacc90222a3293bc631ef88ee5613e23b2d4c0Patrick Scott        if (info != null) {
2396adacc90222a3293bc631ef88ee5613e23b2d4c0Patrick Scott            mIsNetworkUp = info.isAvailable();
2406adacc90222a3293bc631ef88ee5613e23b2d4c0Patrick Scott        }
2416adacc90222a3293bc631ef88ee5613e23b2d4c0Patrick Scott
242a34f686112fb4f9fbea00b8c2c47153d34e93e41Grace Kloba        /* enables registration for changes in network status from
243a34f686112fb4f9fbea00b8c2c47153d34e93e41Grace Kloba           http stack */
244a34f686112fb4f9fbea00b8c2c47153d34e93e41Grace Kloba        mNetworkStateChangedFilter = new IntentFilter();
245a34f686112fb4f9fbea00b8c2c47153d34e93e41Grace Kloba        mNetworkStateChangedFilter.addAction(
246a34f686112fb4f9fbea00b8c2c47153d34e93e41Grace Kloba                ConnectivityManager.CONNECTIVITY_ACTION);
247a34f686112fb4f9fbea00b8c2c47153d34e93e41Grace Kloba        mNetworkStateIntentReceiver = new BroadcastReceiver() {
248a34f686112fb4f9fbea00b8c2c47153d34e93e41Grace Kloba                @Override
249a34f686112fb4f9fbea00b8c2c47153d34e93e41Grace Kloba                public void onReceive(Context context, Intent intent) {
250a34f686112fb4f9fbea00b8c2c47153d34e93e41Grace Kloba                    if (intent.getAction().equals(
251a34f686112fb4f9fbea00b8c2c47153d34e93e41Grace Kloba                            ConnectivityManager.CONNECTIVITY_ACTION)) {
252e4c98469644d3fa2689cf6658b1999add13c7e0eAndrei Popescu
253e4c98469644d3fa2689cf6658b1999add13c7e0eAndrei Popescu                        NetworkInfo info = intent.getParcelableExtra(
254e4c98469644d3fa2689cf6658b1999add13c7e0eAndrei Popescu                                ConnectivityManager.EXTRA_NETWORK_INFO);
255e4c98469644d3fa2689cf6658b1999add13c7e0eAndrei Popescu                        String typeName = info.getTypeName();
256e4c98469644d3fa2689cf6658b1999add13c7e0eAndrei Popescu                        String subtypeName = info.getSubtypeName();
257e4c98469644d3fa2689cf6658b1999add13c7e0eAndrei Popescu                        sendNetworkType(typeName.toLowerCase(),
258e4c98469644d3fa2689cf6658b1999add13c7e0eAndrei Popescu                                (subtypeName != null ? subtypeName.toLowerCase() : ""));
259e4c98469644d3fa2689cf6658b1999add13c7e0eAndrei Popescu
260e4c98469644d3fa2689cf6658b1999add13c7e0eAndrei Popescu                        onNetworkToggle(info.isAvailable());
261a34f686112fb4f9fbea00b8c2c47153d34e93e41Grace Kloba                    }
262a34f686112fb4f9fbea00b8c2c47153d34e93e41Grace Kloba                }
263a34f686112fb4f9fbea00b8c2c47153d34e93e41Grace Kloba            };
264a34f686112fb4f9fbea00b8c2c47153d34e93e41Grace Kloba
265615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba        IntentFilter filter = new IntentFilter(Intent.ACTION_PACKAGE_ADDED);
266615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba        filter.addAction(Intent.ACTION_PACKAGE_REMOVED);
267615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba        filter.addDataScheme("package");
268615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba        mPackageInstallationReceiver = new BroadcastReceiver() {
269615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba            @Override
270615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba            public void onReceive(Context context, Intent intent) {
271615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                final String action = intent.getAction();
272615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                final String packageName = intent.getData()
273615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                        .getSchemeSpecificPart();
274615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                final boolean replacing = intent.getBooleanExtra(
275615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                        Intent.EXTRA_REPLACING, false);
276615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                if (Intent.ACTION_PACKAGE_REMOVED.equals(action) && replacing) {
277615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                    // if it is replacing, refreshPlugins() when adding
278615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                    return;
279615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                }
28030995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu
28130995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu                if (sGoogleApps.contains(packageName)) {
28230995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu                    BrowserActivity.this.packageChanged(packageName,
28330995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu                            Intent.ACTION_PACKAGE_ADDED.equals(action));
28430995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu                }
28530995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu
286615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                PackageManager pm = BrowserActivity.this.getPackageManager();
287615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                PackageInfo pkgInfo = null;
288615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                try {
289615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                    pkgInfo = pm.getPackageInfo(packageName,
290615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                            PackageManager.GET_PERMISSIONS);
291615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                } catch (PackageManager.NameNotFoundException e) {
292615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                    return;
293615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                }
294615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                if (pkgInfo != null) {
295615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                    String permissions[] = pkgInfo.requestedPermissions;
296615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                    if (permissions == null) {
297615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                        return;
298615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                    }
299615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                    boolean permissionOk = false;
300615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                    for (String permit : permissions) {
301615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                        if (PluginManager.PLUGIN_PERMISSION.equals(permit)) {
302615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                            permissionOk = true;
303615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                            break;
304615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                        }
305615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                    }
306615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                    if (permissionOk) {
307615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                        PluginManager.getInstance(BrowserActivity.this)
308615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                                .refreshPlugins(
309615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                                        Intent.ACTION_PACKAGE_ADDED
310615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                                                .equals(action));
311615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                    }
312615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                }
313615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba            }
314615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba        };
315615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba        registerReceiver(mPackageInstallationReceiver, filter);
316615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba
3170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (!mTabControl.restoreState(icicle)) {
3180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // clear up the thumbnail directory if we can't restore the state as
3190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // none of the files in the directory are referenced any more.
3200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            new ClearThumbnails().execute(
3210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    mTabControl.getThumbnailDir().listFiles());
322aab3f09b5c2d39b19067e57635614080b2403a46Grace Kloba            // there is no quit on Android. But if we can't restore the state,
323aab3f09b5c2d39b19067e57635614080b2403a46Grace Kloba            // we can treat it as a new Browser, remove the old session cookies.
324aab3f09b5c2d39b19067e57635614080b2403a46Grace Kloba            CookieManager.getInstance().removeSessionCookie();
3250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            final Intent intent = getIntent();
3260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            final Bundle extra = intent.getExtras();
3270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Create an initial tab.
3280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // If the intent is ACTION_VIEW and data is not null, the Browser is
3290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // invoked to view the content by another application. In this case,
3300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // the tab will be close when exit.
33125ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima            UrlData urlData = getUrlDataFromIntent(intent);
33225ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima
33358d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins            String action = intent.getAction();
33422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            final Tab t = mTabControl.createNewTab(
33558d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins                    (Intent.ACTION_VIEW.equals(action) &&
33658d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins                    intent.getData() != null)
337a1cc3fdce19a336c251297c61cd83ac6cf767cd1Leon Scroggins                    || RecognizerResultsIntent.ACTION_VOICE_SEARCH_RESULTS
338a1cc3fdce19a336c251297c61cd83ac6cf767cd1Leon Scroggins                    .equals(action),
33925ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima                    intent.getStringExtra(Browser.EXTRA_APPLICATION_ID), urlData.mUrl);
3400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mTabControl.setCurrentTab(t);
3410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            attachTabToContentView(t);
3420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            WebView webView = t.getWebView();
3430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (extra != null) {
3440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                int scale = extra.getInt(Browser.INITIAL_ZOOM_LEVEL, 0);
3450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (scale > 0 && scale <= 1000) {
3460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    webView.setInitialScale(scale);
3470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
3480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
3490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
35025ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima            if (urlData.isEmpty()) {
35198d5fce7c687cfcc956b10d44946d31f39b6dc15Shimeng (Simon) Wang                loadUrl(webView, mSettings.getHomePage());
3520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } else {
3539d53da05812f959745810a33bb4e06b273393c42Patrick Scott                loadUrlDataIn(t, urlData);
3540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
3550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
3560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // TabControl.restoreState() will create a new tab even if
3571f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins            // restoring the state fails.
3580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            attachTabToContentView(mTabControl.getCurrentTab());
3590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
360615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba
361b3c02da4553b1a629b16377970fdabae28394c94Feng Qian        // Read JavaScript flags if it exists.
362b3c02da4553b1a629b16377970fdabae28394c94Feng Qian        String jsFlags = mSettings.getJsFlags();
363b3c02da4553b1a629b16377970fdabae28394c94Feng Qian        if (jsFlags.trim().length() != 0) {
364b3c02da4553b1a629b16377970fdabae28394c94Feng Qian            mTabControl.getCurrentWebView().setJsFlags(jsFlags);
365b3c02da4553b1a629b16377970fdabae28394c94Feng Qian        }
36630995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu        // Work out which packages are installed on the system.
36730995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu        getInstalledPackages();
368a7611811e0d744a7220b7bf80c8f795af5ea53edBjorn Bringert
369a7611811e0d744a7220b7bf80c8f795af5ea53edBjorn Bringert        // Start watching the default geolocation permissions
370a7611811e0d744a7220b7bf80c8f795af5ea53edBjorn Bringert        mSystemAllowGeolocationOrigins
371a7611811e0d744a7220b7bf80c8f795af5ea53edBjorn Bringert                = new SystemAllowGeolocationOrigins(getApplicationContext());
372a7611811e0d744a7220b7bf80c8f795af5ea53edBjorn Bringert        mSystemAllowGeolocationOrigins.start();
3730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
3740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
37558d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    /**
37658d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins     * Feed the previously stored results strings to the BrowserProvider so that
37758d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins     * the SearchDialog will show them instead of the standard searches.
37858d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins     * @param result String to show on the editable line of the SearchDialog.
37958d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins     */
38058d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    /* package */ void showVoiceSearchResults(String result) {
38158d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        ContentProviderClient client = mResolver.acquireContentProviderClient(
38258d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins                Browser.BOOKMARKS_URI);
38358d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        ContentProvider prov = client.getLocalContentProvider();
38458d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        BrowserProvider bp = (BrowserProvider) prov;
38558d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        bp.setQueryResults(mTabControl.getCurrentTab().getVoiceSearchResults());
38658d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        client.release();
38758d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins
388fbb3f15f725e890837431f402b43e802045a4f3fLeon Scroggins        Bundle bundle = createGoogleSearchSourceBundle(
389fbb3f15f725e890837431f402b43e802045a4f3fLeon Scroggins                GOOGLE_SEARCH_SOURCE_SEARCHKEY);
390fbb3f15f725e890837431f402b43e802045a4f3fLeon Scroggins        bundle.putBoolean(SearchManager.CONTEXT_IS_VOICE, true);
391fbb3f15f725e890837431f402b43e802045a4f3fLeon Scroggins        startSearch(result, false, bundle, false);
39258d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    }
39358d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins
3940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    @Override
3950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    protected void onNewIntent(Intent intent) {
39622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        Tab current = mTabControl.getCurrentTab();
3970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // When a tab is closed on exit, the current tab index is set to -1.
3980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Reset before proceed as Browser requires the current tab to be set.
3990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (current == null) {
4000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Try to reset the tab in case the index was incorrect.
4010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            current = mTabControl.getTab(0);
4020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (current == null) {
4030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // No tabs at all so just ignore this intent.
4040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                return;
4050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
4060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mTabControl.setCurrentTab(current);
4070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            attachTabToContentView(current);
4080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            resetTitleAndIcon(current.getWebView());
4090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
4100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final String action = intent.getAction();
4110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final int flags = intent.getFlags();
4120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (Intent.ACTION_MAIN.equals(action) ||
4130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                (flags & Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY) != 0) {
4140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // just resume the browser
4150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
4160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
417b8a844da0049965b3cef5739dbab19c7ac766762Leon Scroggins        // In case the SearchDialog is open.
418b8a844da0049965b3cef5739dbab19c7ac766762Leon Scroggins        ((SearchManager) getSystemService(Context.SEARCH_SERVICE))
419b8a844da0049965b3cef5739dbab19c7ac766762Leon Scroggins                .stopSearch();
420a1cc3fdce19a336c251297c61cd83ac6cf767cd1Leon Scroggins        boolean activateVoiceSearch = RecognizerResultsIntent
421a1cc3fdce19a336c251297c61cd83ac6cf767cd1Leon Scroggins                .ACTION_VOICE_SEARCH_RESULTS.equals(action);
4220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (Intent.ACTION_VIEW.equals(action)
4230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                || Intent.ACTION_SEARCH.equals(action)
4240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                || MediaStore.INTENT_ACTION_MEDIA_SEARCH.equals(action)
42558d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins                || Intent.ACTION_WEB_SEARCH.equals(action)
42658d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins                || activateVoiceSearch) {
4273b18ce37c13fce7212948df90a012d7011924a6eLeon Scroggins            if (current.isInVoiceSearchMode()) {
4283b18ce37c13fce7212948df90a012d7011924a6eLeon Scroggins                String title = current.getVoiceDisplayTitle();
4293b18ce37c13fce7212948df90a012d7011924a6eLeon Scroggins                if (title != null && title.equals(intent.getStringExtra(
4303b18ce37c13fce7212948df90a012d7011924a6eLeon Scroggins                        SearchManager.QUERY))) {
4313b18ce37c13fce7212948df90a012d7011924a6eLeon Scroggins                    // The user submitted the same search as the last voice
4323b18ce37c13fce7212948df90a012d7011924a6eLeon Scroggins                    // search, so do nothing.
4333b18ce37c13fce7212948df90a012d7011924a6eLeon Scroggins                    return;
4343b18ce37c13fce7212948df90a012d7011924a6eLeon Scroggins                }
4351fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins                if (Intent.ACTION_SEARCH.equals(action)
4361fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins                        && current.voiceSearchSourceIsGoogle()) {
4371fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins                    Intent logIntent = new Intent(
4381fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins                            LoggingEvents.ACTION_LOG_EVENT);
4391fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins                    logIntent.putExtra(LoggingEvents.EXTRA_EVENT,
4401fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins                            LoggingEvents.VoiceSearch.QUERY_UPDATED);
4411fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins                    logIntent.putExtra(
4421fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins                            LoggingEvents.VoiceSearch.EXTRA_QUERY_UPDATED_VALUE,
4431fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins                            intent.getDataString());
4441fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins                    sendBroadcast(logIntent);
4451fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins                    // Note, onPageStarted will revert the voice title bar
4461fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins                    // When http://b/issue?id=2379215 is fixed, we should update
4471fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins                    // the title bar here.
4481fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins                }
4493b18ce37c13fce7212948df90a012d7011924a6eLeon Scroggins            }
450565505b1a2c1d3099496af5910760087602e994aSatish Sampath            // If this was a search request (e.g. search query directly typed into the address bar),
451565505b1a2c1d3099496af5910760087602e994aSatish Sampath            // pass it on to the default web search provider.
452565505b1a2c1d3099496af5910760087602e994aSatish Sampath            if (handleWebSearchIntent(intent)) {
453565505b1a2c1d3099496af5910760087602e994aSatish Sampath                return;
454565505b1a2c1d3099496af5910760087602e994aSatish Sampath            }
455565505b1a2c1d3099496af5910760087602e994aSatish Sampath
45625ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima            UrlData urlData = getUrlDataFromIntent(intent);
45725ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima            if (urlData.isEmpty()) {
45825ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima                urlData = new UrlData(mSettings.getHomePage());
4590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
46025ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima
461cc63403643786905262f505ab5266d8e80b9924cGrace Kloba            final String appId = intent
462cc63403643786905262f505ab5266d8e80b9924cGrace Kloba                    .getStringExtra(Browser.EXTRA_APPLICATION_ID);
4634720868afa09efffadd845019f2d8268ae3f2c78Leon Scroggins            if ((Intent.ACTION_VIEW.equals(action)
4644720868afa09efffadd845019f2d8268ae3f2c78Leon Scroggins                    // If a voice search has no appId, it means that it came
4654720868afa09efffadd845019f2d8268ae3f2c78Leon Scroggins                    // from the browser.  In that case, reuse the current tab.
4664720868afa09efffadd845019f2d8268ae3f2c78Leon Scroggins                    || (activateVoiceSearch && appId != null))
467cc63403643786905262f505ab5266d8e80b9924cGrace Kloba                    && !getPackageName().equals(appId)
468cc63403643786905262f505ab5266d8e80b9924cGrace Kloba                    && (flags & Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT) != 0) {
46922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                Tab appTab = mTabControl.getTabFromId(appId);
470f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                if (appTab != null) {
471f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    Log.i(LOGTAG, "Reusing tab for " + appId);
472f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    // Dismiss the subwindow if applicable.
473f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    dismissSubWindow(appTab);
474f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    // Since we might kill the WebView, remove it from the
475f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    // content view first.
476f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    removeTabFromContentView(appTab);
477f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    // Recreate the main WebView after destroying the old one.
478f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    // If the WebView has the same original url and is on that
479f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    // page, it can be reused.
480f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    boolean needsLoad =
4816eac63e78d43d04e31c4d16830c44c4d9df82639Leon Scroggins                            mTabControl.recreateWebView(appTab, urlData);
482bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch
483f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    if (current != appTab) {
4841f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                        switchToTab(mTabControl.getTabIndex(appTab));
4851f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                        if (needsLoad) {
4869d53da05812f959745810a33bb4e06b273393c42Patrick Scott                            loadUrlDataIn(appTab, urlData);
4871f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                        }
488f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    } else {
4891f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                        // If the tab was the current tab, we have to attach
4901f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                        // it to the view system again.
4911f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                        attachTabToContentView(appTab);
4921f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                        if (needsLoad) {
4939d53da05812f959745810a33bb4e06b273393c42Patrick Scott                            loadUrlDataIn(appTab, urlData);
494f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                        }
495f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    }
496f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    return;
497cd11589fc3930906d4b9b7dd18aa52a9f1eb0c8aPatrick Scott                } else {
498cd11589fc3930906d4b9b7dd18aa52a9f1eb0c8aPatrick Scott                    // No matching application tab, try to find a regular tab
499cd11589fc3930906d4b9b7dd18aa52a9f1eb0c8aPatrick Scott                    // with a matching url.
500cd11589fc3930906d4b9b7dd18aa52a9f1eb0c8aPatrick Scott                    appTab = mTabControl.findUnusedTabWithUrl(urlData.mUrl);
50125515f8bd458a2471d13d876cfb0e18d8ff2a00fLeon Scroggins                    if (appTab != null) {
50225515f8bd458a2471d13d876cfb0e18d8ff2a00fLeon Scroggins                        if (current != appTab) {
50325515f8bd458a2471d13d876cfb0e18d8ff2a00fLeon Scroggins                            switchToTab(mTabControl.getTabIndex(appTab));
50425515f8bd458a2471d13d876cfb0e18d8ff2a00fLeon Scroggins                        }
50525515f8bd458a2471d13d876cfb0e18d8ff2a00fLeon Scroggins                        // Otherwise, we are already viewing the correct tab.
506cd11589fc3930906d4b9b7dd18aa52a9f1eb0c8aPatrick Scott                    } else {
507cd11589fc3930906d4b9b7dd18aa52a9f1eb0c8aPatrick Scott                        // if FLAG_ACTIVITY_BROUGHT_TO_FRONT flag is on, the url
508cd11589fc3930906d4b9b7dd18aa52a9f1eb0c8aPatrick Scott                        // will be opened in a new tab unless we have reached
509cd11589fc3930906d4b9b7dd18aa52a9f1eb0c8aPatrick Scott                        // MAX_TABS. Then the url will be opened in the current
510cd11589fc3930906d4b9b7dd18aa52a9f1eb0c8aPatrick Scott                        // tab. If a new tab is created, it will have "true" for
511cd11589fc3930906d4b9b7dd18aa52a9f1eb0c8aPatrick Scott                        // exit on close.
5121f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                        openTabAndShow(urlData, true, appId);
513cd11589fc3930906d4b9b7dd18aa52a9f1eb0c8aPatrick Scott                    }
514f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                }
5150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } else {
516638d3f45791a31d0b290e180b93bad49576eb6d3Grace Kloba                if (!urlData.isEmpty()
517638d3f45791a31d0b290e180b93bad49576eb6d3Grace Kloba                        && urlData.mUrl.startsWith("about:debug")) {
518638d3f45791a31d0b290e180b93bad49576eb6d3Grace Kloba                    if ("about:debug.dom".equals(urlData.mUrl)) {
519638d3f45791a31d0b290e180b93bad49576eb6d3Grace Kloba                        current.getWebView().dumpDomTree(false);
520638d3f45791a31d0b290e180b93bad49576eb6d3Grace Kloba                    } else if ("about:debug.dom.file".equals(urlData.mUrl)) {
521638d3f45791a31d0b290e180b93bad49576eb6d3Grace Kloba                        current.getWebView().dumpDomTree(true);
522638d3f45791a31d0b290e180b93bad49576eb6d3Grace Kloba                    } else if ("about:debug.render".equals(urlData.mUrl)) {
523638d3f45791a31d0b290e180b93bad49576eb6d3Grace Kloba                        current.getWebView().dumpRenderTree(false);
524638d3f45791a31d0b290e180b93bad49576eb6d3Grace Kloba                    } else if ("about:debug.render.file".equals(urlData.mUrl)) {
525638d3f45791a31d0b290e180b93bad49576eb6d3Grace Kloba                        current.getWebView().dumpRenderTree(true);
526638d3f45791a31d0b290e180b93bad49576eb6d3Grace Kloba                    } else if ("about:debug.display".equals(urlData.mUrl)) {
527638d3f45791a31d0b290e180b93bad49576eb6d3Grace Kloba                        current.getWebView().dumpDisplayTree();
5289b78e1d1e0bd819ae03df5594d4a56519e5d87c7Mike Reed                    } else if (urlData.mUrl.startsWith("about:debug.drag")) {
5299b78e1d1e0bd819ae03df5594d4a56519e5d87c7Mike Reed                        int index = urlData.mUrl.codePointAt(16) - '0';
5309b78e1d1e0bd819ae03df5594d4a56519e5d87c7Mike Reed                        if (index <= 0 || index > 9) {
5319b78e1d1e0bd819ae03df5594d4a56519e5d87c7Mike Reed                            current.getWebView().setDragTracker(null);
5329b78e1d1e0bd819ae03df5594d4a56519e5d87c7Mike Reed                        } else {
5339b78e1d1e0bd819ae03df5594d4a56519e5d87c7Mike Reed                            current.getWebView().setDragTracker(new MeshTracker(index));
5349b78e1d1e0bd819ae03df5594d4a56519e5d87c7Mike Reed                        }
535638d3f45791a31d0b290e180b93bad49576eb6d3Grace Kloba                    } else {
536638d3f45791a31d0b290e180b93bad49576eb6d3Grace Kloba                        mSettings.toggleDebugSettings();
537638d3f45791a31d0b290e180b93bad49576eb6d3Grace Kloba                    }
5380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    return;
5390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
5401f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                // Get rid of the subwindow if it exists
5411f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                dismissSubWindow(current);
5428588d15a7c0b87049469fd80f9c53eb274cd837bLeon Scroggins                // If the current Tab is being used as an application tab,
5438588d15a7c0b87049469fd80f9c53eb274cd837bLeon Scroggins                // remove the association, since the new Intent means that it is
5448588d15a7c0b87049469fd80f9c53eb274cd837bLeon Scroggins                // no longer associated with that application.
5458588d15a7c0b87049469fd80f9c53eb274cd837bLeon Scroggins                current.setAppId(null);
5469d53da05812f959745810a33bb4e06b273393c42Patrick Scott                loadUrlDataIn(current, urlData);
5470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
5480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
5490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
5500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
551565505b1a2c1d3099496af5910760087602e994aSatish Sampath    private int parseUrlShortcut(String url) {
552565505b1a2c1d3099496af5910760087602e994aSatish Sampath        if (url == null) return SHORTCUT_INVALID;
553565505b1a2c1d3099496af5910760087602e994aSatish Sampath
554565505b1a2c1d3099496af5910760087602e994aSatish Sampath        // FIXME: quick search, need to be customized by setting
555565505b1a2c1d3099496af5910760087602e994aSatish Sampath        if (url.length() > 2 && url.charAt(1) == ' ') {
556565505b1a2c1d3099496af5910760087602e994aSatish Sampath            switch (url.charAt(0)) {
557565505b1a2c1d3099496af5910760087602e994aSatish Sampath            case 'g': return SHORTCUT_GOOGLE_SEARCH;
558565505b1a2c1d3099496af5910760087602e994aSatish Sampath            case 'w': return SHORTCUT_WIKIPEDIA_SEARCH;
559565505b1a2c1d3099496af5910760087602e994aSatish Sampath            case 'd': return SHORTCUT_DICTIONARY_SEARCH;
560565505b1a2c1d3099496af5910760087602e994aSatish Sampath            case 'l': return SHORTCUT_GOOGLE_MOBILE_LOCAL_SEARCH;
561565505b1a2c1d3099496af5910760087602e994aSatish Sampath            }
562565505b1a2c1d3099496af5910760087602e994aSatish Sampath        }
563565505b1a2c1d3099496af5910760087602e994aSatish Sampath        return SHORTCUT_INVALID;
564565505b1a2c1d3099496af5910760087602e994aSatish Sampath    }
565565505b1a2c1d3099496af5910760087602e994aSatish Sampath
566565505b1a2c1d3099496af5910760087602e994aSatish Sampath    /**
567565505b1a2c1d3099496af5910760087602e994aSatish Sampath     * Launches the default web search activity with the query parameters if the given intent's data
568565505b1a2c1d3099496af5910760087602e994aSatish Sampath     * are identified as plain search terms and not URLs/shortcuts.
569565505b1a2c1d3099496af5910760087602e994aSatish Sampath     * @return true if the intent was handled and web search activity was launched, false if not.
570565505b1a2c1d3099496af5910760087602e994aSatish Sampath     */
571565505b1a2c1d3099496af5910760087602e994aSatish Sampath    private boolean handleWebSearchIntent(Intent intent) {
572565505b1a2c1d3099496af5910760087602e994aSatish Sampath        if (intent == null) return false;
573565505b1a2c1d3099496af5910760087602e994aSatish Sampath
574565505b1a2c1d3099496af5910760087602e994aSatish Sampath        String url = null;
575565505b1a2c1d3099496af5910760087602e994aSatish Sampath        final String action = intent.getAction();
576a1cc3fdce19a336c251297c61cd83ac6cf767cd1Leon Scroggins        if (RecognizerResultsIntent.ACTION_VOICE_SEARCH_RESULTS.equals(
577a1cc3fdce19a336c251297c61cd83ac6cf767cd1Leon Scroggins                action)) {
57858d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins            return false;
57958d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        }
580565505b1a2c1d3099496af5910760087602e994aSatish Sampath        if (Intent.ACTION_VIEW.equals(action)) {
5811e70505659dd9bf0f7e03bce787ba880f9b7a8aaGrace Kloba            Uri data = intent.getData();
5821e70505659dd9bf0f7e03bce787ba880f9b7a8aaGrace Kloba            if (data != null) url = data.toString();
583565505b1a2c1d3099496af5910760087602e994aSatish Sampath        } else if (Intent.ACTION_SEARCH.equals(action)
584565505b1a2c1d3099496af5910760087602e994aSatish Sampath                || MediaStore.INTENT_ACTION_MEDIA_SEARCH.equals(action)
585565505b1a2c1d3099496af5910760087602e994aSatish Sampath                || Intent.ACTION_WEB_SEARCH.equals(action)) {
586565505b1a2c1d3099496af5910760087602e994aSatish Sampath            url = intent.getStringExtra(SearchManager.QUERY);
587565505b1a2c1d3099496af5910760087602e994aSatish Sampath        }
5880485170e03e079eb61b9dd52fc2c98da02fa7b2cBjorn Bringert        return handleWebSearchRequest(url, intent.getBundleExtra(SearchManager.APP_DATA),
5890485170e03e079eb61b9dd52fc2c98da02fa7b2cBjorn Bringert                intent.getStringExtra(SearchManager.EXTRA_DATA_KEY));
590565505b1a2c1d3099496af5910760087602e994aSatish Sampath    }
591565505b1a2c1d3099496af5910760087602e994aSatish Sampath
592565505b1a2c1d3099496af5910760087602e994aSatish Sampath    /**
593565505b1a2c1d3099496af5910760087602e994aSatish Sampath     * Launches the default web search activity with the query parameters if the given url string
594565505b1a2c1d3099496af5910760087602e994aSatish Sampath     * was identified as plain search terms and not URL/shortcut.
595565505b1a2c1d3099496af5910760087602e994aSatish Sampath     * @return true if the request was handled and web search activity was launched, false if not.
596565505b1a2c1d3099496af5910760087602e994aSatish Sampath     */
5970485170e03e079eb61b9dd52fc2c98da02fa7b2cBjorn Bringert    private boolean handleWebSearchRequest(String inUrl, Bundle appData, String extraData) {
598565505b1a2c1d3099496af5910760087602e994aSatish Sampath        if (inUrl == null) return false;
599565505b1a2c1d3099496af5910760087602e994aSatish Sampath
600565505b1a2c1d3099496af5910760087602e994aSatish Sampath        // In general, we shouldn't modify URL from Intent.
601565505b1a2c1d3099496af5910760087602e994aSatish Sampath        // But currently, we get the user-typed URL from search box as well.
602565505b1a2c1d3099496af5910760087602e994aSatish Sampath        String url = fixUrl(inUrl).trim();
603565505b1a2c1d3099496af5910760087602e994aSatish Sampath
604565505b1a2c1d3099496af5910760087602e994aSatish Sampath        // URLs and site specific search shortcuts are handled by the regular flow of control, so
605565505b1a2c1d3099496af5910760087602e994aSatish Sampath        // return early.
6065ee906c089567bca705e18561357510d7b55cb5aDan Egnor        if (Patterns.WEB_URL.matcher(url).matches()
607bc5b9f358a2b75bf3a104b9f5cd477ad2f6f740fSatish Sampath                || ACCEPTED_URI_SCHEMA.matcher(url).matches()
608565505b1a2c1d3099496af5910760087602e994aSatish Sampath                || parseUrlShortcut(url) != SHORTCUT_INVALID) {
609565505b1a2c1d3099496af5910760087602e994aSatish Sampath            return false;
610565505b1a2c1d3099496af5910760087602e994aSatish Sampath        }
611565505b1a2c1d3099496af5910760087602e994aSatish Sampath
6128d06e36fe80f516e04ad33ff8b446720e36cabfdLeon Scroggins        final ContentResolver cr = mResolver;
6138d06e36fe80f516e04ad33ff8b446720e36cabfdLeon Scroggins        final String newUrl = url;
6148d06e36fe80f516e04ad33ff8b446720e36cabfdLeon Scroggins        new AsyncTask<Void, Void, Void>() {
6158d06e36fe80f516e04ad33ff8b446720e36cabfdLeon Scroggins            protected Void doInBackground(Void... unused) {
6168d06e36fe80f516e04ad33ff8b446720e36cabfdLeon Scroggins                Browser.updateVisitedHistory(cr, newUrl, false);
6178d06e36fe80f516e04ad33ff8b446720e36cabfdLeon Scroggins                Browser.addSearchUrl(cr, newUrl);
6188d06e36fe80f516e04ad33ff8b446720e36cabfdLeon Scroggins                return null;
6198d06e36fe80f516e04ad33ff8b446720e36cabfdLeon Scroggins            }
6208d06e36fe80f516e04ad33ff8b446720e36cabfdLeon Scroggins        }.execute();
621565505b1a2c1d3099496af5910760087602e994aSatish Sampath
622565505b1a2c1d3099496af5910760087602e994aSatish Sampath        Intent intent = new Intent(Intent.ACTION_WEB_SEARCH);
623565505b1a2c1d3099496af5910760087602e994aSatish Sampath        intent.addCategory(Intent.CATEGORY_DEFAULT);
624565505b1a2c1d3099496af5910760087602e994aSatish Sampath        intent.putExtra(SearchManager.QUERY, url);
62515e9f2dc92cf1621f95071b3c740f46079aa0f3bSatish Sampath        if (appData != null) {
62615e9f2dc92cf1621f95071b3c740f46079aa0f3bSatish Sampath            intent.putExtra(SearchManager.APP_DATA, appData);
62715e9f2dc92cf1621f95071b3c740f46079aa0f3bSatish Sampath        }
6280485170e03e079eb61b9dd52fc2c98da02fa7b2cBjorn Bringert        if (extraData != null) {
6290485170e03e079eb61b9dd52fc2c98da02fa7b2cBjorn Bringert            intent.putExtra(SearchManager.EXTRA_DATA_KEY, extraData);
6300485170e03e079eb61b9dd52fc2c98da02fa7b2cBjorn Bringert        }
631cc63403643786905262f505ab5266d8e80b9924cGrace Kloba        intent.putExtra(Browser.EXTRA_APPLICATION_ID, getPackageName());
632565505b1a2c1d3099496af5910760087602e994aSatish Sampath        startActivity(intent);
633565505b1a2c1d3099496af5910760087602e994aSatish Sampath
634565505b1a2c1d3099496af5910760087602e994aSatish Sampath        return true;
635565505b1a2c1d3099496af5910760087602e994aSatish Sampath    }
636565505b1a2c1d3099496af5910760087602e994aSatish Sampath
63725ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima    private UrlData getUrlDataFromIntent(Intent intent) {
63858d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        String url = "";
639068e48b469f5abca53ee3da38f933cf2c25c93b8Grace Kloba        Map<String, String> headers = null;
6400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (intent != null) {
6410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            final String action = intent.getAction();
6420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (Intent.ACTION_VIEW.equals(action)) {
6430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                url = smartUrlFilter(intent.getData());
6440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (url != null && url.startsWith("content:")) {
6450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    /* Append mimetype so webview knows how to display */
6460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    String mimeType = intent.resolveType(getContentResolver());
6470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    if (mimeType != null) {
6480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        url += "?" + mimeType;
6490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
6500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
651068e48b469f5abca53ee3da38f933cf2c25c93b8Grace Kloba                if (url != null && url.startsWith("http")) {
65200f54c589fd38431efd42ea2a551a49e64d595d5Grace Kloba                    final Bundle pairs = intent
65300f54c589fd38431efd42ea2a551a49e64d595d5Grace Kloba                            .getBundleExtra(Browser.EXTRA_HEADERS);
6542d508edbf54ea74cd4e89be8b622b1cbd587464aGrace Kloba                    if (pairs != null && !pairs.isEmpty()) {
65500f54c589fd38431efd42ea2a551a49e64d595d5Grace Kloba                        Iterator<String> iter = pairs.keySet().iterator();
656068e48b469f5abca53ee3da38f933cf2c25c93b8Grace Kloba                        headers = new HashMap<String, String>();
65700f54c589fd38431efd42ea2a551a49e64d595d5Grace Kloba                        while (iter.hasNext()) {
65800f54c589fd38431efd42ea2a551a49e64d595d5Grace Kloba                            String key = iter.next();
65900f54c589fd38431efd42ea2a551a49e64d595d5Grace Kloba                            headers.put(key, pairs.getString(key));
660068e48b469f5abca53ee3da38f933cf2c25c93b8Grace Kloba                        }
661068e48b469f5abca53ee3da38f933cf2c25c93b8Grace Kloba                    }
66225ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima                }
6630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } else if (Intent.ACTION_SEARCH.equals(action)
6640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    || MediaStore.INTENT_ACTION_MEDIA_SEARCH.equals(action)
6650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    || Intent.ACTION_WEB_SEARCH.equals(action)) {
6660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                url = intent.getStringExtra(SearchManager.QUERY);
6670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (url != null) {
6680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    mLastEnteredUrl = url;
6690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // In general, we shouldn't modify URL from Intent.
6700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // But currently, we get the user-typed URL from search box as well.
6710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    url = fixUrl(url);
6720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    url = smartUrlFilter(url);
6738d06e36fe80f516e04ad33ff8b446720e36cabfdLeon Scroggins                    final ContentResolver cr = mResolver;
6748d06e36fe80f516e04ad33ff8b446720e36cabfdLeon Scroggins                    final String newUrl = url;
6758d06e36fe80f516e04ad33ff8b446720e36cabfdLeon Scroggins                    new AsyncTask<Void, Void, Void>() {
6768d06e36fe80f516e04ad33ff8b446720e36cabfdLeon Scroggins                        protected Void doInBackground(Void... unused) {
6778d06e36fe80f516e04ad33ff8b446720e36cabfdLeon Scroggins                            Browser.updateVisitedHistory(cr, newUrl, false);
6788d06e36fe80f516e04ad33ff8b446720e36cabfdLeon Scroggins                            return null;
6798d06e36fe80f516e04ad33ff8b446720e36cabfdLeon Scroggins                        }
6808d06e36fe80f516e04ad33ff8b446720e36cabfdLeon Scroggins                    }.execute();
6810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    String searchSource = "&source=android-" + GOOGLE_SEARCH_SOURCE_SUGGEST + "&";
6820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    if (url.contains(searchSource)) {
6830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        String source = null;
6840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        final Bundle appData = intent.getBundleExtra(SearchManager.APP_DATA);
6850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        if (appData != null) {
68610d1cca0c208d1f9db23893a8515685e04cfe224Bjorn Bringert                            source = appData.getString(Search.SOURCE);
6870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }
6880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        if (TextUtils.isEmpty(source)) {
6890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            source = GOOGLE_SEARCH_SOURCE_UNKNOWN;
6900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }
6910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        url = url.replace(searchSource, "&source=android-"+source+"&");
6920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
6930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
6940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
6950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
69658d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        return new UrlData(url, headers, intent);
6970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
69858d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    /* package */ void showVoiceTitleBar(String title) {
69958d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        mTitleBar.setInVoiceMode(true);
70058d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        mFakeTitleBar.setInVoiceMode(true);
7010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
70258d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        mTitleBar.setDisplayTitle(title);
70358d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        mFakeTitleBar.setDisplayTitle(title);
70458d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    }
70558d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    /* package */ void revertVoiceTitleBar() {
70658d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        mTitleBar.setInVoiceMode(false);
70758d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        mFakeTitleBar.setInVoiceMode(false);
70858d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins
709003a5ddf3a7ff1b30bfd82cddc8da49cb9fedf15Leon Scroggins        mTitleBar.setDisplayTitle(mUrl);
710003a5ddf3a7ff1b30bfd82cddc8da49cb9fedf15Leon Scroggins        mFakeTitleBar.setDisplayTitle(mUrl);
71158d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    }
7120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /* package */ static String fixUrl(String inUrl) {
713652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark        // FIXME: Converting the url to lower case
714652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark        // duplicates functionality in smartUrlFilter().
715652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark        // However, changing all current callers of fixUrl to
716652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark        // call smartUrlFilter in addition may have unwanted
717652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark        // consequences, and is deferred for now.
718652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark        int colon = inUrl.indexOf(':');
719652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark        boolean allLower = true;
720652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark        for (int index = 0; index < colon; index++) {
721652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark            char ch = inUrl.charAt(index);
722652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark            if (!Character.isLetter(ch)) {
723652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark                break;
724652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark            }
725652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark            allLower &= Character.isLowerCase(ch);
726652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark            if (index == colon - 1 && !allLower) {
727652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark                inUrl = inUrl.substring(0, colon).toLowerCase()
728652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark                        + inUrl.substring(colon);
729652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark            }
730652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark        }
7310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (inUrl.startsWith("http://") || inUrl.startsWith("https://"))
7320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return inUrl;
7330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (inUrl.startsWith("http:") ||
7340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                inUrl.startsWith("https:")) {
7350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (inUrl.startsWith("http:/") || inUrl.startsWith("https:/")) {
7360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                inUrl = inUrl.replaceFirst("/", "//");
7370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } else inUrl = inUrl.replaceFirst(":", "://");
7380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
7390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return inUrl;
7400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
7410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
74222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    @Override
74322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    protected void onResume() {
7440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        super.onResume();
74531a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort        if (LOGV_ENABLED) {
7460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Log.v(LOGTAG, "BrowserActivity.onResume: this=" + this);
7470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
7480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
7490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (!mActivityInPause) {
7500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Log.e(LOGTAG, "BrowserActivity is already resumed.");
7510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
7520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
7530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
7547bfa63b55644fbf2da1fe6a24b3be0267529202cMike Reed        mTabControl.resumeCurrentTab();
7550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mActivityInPause = false;
7567bfa63b55644fbf2da1fe6a24b3be0267529202cMike Reed        resumeWebViewTimers();
7570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
7580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mWakeLock.isHeld()) {
7590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mHandler.removeMessages(RELEASE_WAKELOCK);
7600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mWakeLock.release();
7610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
7620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
7630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        registerReceiver(mNetworkStateIntentReceiver,
7640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                         mNetworkStateChangedFilter);
7650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebView.enablePlatformNotifications();
7660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
7670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
7683bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    /**
7693bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     * Since the actual title bar is embedded in the WebView, and removing it
770fe87bd3a3897e4bad65bb3d284659ae2f4e57570Leon Scroggins     * would change its appearance, use a different TitleBar to show overlayed
771fe87bd3a3897e4bad65bb3d284659ae2f4e57570Leon Scroggins     * at the top of the screen, when the menu is open or the page is loading.
7723bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     */
7733bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    private TitleBar mFakeTitleBar;
7743bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins
7753bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    /**
7763bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     * Keeps track of whether the options menu is open.  This is important in
7773bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     * determining whether to show or hide the title bar overlay.
7783bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     */
7793bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    private boolean mOptionsMenuOpen;
7803bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins
7813bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    /**
7823bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     * Only meaningful when mOptionsMenuOpen is true.  This variable keeps track
7833bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     * of whether the configuration has changed.  The first onMenuOpened call
7843bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     * after a configuration change is simply a reopening of the same menu
7853bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     * (i.e. mIconView did not change).
7863bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     */
7873bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    private boolean mConfigChanged;
7883bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins
7893bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    /**
7903bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     * Whether or not the options menu is in its smaller, icon menu form.  When
7913bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     * true, we want the title bar overlay to be up.  When false, we do not.
7923bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     * Only meaningful if mOptionsMenuOpen is true.
7933bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     */
7943bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    private boolean mIconView;
7953bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins
796a81a764063d2f849fba0cbc3039f86e67c2960ddLeon Scroggins    @Override
797a81a764063d2f849fba0cbc3039f86e67c2960ddLeon Scroggins    public boolean onMenuOpened(int featureId, Menu menu) {
7983bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins        if (Window.FEATURE_OPTIONS_PANEL == featureId) {
7993bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins            if (mOptionsMenuOpen) {
8003bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                if (mConfigChanged) {
8013bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                    // We do not need to make any changes to the state of the
8023bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                    // title bar, since the only thing that happened was a
8033bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                    // change in orientation
8043bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                    mConfigChanged = false;
8053bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                } else {
8063bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                    if (mIconView) {
8073bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                        // Switching the menu to expanded view, so hide the
8083bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                        // title bar.
8093bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                        hideFakeTitleBar();
8103bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                        mIconView = false;
8113bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                    } else {
8123bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                        // Switching the menu back to icon view, so show the
8133bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                        // title bar once again.
8143bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                        showFakeTitleBar();
8153bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                        mIconView = true;
8163bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                    }
8173bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                }
8183bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins            } else {
8193bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                // The options menu is closed, so open it, and show the title
8203bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                showFakeTitleBar();
8213bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                mOptionsMenuOpen = true;
8223bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                mConfigChanged = false;
8233bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                mIconView = true;
8243bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins            }
8253bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins        }
826a81a764063d2f849fba0cbc3039f86e67c2960ddLeon Scroggins        return true;
827a81a764063d2f849fba0cbc3039f86e67c2960ddLeon Scroggins    }
828a81a764063d2f849fba0cbc3039f86e67c2960ddLeon Scroggins
8293bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    private void showFakeTitleBar() {
830fe87bd3a3897e4bad65bb3d284659ae2f4e57570Leon Scroggins        if (mFakeTitleBar.getParent() == null && mActiveTabsPage == null
831847c25b877f1c912fe54ba7d3890df7ed3798e47Grace Kloba                && !mActivityInPause) {
832847c25b877f1c912fe54ba7d3890df7ed3798e47Grace Kloba            WebView mainView = mTabControl.getCurrentWebView();
833847c25b877f1c912fe54ba7d3890df7ed3798e47Grace Kloba            // if there is no current WebView, don't show the faked title bar;
83465190702c53f2d3ceb8e3c88d707bd6ff874034cGrace Kloba            if (mainView == null) {
835a04645545690d9f637ccae4d043a5a1b8478a832Cary Clark                return;
836a04645545690d9f637ccae4d043a5a1b8478a832Cary Clark            }
83779e36d97b67bf06b1e0c0edf773882e93a3293e4Leon Scroggins            // Do not need to check for null, since the current tab will have
83879e36d97b67bf06b1e0c0edf773882e93a3293e4Leon Scroggins            // at least a main WebView, or we would have returned above.
83979e36d97b67bf06b1e0c0edf773882e93a3293e4Leon Scroggins            if (getTopWindow().getFindIsUp()) {
84079e36d97b67bf06b1e0c0edf773882e93a3293e4Leon Scroggins                // Do not show the fake title bar, which would cover up the
84179e36d97b67bf06b1e0c0edf773882e93a3293e4Leon Scroggins                // FindDialog.
84279e36d97b67bf06b1e0c0edf773882e93a3293e4Leon Scroggins                return;
84379e36d97b67bf06b1e0c0edf773882e93a3293e4Leon Scroggins            }
8443bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins
8453bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins            WindowManager manager
8463bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                    = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
8473bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins
8483bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins            // Add the title bar to the window manager so it can receive touches
8493bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins            // while the menu is up
8503bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins            WindowManager.LayoutParams params
8513bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                    = new WindowManager.LayoutParams(
85215b8ec6b226f4d57307716e1f495e10a91f8cbf4Romain Guy                    ViewGroup.LayoutParams.MATCH_PARENT,
8533bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                    ViewGroup.LayoutParams.WRAP_CONTENT,
854847c25b877f1c912fe54ba7d3890df7ed3798e47Grace Kloba                    WindowManager.LayoutParams.TYPE_APPLICATION,
8553bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                    WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
856685498685d8424f48d77d26d8d5790da34645f44Leon Scroggins                    PixelFormat.TRANSLUCENT);
8573bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins            params.gravity = Gravity.TOP;
858847c25b877f1c912fe54ba7d3890df7ed3798e47Grace Kloba            boolean atTop = mainView.getScrollY() == 0;
85983932c74ba031eb2f581f1557c1a90f4b5bbb423Leon Scroggins            params.windowAnimations = atTop ? 0 : R.style.TitleBar;
86013f9aced9c949d452a5cb44ffc55c82f97871c89Grace Kloba            manager.addView(mFakeTitleBar, params);
8613bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins        }
8623bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    }
8633bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins
8643bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    @Override
8653bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    public void onOptionsMenuClosed(Menu menu) {
8663bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins        mOptionsMenuOpen = false;
867a27ff19e24cb1c9fef5624dbc4554548349b5b31Leon Scroggins        if (!mInLoad) {
868a27ff19e24cb1c9fef5624dbc4554548349b5b31Leon Scroggins            hideFakeTitleBar();
869a27ff19e24cb1c9fef5624dbc4554548349b5b31Leon Scroggins        } else if (!mIconView) {
870a27ff19e24cb1c9fef5624dbc4554548349b5b31Leon Scroggins            // The page is currently loading, and we are in expanded mode, so
871a27ff19e24cb1c9fef5624dbc4554548349b5b31Leon Scroggins            // we were not showing the menu.  Show it once again.  It will be
872a27ff19e24cb1c9fef5624dbc4554548349b5b31Leon Scroggins            // removed when the page finishes.
873a27ff19e24cb1c9fef5624dbc4554548349b5b31Leon Scroggins            showFakeTitleBar();
874a27ff19e24cb1c9fef5624dbc4554548349b5b31Leon Scroggins        }
8753bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    }
87622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
8773bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    private void hideFakeTitleBar() {
878fe87bd3a3897e4bad65bb3d284659ae2f4e57570Leon Scroggins        if (mFakeTitleBar.getParent() == null) return;
87920329570ba9409637298da90b83f25801d7a3d55Leon Scroggins        WindowManager.LayoutParams params = (WindowManager.LayoutParams)
88013f9aced9c949d452a5cb44ffc55c82f97871c89Grace Kloba                mFakeTitleBar.getLayoutParams();
88120329570ba9409637298da90b83f25801d7a3d55Leon Scroggins        WebView mainView = mTabControl.getCurrentWebView();
88220329570ba9409637298da90b83f25801d7a3d55Leon Scroggins        // Although we decided whether or not to animate based on the current
88320329570ba9409637298da90b83f25801d7a3d55Leon Scroggins        // scroll position, the scroll position may have changed since the
88420329570ba9409637298da90b83f25801d7a3d55Leon Scroggins        // fake title bar was displayed.  Make sure it has the appropriate
88520329570ba9409637298da90b83f25801d7a3d55Leon Scroggins        // animation/lack thereof before removing.
88620329570ba9409637298da90b83f25801d7a3d55Leon Scroggins        params.windowAnimations = mainView != null && mainView.getScrollY() == 0
88783932c74ba031eb2f581f1557c1a90f4b5bbb423Leon Scroggins                ? 0 : R.style.TitleBar;
8883bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins        WindowManager manager
8893bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                    = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
89013f9aced9c949d452a5cb44ffc55c82f97871c89Grace Kloba        manager.updateViewLayout(mFakeTitleBar, params);
89113f9aced9c949d452a5cb44ffc55c82f97871c89Grace Kloba        manager.removeView(mFakeTitleBar);
8923bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    }
8933bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins
8940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
895c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins     * Special method for the fake title bar to call when displaying its context
896c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins     * menu, since it is in its own Window, and its parent does not show a
897c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins     * context menu.
898c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins     */
899c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins    /* package */ void showTitleBarContextMenu() {
90065f4a3ce9e5c4a5227bbcbb995e5e15f1f85d3d7Cary Clark        if (null == mTitleBar.getParent()) {
90165f4a3ce9e5c4a5227bbcbb995e5e15f1f85d3d7Cary Clark            return;
90265f4a3ce9e5c4a5227bbcbb995e5e15f1f85d3d7Cary Clark        }
903c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins        openContextMenu(mTitleBar);
904c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins    }
905c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins
906b2b19f501ee05448ca81bddaaca70e9b2f51cb54Leon Scroggins    @Override
907b2b19f501ee05448ca81bddaaca70e9b2f51cb54Leon Scroggins    public void onContextMenuClosed(Menu menu) {
908b2b19f501ee05448ca81bddaaca70e9b2f51cb54Leon Scroggins        super.onContextMenuClosed(menu);
909b2b19f501ee05448ca81bddaaca70e9b2f51cb54Leon Scroggins        if (mInLoad) {
910b2b19f501ee05448ca81bddaaca70e9b2f51cb54Leon Scroggins            showFakeTitleBar();
911b2b19f501ee05448ca81bddaaca70e9b2f51cb54Leon Scroggins        }
912b2b19f501ee05448ca81bddaaca70e9b2f51cb54Leon Scroggins    }
913b2b19f501ee05448ca81bddaaca70e9b2f51cb54Leon Scroggins
914c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins    /**
9150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *  onSaveInstanceState(Bundle map)
9160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *  onSaveInstanceState is called right before onStop(). The map contains
9170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *  the saved state.
9180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
91922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    @Override
92022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    protected void onSaveInstanceState(Bundle outState) {
92131a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort        if (LOGV_ENABLED) {
9220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Log.v(LOGTAG, "BrowserActivity.onSaveInstanceState: this=" + this);
9230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
9240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // the default implementation requires each view to have an id. As the
9250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // browser handles the state itself and it doesn't use id for the views,
9260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // don't call the default implementation. Otherwise it will trigger the
9270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // warning like this, "couldn't save which view has focus because the
9280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // focused view XXX has no id".
9290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
9300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Save all the tabs
9310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mTabControl.saveState(outState);
9320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
9330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
93422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    @Override
93522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    protected void onPause() {
9360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        super.onPause();
9370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
9380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mActivityInPause) {
9390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Log.e(LOGTAG, "BrowserActivity is already paused.");
9400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
9410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
9420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
9437bfa63b55644fbf2da1fe6a24b3be0267529202cMike Reed        mTabControl.pauseCurrentTab();
9440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mActivityInPause = true;
9457bfa63b55644fbf2da1fe6a24b3be0267529202cMike Reed        if (mTabControl.getCurrentIndex() >= 0 && !pauseWebViewTimers()) {
9460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mWakeLock.acquire();
9470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mHandler.sendMessageDelayed(mHandler
9480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    .obtainMessage(RELEASE_WAKELOCK), WAKELOCK_TIMEOUT);
9490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
9500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
951a2ab6a7dc0f7023c1d7ebb1cbad397c5dc3d6453Leon Scroggins        // FIXME: This removes the active tabs page and resets the menu to
952a2ab6a7dc0f7023c1d7ebb1cbad397c5dc3d6453Leon Scroggins        // MAIN_MENU.  A better solution might be to do this work in onNewIntent
953a2ab6a7dc0f7023c1d7ebb1cbad397c5dc3d6453Leon Scroggins        // but then we would need to save it in onSaveInstanceState and restore
954a2ab6a7dc0f7023c1d7ebb1cbad397c5dc3d6453Leon Scroggins        // it in onCreate/onRestoreInstanceState
955a2ab6a7dc0f7023c1d7ebb1cbad397c5dc3d6453Leon Scroggins        if (mActiveTabsPage != null) {
956a2ab6a7dc0f7023c1d7ebb1cbad397c5dc3d6453Leon Scroggins            removeActiveTabPage(true);
957a2ab6a7dc0f7023c1d7ebb1cbad397c5dc3d6453Leon Scroggins        }
958a2ab6a7dc0f7023c1d7ebb1cbad397c5dc3d6453Leon Scroggins
9590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        cancelStopToast();
9600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
9610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // unregister network state listener
9620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        unregisterReceiver(mNetworkStateIntentReceiver);
9630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebView.disablePlatformNotifications();
9640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
9650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
96622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    @Override
96722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    protected void onDestroy() {
96831a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort        if (LOGV_ENABLED) {
9690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Log.v(LOGTAG, "BrowserActivity.onDestroy: this=" + this);
9700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
9710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        super.onDestroy();
9720923d69a8ca45222cabd82a80eaa88da9f132e9aGrace Kloba
9738d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins        if (mUploadMessage != null) {
9748d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins            mUploadMessage.onReceiveValue(null);
9758d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins            mUploadMessage = null;
9768d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins        }
9778d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins
9780923d69a8ca45222cabd82a80eaa88da9f132e9aGrace Kloba        if (mTabControl == null) return;
9790923d69a8ca45222cabd82a80eaa88da9f132e9aGrace Kloba
9801fc98a322e9df6b0e797c26de6b2cb23d69ad5d3Grace Kloba        // Remove the fake title bar if it is there
9811fc98a322e9df6b0e797c26de6b2cb23d69ad5d3Grace Kloba        hideFakeTitleBar();
9821fc98a322e9df6b0e797c26de6b2cb23d69ad5d3Grace Kloba
9830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Remove the current tab and sub window
98422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        Tab t = mTabControl.getCurrentTab();
985fb5e77fac7b8b311fe72827183f8988f5ee92a5fPatrick Scott        if (t != null) {
986fb5e77fac7b8b311fe72827183f8988f5ee92a5fPatrick Scott            dismissSubWindow(t);
987fb5e77fac7b8b311fe72827183f8988f5ee92a5fPatrick Scott            removeTabFromContentView(t);
988fb5e77fac7b8b311fe72827183f8988f5ee92a5fPatrick Scott        }
9890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Destroy all the tabs
9900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mTabControl.destroy();
9910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebIconDatabase.getInstance().close();
9920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
993b4da0ad0351996f639b50f9f29b123a9b5c24fd0Grace Kloba        unregisterReceiver(mPackageInstallationReceiver);
994a7611811e0d744a7220b7bf80c8f795af5ea53edBjorn Bringert
995a7611811e0d744a7220b7bf80c8f795af5ea53edBjorn Bringert        // Stop watching the default geolocation permissions
996a7611811e0d744a7220b7bf80c8f795af5ea53edBjorn Bringert        mSystemAllowGeolocationOrigins.stop();
997a7611811e0d744a7220b7bf80c8f795af5ea53edBjorn Bringert        mSystemAllowGeolocationOrigins = null;
9980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
9990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
10000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    @Override
10010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public void onConfigurationChanged(Configuration newConfig) {
10023bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins        mConfigChanged = true;
10030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        super.onConfigurationChanged(newConfig);
10040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
10050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mPageInfoDialog != null) {
10060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mPageInfoDialog.dismiss();
10070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            showPageInfo(
10080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mPageInfoView,
1009c7b92f811dfa3572578ddc6714c98a03936d9ce5Leon Scroggins                mPageInfoFromShowSSLCertificateOnError);
10100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
10110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mSSLCertificateDialog != null) {
10120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mSSLCertificateDialog.dismiss();
10130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            showSSLCertificate(
10140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mSSLCertificateView);
10150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
10160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mSSLCertificateOnErrorDialog != null) {
10170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mSSLCertificateOnErrorDialog.dismiss();
10180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            showSSLCertificateOnError(
10190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mSSLCertificateOnErrorView,
10200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mSSLCertificateOnErrorHandler,
10210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mSSLCertificateOnErrorError);
10220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
10230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mHttpAuthenticationDialog != null) {
10240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            String title = ((TextView) mHttpAuthenticationDialog
10250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    .findViewById(com.android.internal.R.id.alertTitle)).getText()
10260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    .toString();
10270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            String name = ((TextView) mHttpAuthenticationDialog
10280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    .findViewById(R.id.username_edit)).getText().toString();
10290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            String password = ((TextView) mHttpAuthenticationDialog
10300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    .findViewById(R.id.password_edit)).getText().toString();
10310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            int focusId = mHttpAuthenticationDialog.getCurrentFocus()
10320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    .getId();
10330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mHttpAuthenticationDialog.dismiss();
10340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            showHttpAuthentication(mHttpAuthHandler, null, null, title,
10350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    name, password, focusId);
10360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
10370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
10380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
103922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    @Override
104022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    public void onLowMemory() {
10410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        super.onLowMemory();
10420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mTabControl.freeMemory();
10430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
10440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
1045ff4d92ca529f8b77db67d0aea5d9988d5e390211Cary Clark    private void resumeWebViewTimers() {
104622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        Tab tab = mTabControl.getCurrentTab();
1047ff4d92ca529f8b77db67d0aea5d9988d5e390211Cary Clark        if (tab == null) return; // monkey can trigger this
104822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        boolean inLoad = tab.inLoad();
104922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if ((!mActivityInPause && !inLoad) || (mActivityInPause && inLoad)) {
10500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            CookieSyncManager.getInstance().startSync();
105122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            WebView w = tab.getWebView();
10520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (w != null) {
10530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                w.resumeTimers();
10540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
10550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
10560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
10570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
10587bfa63b55644fbf2da1fe6a24b3be0267529202cMike Reed    private boolean pauseWebViewTimers() {
105922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        Tab tab = mTabControl.getCurrentTab();
106022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        boolean inLoad = tab.inLoad();
106122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mActivityInPause && !inLoad) {
10620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            CookieSyncManager.getInstance().stopSync();
10630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            WebView w = mTabControl.getCurrentWebView();
10640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (w != null) {
10650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                w.pauseTimers();
10660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
10670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return true;
10680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
10690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return false;
10700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
10710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
10720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
10730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Open the icon database and retain all the icons for visited sites.
10740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void retainIconsOnStartup() {
10750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final WebIconDatabase db = WebIconDatabase.getInstance();
10760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        db.open(getDir("icons", 0).getPath());
10772c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins        Cursor c = null;
10780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        try {
10792c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins            c = Browser.getAllBookmarks(mResolver);
10802c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins            if (c.moveToFirst()) {
10812c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins                int urlIndex = c.getColumnIndex(Browser.BookmarkColumns.URL);
10822c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins                do {
10832c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins                    String url = c.getString(urlIndex);
10842c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins                    db.retainIconForPageUrl(url);
10852c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins                } while (c.moveToNext());
10860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
10870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } catch (IllegalStateException e) {
10880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Log.e(LOGTAG, "retainIconsOnStartup", e);
10892c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins        } finally {
10902c0f611fab8c0a24365c0dd5cbf0a90f70f314c8Leon Scroggins            if (c!= null) c.close();
10910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
10920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
10930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
10940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Helper method for getting the top window.
10950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    WebView getTopWindow() {
10960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return mTabControl.getCurrentTopWebView();
10970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
10980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
109922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    TabControl getTabControl() {
110022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return mTabControl;
110122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
110222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
11030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    @Override
11040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public boolean onCreateOptionsMenu(Menu menu) {
11050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        super.onCreateOptionsMenu(menu);
11060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
11070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        MenuInflater inflater = getMenuInflater();
11080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        inflater.inflate(R.menu.browser, menu);
11090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mMenu = menu;
11100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        updateInLoadMenuItems();
11110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return true;
11120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
11130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
11140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
11150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * As the menu can be open when loading state changes
11160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * we must manually update the state of the stop/reload menu
11170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * item
11180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
11190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void updateInLoadMenuItems() {
11200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mMenu == null) {
11210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
11220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
11230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        MenuItem src = mInLoad ?
11240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mMenu.findItem(R.id.stop_menu_id):
11250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    mMenu.findItem(R.id.reload_menu_id);
11260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        MenuItem dest = mMenu.findItem(R.id.stop_reload_menu_id);
11270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        dest.setIcon(src.getIcon());
11280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        dest.setTitle(src.getTitle());
11290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
11300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
11310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    @Override
11320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public boolean onContextItemSelected(MenuItem item) {
11330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // chording is not an issue with context menus, but we use the same
11340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // options selector, so set mCanChord to true so we can access them.
11350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mCanChord = true;
11360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        int id = item.getItemId();
113796afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins        boolean result = true;
11380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        switch (id) {
1139c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins            // For the context menu from the title bar
1140c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins            case R.id.title_bar_copy_page_url:
114196afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                Tab currentTab = mTabControl.getCurrentTab();
114296afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                if (null == currentTab) {
114396afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                    result = false;
114496afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                    break;
1145c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins                }
114696afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                WebView mainView = currentTab.getWebView();
114796afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                if (null == mainView) {
114896afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                    result = false;
114996afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                    break;
1150c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins                }
115196afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                copy(mainView.getUrl());
1152c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins                break;
11530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // -- Browser context menu
11540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.open_context_menu_id:
11550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.open_newtab_context_menu_id:
11560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.bookmark_context_menu_id:
11570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.save_link_context_menu_id:
11580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.share_link_context_menu_id:
11590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.copy_link_context_menu_id:
1160c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins                final WebView webView = getTopWindow();
1161c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins                if (null == webView) {
116296afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                    result = false;
116396afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                    break;
1164c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins                }
1165c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins                final HashMap hrefMap = new HashMap();
1166c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins                hrefMap.put("webview", webView);
1167c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins                final Message msg = mHandler.obtainMessage(
1168c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins                        FOCUS_NODE_HREF, id, 0, hrefMap);
11690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                webView.requestFocusNodeHref(msg);
11700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
11710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
11720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            default:
11730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // For other context menus
117496afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                result = onOptionsItemSelected(item);
11750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
11760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mCanChord = false;
117796afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins        return result;
11780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
11790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
11800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private Bundle createGoogleSearchSourceBundle(String source) {
11810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        Bundle bundle = new Bundle();
118210d1cca0c208d1f9db23893a8515685e04cfe224Bjorn Bringert        bundle.putString(Search.SOURCE, source);
11830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return bundle;
11840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
11850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
11868ad299270a97dfa3f9bcb956096bc152498fb727Leon Scroggins    /* package */ void editUrl() {
118768579393973f745fc65a2781061af9bb8f2d7020Leon Scroggins        if (mOptionsMenuOpen) closeOptionsMenu();
11885bbe98025a2c606a35c91b826760020890daadb1Leon Scroggins        String url = (getTopWindow() == null) ? null : getTopWindow().getUrl();
118983f473462fcd7869031a423c02b957c6e938a2f6Grace Kloba        startSearch(mSettings.getHomePage().equals(url) ? null : url, true,
11908ad299270a97dfa3f9bcb956096bc152498fb727Leon Scroggins                null, false);
11910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
11920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
11938ad299270a97dfa3f9bcb956096bc152498fb727Leon Scroggins    /**
11948ad299270a97dfa3f9bcb956096bc152498fb727Leon Scroggins     * Overriding this to insert a local information bundle
11958ad299270a97dfa3f9bcb956096bc152498fb727Leon Scroggins     */
11960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    @Override
11970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public void startSearch(String initialQuery, boolean selectInitialQuery,
11980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Bundle appSearchData, boolean globalSearch) {
11990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (appSearchData == null) {
12000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            appSearchData = createGoogleSearchSourceBundle(GOOGLE_SEARCH_SOURCE_TYPE);
12010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
12020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        super.startSearch(initialQuery, selectInitialQuery, appSearchData, globalSearch);
12030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
12040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
12051f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins    /**
12061f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins     * Switch tabs.  Called by the TitleBarSet when sliding the title bar
12071f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins     * results in changing tabs.
1208160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins     * @param index Index of the tab to change to, as defined by
1209160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins     *              mTabControl.getTabIndex(Tab t).
1210160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins     * @return boolean True if we successfully switched to a different tab.  If
1211160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins     *                 the indexth tab is null, or if that tab is the same as
1212160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins     *                 the current one, return false.
12131f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins     */
1214160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins    /* package */ boolean switchToTab(int index) {
121522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        Tab tab = mTabControl.getTab(index);
121622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        Tab currentTab = mTabControl.getCurrentTab();
12171f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins        if (tab == null || tab == currentTab) {
1218160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins            return false;
12191f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins        }
12201f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins        if (currentTab != null) {
12211f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins            // currentTab may be null if it was just removed.  In that case,
12221f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins            // we do not need to remove it
12231f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins            removeTabFromContentView(currentTab);
12241f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins        }
12251f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins        mTabControl.setCurrentTab(tab);
12261f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins        attachTabToContentView(tab);
1227eb6eef4c45df2d65c3e70660493a147a2be405e3Grace Kloba        resetTitleIconAndProgress();
1228eb6eef4c45df2d65c3e70660493a147a2be405e3Grace Kloba        updateLockIconToLatest();
1229160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins        return true;
12301f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins    }
12311f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins
123222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /* package */ Tab openTabToHomePage() {
12330a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins        return openTabAndShow(mSettings.getHomePage(), false, null);
12340a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins    }
12350a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins
12361f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins    /* package */ void closeCurrentWindow() {
123722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        final Tab current = mTabControl.getCurrentTab();
1238160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins        if (mTabControl.getTabCount() == 1) {
1239304442375719effd41dbd53ae62de7a8d0cec7d9Leon Scroggins            // This is the last tab.  Open a new one, with the home
1240304442375719effd41dbd53ae62de7a8d0cec7d9Leon Scroggins            // page and close the current one.
124122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            openTabToHomePage();
1242160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins            closeTab(current);
1243160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins            return;
1244160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins        }
124522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        final Tab parent = current.getParentTab();
12461f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins        int indexToShow = -1;
12471f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins        if (parent != null) {
12481f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins            indexToShow = mTabControl.getTabIndex(parent);
12491f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins        } else {
1250160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins            final int currentIndex = mTabControl.getCurrentIndex();
1251160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins            // Try to move to the tab to the right
1252160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins            indexToShow = currentIndex + 1;
1253160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins            if (indexToShow > mTabControl.getTabCount() - 1) {
1254160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins                // Try to move to the tab to the left
1255160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins                indexToShow = currentIndex - 1;
12561f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins            }
12571f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins        }
1258160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins        if (switchToTab(indexToShow)) {
1259160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins            // Close window
1260160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins            closeTab(current);
1261160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins        }
12621f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins    }
12631f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins
12640a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins    private ActiveTabsPage mActiveTabsPage;
12650a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins
12660a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins    /**
12670a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins     * Remove the active tabs page.
12680a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins     * @param needToAttach If true, the active tabs page did not attach a tab
12690a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins     *                     to the content view, so we need to do that here.
12700a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins     */
12710a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins    /* package */ void removeActiveTabPage(boolean needToAttach) {
12720a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins        mContentView.removeView(mActiveTabsPage);
12730a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins        mActiveTabsPage = null;
12740a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins        mMenuState = R.id.MAIN_MENU;
12750a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins        if (needToAttach) {
12760a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins            attachTabToContentView(mTabControl.getCurrentTab());
12770a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins        }
12780a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins        getTopWindow().requestFocus();
12790a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins    }
12800a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins
12810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    @Override
12820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public boolean onOptionsItemSelected(MenuItem item) {
12830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (!mCanChord) {
12840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // The user has already fired a shortcut with this hold down of the
12850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // menu key.
12860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return false;
12870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
12881f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins        if (null == getTopWindow()) {
12890d7ae0ed82e21d472cde8cf92b5657d8ee8ca0d8Leon Scroggins            return false;
12900d7ae0ed82e21d472cde8cf92b5657d8ee8ca0d8Leon Scroggins        }
12916ee9c498b8cf648f1507281ed5a1834ba3390907Grace Kloba        if (mMenuIsDown) {
12926ee9c498b8cf648f1507281ed5a1834ba3390907Grace Kloba            // The shortcut action consumes the MENU. Even if it is still down,
12936ee9c498b8cf648f1507281ed5a1834ba3390907Grace Kloba            // it won't trigger the next shortcut action. In the case of the
12946ee9c498b8cf648f1507281ed5a1834ba3390907Grace Kloba            // shortcut action triggering a new activity, like Bookmarks, we
12956ee9c498b8cf648f1507281ed5a1834ba3390907Grace Kloba            // won't get onKeyUp for MENU. So it is important to reset it here.
12966ee9c498b8cf648f1507281ed5a1834ba3390907Grace Kloba            mMenuIsDown = false;
12976ee9c498b8cf648f1507281ed5a1834ba3390907Grace Kloba        }
12980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        switch (item.getItemId()) {
12990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // -- Main menu
1300a81a764063d2f849fba0cbc3039f86e67c2960ddLeon Scroggins            case R.id.new_tab_menu_id:
13010a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins                openTabToHomePage();
1302a81a764063d2f849fba0cbc3039f86e67c2960ddLeon Scroggins                break;
1303a81a764063d2f849fba0cbc3039f86e67c2960ddLeon Scroggins
130464b80f3efd95d7b5192731e995ccde79c4c6c11fLeon Scroggins            case R.id.goto_menu_id:
13058ad299270a97dfa3f9bcb956096bc152498fb727Leon Scroggins                editUrl();
1306b3a5bedeede968b53363a6c517f92bc2484bb42dLeon Scroggins                break;
1307b3a5bedeede968b53363a6c517f92bc2484bb42dLeon Scroggins
1308b3a5bedeede968b53363a6c517f92bc2484bb42dLeon Scroggins            case R.id.bookmarks_menu_id:
1309304442375719effd41dbd53ae62de7a8d0cec7d9Leon Scroggins                bookmarksOrHistoryPicker(false);
13100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
13110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
13120a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins            case R.id.active_tabs_menu_id:
13130a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins                mActiveTabsPage = new ActiveTabsPage(this, mTabControl);
13140a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins                removeTabFromContentView(mTabControl.getCurrentTab());
131543de61666cfc98a3acc41c7161a1a8b0bdb2b72bLeon Scroggins                hideFakeTitleBar();
13160a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins                mContentView.addView(mActiveTabsPage, COVER_SCREEN_PARAMS);
13170a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins                mActiveTabsPage.requestFocus();
13180a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins                mMenuState = EMPTY_MENU;
13190a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins                break;
13200a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins
13211f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins            case R.id.add_bookmark_menu_id:
13221f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                Intent i = new Intent(BrowserActivity.this,
13231f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                        AddBookmarkPage.class);
13241f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                WebView w = getTopWindow();
13251f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                i.putExtra("url", w.getUrl());
13261f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                i.putExtra("title", w.getTitle());
132783cdb2c40f2dbcbdf522a2af0ec8224c7195c6c1Grace Kloba                i.putExtra("touch_icon_url", w.getTouchIconUrl());
1328dcc2b6f08dd5677bc6ba761a9ba6f1c655113051Ben Murdoch                i.putExtra("thumbnail", createScreenshot(w));
13291f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                startActivity(i);
13300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
13310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
13320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.stop_reload_menu_id:
13330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (mInLoad) {
13340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    stopLoading();
13350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                } else {
13360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    getTopWindow().reload();
13370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
13380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
13390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
13400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.back_menu_id:
13410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                getTopWindow().goBack();
13420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
13430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
13440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.forward_menu_id:
13450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                getTopWindow().goForward();
13460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
13470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
13480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.close_menu_id:
13490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // Close the subwindow if it exists.
13500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (mTabControl.getCurrentSubWindow() != null) {
13510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    dismissSubWindow(mTabControl.getCurrentTab());
13520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    break;
13530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
13541f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                closeCurrentWindow();
13550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
13560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
13570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.homepage_menu_id:
135822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                Tab current = mTabControl.getCurrentTab();
13590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (current != null) {
13600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    dismissSubWindow(current);
136192472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins                    loadUrl(current.getWebView(), mSettings.getHomePage());
13620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
13630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
13640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
13650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.preferences_menu_id:
13660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                Intent intent = new Intent(this,
13670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        BrowserPreferencesPage.class);
1368d530494de9c182af4aff97ddd46343b32594da51Leon Scroggins                intent.putExtra(BrowserPreferencesPage.CURRENT_PAGE,
1369d530494de9c182af4aff97ddd46343b32594da51Leon Scroggins                        getTopWindow().getUrl());
13700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                startActivityForResult(intent, PREFERENCES_PAGE);
13710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
13720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
13730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.find_menu_id:
13740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (null == mFindDialog) {
13750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    mFindDialog = new FindDialog(this);
13760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
1377211ba54a3052f7e68bf8af035ea1ef4e9445130cLeon Scroggins III                // Need to do something special for Tablet
137879e36d97b67bf06b1e0c0edf773882e93a3293e4Leon Scroggins                Tab tab = mTabControl.getCurrentTab();
137979e36d97b67bf06b1e0c0edf773882e93a3293e4Leon Scroggins                if (tab.getSubWebView() == null) {
138079e36d97b67bf06b1e0c0edf773882e93a3293e4Leon Scroggins                    // If the Find is being performed on the main webview,
138179e36d97b67bf06b1e0c0edf773882e93a3293e4Leon Scroggins                    // remove the embedded title bar.
138279e36d97b67bf06b1e0c0edf773882e93a3293e4Leon Scroggins                    WebView mainView = tab.getWebView();
138379e36d97b67bf06b1e0c0edf773882e93a3293e4Leon Scroggins                    if (mainView != null) {
138479e36d97b67bf06b1e0c0edf773882e93a3293e4Leon Scroggins                        mainView.setEmbeddedTitleBar(null);
138579e36d97b67bf06b1e0c0edf773882e93a3293e4Leon Scroggins                    }
138679e36d97b67bf06b1e0c0edf773882e93a3293e4Leon Scroggins                }
138779e36d97b67bf06b1e0c0edf773882e93a3293e4Leon Scroggins                hideFakeTitleBar();
138879e36d97b67bf06b1e0c0edf773882e93a3293e4Leon Scroggins                tab.showFind(mFindDialog);
13890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mMenuState = EMPTY_MENU;
13900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
13910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
13920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.select_text_id:
13930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                getTopWindow().emulateShiftHeld();
13940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
13950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.page_info_menu_id:
13960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                showPageInfo(mTabControl.getCurrentTab(), false);
13970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
13980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
13990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.classic_history_menu_id:
1400304442375719effd41dbd53ae62de7a8d0cec7d9Leon Scroggins                bookmarksOrHistoryPicker(true);
14010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
14020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
140396afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins            case R.id.title_bar_share_page_url:
14040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.share_page_menu_id:
140596afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                Tab currentTab = mTabControl.getCurrentTab();
140696afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                if (null == currentTab) {
140796afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                    mCanChord = false;
140896afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                    return false;
140996afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                }
141096afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                currentTab.populatePickerData();
141196afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                sharePage(this, currentTab.getTitle(),
141296afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                        currentTab.getUrl(), currentTab.getFavicon(),
141396afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                        createScreenshot(currentTab.getWebView()));
14140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
14150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
14160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.dump_nav_menu_id:
14170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                getTopWindow().debugDump();
14180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
14190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
14207a8b88b0e0f20544df5ee34b798398603261b733Andrei Popescu            case R.id.dump_counters_menu_id:
14217a8b88b0e0f20544df5ee34b798398603261b733Andrei Popescu                getTopWindow().dumpV8Counters();
14227a8b88b0e0f20544df5ee34b798398603261b733Andrei Popescu                break;
14237a8b88b0e0f20544df5ee34b798398603261b733Andrei Popescu
14240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.zoom_in_menu_id:
14250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                getTopWindow().zoomIn();
14260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
14270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
14280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.zoom_out_menu_id:
14290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                getTopWindow().zoomOut();
14300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
14310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
14320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.view_downloads_menu_id:
14330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                viewDownloads(null);
14340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
14350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
14360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.window_one_menu_id:
14370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.window_two_menu_id:
14380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.window_three_menu_id:
14390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.window_four_menu_id:
14400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.window_five_menu_id:
14410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.window_six_menu_id:
14420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.window_seven_menu_id:
14430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.window_eight_menu_id:
14440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                {
14450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    int menuid = item.getItemId();
14460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    for (int id = 0; id < WINDOW_SHORTCUT_ID_ARRAY.length; id++) {
14470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        if (WINDOW_SHORTCUT_ID_ARRAY[id] == menuid) {
144822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            Tab desiredTab = mTabControl.getTab(id);
14490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            if (desiredTab != null &&
14500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    desiredTab != mTabControl.getCurrentTab()) {
14511f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                                switchToTab(id);
14520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            }
14530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            break;
14540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }
14550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
14560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
14570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
14580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
14590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            default:
14600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (!super.onOptionsItemSelected(item)) {
14610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    return false;
14620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
14630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // Otherwise fall through.
14640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
14650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mCanChord = false;
14660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return true;
14670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
14680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
1469211ba54a3052f7e68bf8af035ea1ef4e9445130cLeon Scroggins III    /*
1470211ba54a3052f7e68bf8af035ea1ef4e9445130cLeon Scroggins III     * Remove the FindDialog.
1471211ba54a3052f7e68bf8af035ea1ef4e9445130cLeon Scroggins III     */
14720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public void closeFind() {
147379e36d97b67bf06b1e0c0edf773882e93a3293e4Leon Scroggins        Tab currentTab = mTabControl.getCurrentTab();
1474211ba54a3052f7e68bf8af035ea1ef4e9445130cLeon Scroggins III        if (mFindDialog != null) {
147579e36d97b67bf06b1e0c0edf773882e93a3293e4Leon Scroggins            currentTab.closeFind(mFindDialog);
1476211ba54a3052f7e68bf8af035ea1ef4e9445130cLeon Scroggins III            mFindDialog.dismiss();
1477211ba54a3052f7e68bf8af035ea1ef4e9445130cLeon Scroggins III        }
147879e36d97b67bf06b1e0c0edf773882e93a3293e4Leon Scroggins        // If the Find was being performed in the main WebView, replace the
147979e36d97b67bf06b1e0c0edf773882e93a3293e4Leon Scroggins        // embedded title bar.
148079e36d97b67bf06b1e0c0edf773882e93a3293e4Leon Scroggins        if (currentTab.getSubWebView() == null) {
148179e36d97b67bf06b1e0c0edf773882e93a3293e4Leon Scroggins            WebView mainView = currentTab.getWebView();
148279e36d97b67bf06b1e0c0edf773882e93a3293e4Leon Scroggins            if (mainView != null) {
148379e36d97b67bf06b1e0c0edf773882e93a3293e4Leon Scroggins                mainView.setEmbeddedTitleBar(mTitleBar);
148479e36d97b67bf06b1e0c0edf773882e93a3293e4Leon Scroggins            }
148579e36d97b67bf06b1e0c0edf773882e93a3293e4Leon Scroggins        }
14860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mMenuState = R.id.MAIN_MENU;
148779e36d97b67bf06b1e0c0edf773882e93a3293e4Leon Scroggins        if (mInLoad) {
148879e36d97b67bf06b1e0c0edf773882e93a3293e4Leon Scroggins            // The title bar was hidden, because otherwise it would cover up the
148979e36d97b67bf06b1e0c0edf773882e93a3293e4Leon Scroggins            // find dialog.  Now that the dialog has been removed, show the fake
149079e36d97b67bf06b1e0c0edf773882e93a3293e4Leon Scroggins            // title bar once again.
149179e36d97b67bf06b1e0c0edf773882e93a3293e4Leon Scroggins            showFakeTitleBar();
149279e36d97b67bf06b1e0c0edf773882e93a3293e4Leon Scroggins        }
14930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
14940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
149522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    @Override
149622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    public boolean onPrepareOptionsMenu(Menu menu) {
14970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // This happens when the user begins to hold down the menu key, so
14980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // allow them to chord to get a shortcut.
14990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mCanChord = true;
15000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Note: setVisible will decide whether an item is visible; while
15010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // setEnabled() will decide whether an item is enabled, which also means
15020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // whether the matching shortcut key will function.
15030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        super.onPrepareOptionsMenu(menu);
15040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        switch (mMenuState) {
15050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case EMPTY_MENU:
15060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (mCurrentMenuState != mMenuState) {
15070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    menu.setGroupVisible(R.id.MAIN_MENU, false);
15080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    menu.setGroupEnabled(R.id.MAIN_MENU, false);
15090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    menu.setGroupEnabled(R.id.MAIN_SHORTCUT_MENU, false);
15100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
15110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
15120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            default:
15130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (mCurrentMenuState != mMenuState) {
15140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    menu.setGroupVisible(R.id.MAIN_MENU, true);
15150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    menu.setGroupEnabled(R.id.MAIN_MENU, true);
15160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    menu.setGroupEnabled(R.id.MAIN_SHORTCUT_MENU, true);
15170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
15180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                final WebView w = getTopWindow();
15190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                boolean canGoBack = false;
15200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                boolean canGoForward = false;
15210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                boolean isHome = false;
15220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (w != null) {
15230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    canGoBack = w.canGoBack();
15240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    canGoForward = w.canGoForward();
15250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    isHome = mSettings.getHomePage().equals(w.getUrl());
15260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
15270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                final MenuItem back = menu.findItem(R.id.back_menu_id);
15280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                back.setEnabled(canGoBack);
15290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
15300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                final MenuItem home = menu.findItem(R.id.homepage_menu_id);
15310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                home.setEnabled(!isHome);
15320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
15330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.forward_menu_id)
15340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        .setEnabled(canGoForward);
15350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
1536a81a764063d2f849fba0cbc3039f86e67c2960ddLeon Scroggins                menu.findItem(R.id.new_tab_menu_id).setEnabled(
153722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        mTabControl.canCreateNewTab());
1538a81a764063d2f849fba0cbc3039f86e67c2960ddLeon Scroggins
15390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // decide whether to show the share link option
15400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                PackageManager pm = getPackageManager();
15410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                Intent send = new Intent(Intent.ACTION_SEND);
15420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                send.setType("text/plain");
15430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                ResolveInfo ri = pm.resolveActivity(send, PackageManager.MATCH_DEFAULT_ONLY);
15440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.share_page_menu_id).setVisible(ri != null);
15450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
15460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                boolean isNavDump = mSettings.isNavDump();
15470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                final MenuItem nav = menu.findItem(R.id.dump_nav_menu_id);
15480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                nav.setVisible(isNavDump);
15490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                nav.setEnabled(isNavDump);
15507a8b88b0e0f20544df5ee34b798398603261b733Andrei Popescu
15517a8b88b0e0f20544df5ee34b798398603261b733Andrei Popescu                boolean showDebugSettings = mSettings.showDebugSettings();
15527a8b88b0e0f20544df5ee34b798398603261b733Andrei Popescu                final MenuItem counter = menu.findItem(R.id.dump_counters_menu_id);
15537a8b88b0e0f20544df5ee34b798398603261b733Andrei Popescu                counter.setVisible(showDebugSettings);
15547a8b88b0e0f20544df5ee34b798398603261b733Andrei Popescu                counter.setEnabled(showDebugSettings);
15557a8b88b0e0f20544df5ee34b798398603261b733Andrei Popescu
15560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
15570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
15580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mCurrentMenuState = mMenuState;
15590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return true;
15600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
15610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
15620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    @Override
15630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public void onCreateContextMenu(ContextMenu menu, View v,
15640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ContextMenuInfo menuInfo) {
15654e9f89b0a64395133b9160dcb4533d2dc62a424fLeon Scroggins        if (v instanceof TitleBar) {
15664e9f89b0a64395133b9160dcb4533d2dc62a424fLeon Scroggins            return;
15674e9f89b0a64395133b9160dcb4533d2dc62a424fLeon Scroggins        }
15680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebView webview = (WebView) v;
15690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebView.HitTestResult result = webview.getHitTestResult();
15700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (result == null) {
15710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
15720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
15730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
15740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        int type = result.getType();
15750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (type == WebView.HitTestResult.UNKNOWN_TYPE) {
15760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Log.w(LOGTAG,
15770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    "We should not show context menu when nothing is touched");
15780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
15790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
15800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (type == WebView.HitTestResult.EDIT_TEXT_TYPE) {
15810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // let TextView handles context menu
15820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
15830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
15840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
15850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Note, http://b/issue?id=1106666 is requesting that
15860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // an inflated menu can be used again. This is not available
15870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // yet, so inflate each time (yuk!)
15880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        MenuInflater inflater = getMenuInflater();
15890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        inflater.inflate(R.menu.browsercontext, menu);
15900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
15910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Show the correct menu group
15920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String extra = result.getExtra();
15930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        menu.setGroupVisible(R.id.PHONE_MENU,
15940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                type == WebView.HitTestResult.PHONE_TYPE);
15950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        menu.setGroupVisible(R.id.EMAIL_MENU,
15960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                type == WebView.HitTestResult.EMAIL_TYPE);
15970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        menu.setGroupVisible(R.id.GEO_MENU,
15980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                type == WebView.HitTestResult.GEO_TYPE);
15990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        menu.setGroupVisible(R.id.IMAGE_MENU,
16000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                type == WebView.HitTestResult.IMAGE_TYPE
16010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                || type == WebView.HitTestResult.SRC_IMAGE_ANCHOR_TYPE);
16020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        menu.setGroupVisible(R.id.ANCHOR_MENU,
16030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                type == WebView.HitTestResult.SRC_ANCHOR_TYPE
16040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                || type == WebView.HitTestResult.SRC_IMAGE_ANCHOR_TYPE);
16050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
16060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Setup custom handling depending on the type
16070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        switch (type) {
16080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case WebView.HitTestResult.PHONE_TYPE:
16090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.setHeaderTitle(Uri.decode(extra));
16100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.dial_context_menu_id).setIntent(
16110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new Intent(Intent.ACTION_VIEW, Uri
16120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                .parse(WebView.SCHEME_TEL + extra)));
16130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                Intent addIntent = new Intent(Intent.ACTION_INSERT_OR_EDIT);
16140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                addIntent.putExtra(Insert.PHONE, Uri.decode(extra));
16155e335a381a0cd66e94117b202c1f34f5cb29c9b8Cary Clark                addIntent.setType(ContactsContract.Contacts.CONTENT_ITEM_TYPE);
16160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.add_contact_context_menu_id).setIntent(
16170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        addIntent);
16180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.copy_phone_context_menu_id).setOnMenuItemClickListener(
16190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new Copy(extra));
16200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
16210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
16220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case WebView.HitTestResult.EMAIL_TYPE:
16230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.setHeaderTitle(extra);
16240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.email_context_menu_id).setIntent(
16250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new Intent(Intent.ACTION_VIEW, Uri
16260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                .parse(WebView.SCHEME_MAILTO + extra)));
16270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.copy_mail_context_menu_id).setOnMenuItemClickListener(
16280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new Copy(extra));
16290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
16300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
16310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case WebView.HitTestResult.GEO_TYPE:
16320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.setHeaderTitle(extra);
16330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.map_context_menu_id).setIntent(
16340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new Intent(Intent.ACTION_VIEW, Uri
16350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                .parse(WebView.SCHEME_GEO
16360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        + URLEncoder.encode(extra))));
16370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.copy_geo_context_menu_id).setOnMenuItemClickListener(
16380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new Copy(extra));
16390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
16400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
16410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case WebView.HitTestResult.SRC_ANCHOR_TYPE:
16420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case WebView.HitTestResult.SRC_IMAGE_ANCHOR_TYPE:
16430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                TextView titleView = (TextView) LayoutInflater.from(this)
16440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        .inflate(android.R.layout.browser_link_context_header,
16450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        null);
16460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                titleView.setText(extra);
16470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.setHeaderView(titleView);
16480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // decide whether to show the open link in new tab option
16490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.open_newtab_context_menu_id).setVisible(
165022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        mTabControl.canCreateNewTab());
1651de353621650d17a412b6ffe2cbf0366db5f11c40Ben Murdoch                menu.findItem(R.id.bookmark_context_menu_id).setVisible(
1652de353621650d17a412b6ffe2cbf0366db5f11c40Ben Murdoch                        Bookmarks.urlHasAcceptableScheme(extra));
16530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                PackageManager pm = getPackageManager();
16540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                Intent send = new Intent(Intent.ACTION_SEND);
16550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                send.setType("text/plain");
16560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                ResolveInfo ri = pm.resolveActivity(send, PackageManager.MATCH_DEFAULT_ONLY);
16570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.share_link_context_menu_id).setVisible(ri != null);
16580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (type == WebView.HitTestResult.SRC_ANCHOR_TYPE) {
16590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    break;
16600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
16610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // otherwise fall through to handle image part
16620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case WebView.HitTestResult.IMAGE_TYPE:
16630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (type == WebView.HitTestResult.IMAGE_TYPE) {
16640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    menu.setHeaderTitle(extra);
16650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
16660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.view_image_context_menu_id).setIntent(
16670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new Intent(Intent.ACTION_VIEW, Uri.parse(extra)));
16680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.download_context_menu_id).
16690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        setOnMenuItemClickListener(new Download(extra));
16704f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                menu.findItem(R.id.set_wallpaper_context_menu_id).
16714f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                        setOnMenuItemClickListener(new SetAsWallpaper(extra));
16720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
16730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
16740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            default:
16750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                Log.w(LOGTAG, "We should not get here.");
16760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
16770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
1678b2b19f501ee05448ca81bddaaca70e9b2f51cb54Leon Scroggins        hideFakeTitleBar();
16790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
16800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
16810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Attach the given tab to the content view.
1682c928c30a51eee84b40cb7045842c288c1cfafff0Grace Kloba    // this should only be called for the current tab.
168322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private void attachTabToContentView(Tab t) {
16842bc69918d97a767a02132090e58718077381ba1aSteve Block        // Attach the container that contains the main WebView and any other UI
16852bc69918d97a767a02132090e58718077381ba1aSteve Block        // associated with the tab.
1686d0119535d0c490e087be114ae8fd1639bb1945dcPatrick Scott        t.attachTabToContentView(mContentView);
1687bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch
1688bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch        if (mShouldShowErrorConsole) {
168922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            ErrorConsoleView errorConsole = t.getErrorConsole(true);
1690bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch            if (errorConsole.numberOfErrors() == 0) {
1691bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch                errorConsole.showConsole(ErrorConsoleView.SHOW_NONE);
1692bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch            } else {
1693bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch                errorConsole.showConsole(ErrorConsoleView.SHOW_MINIMIZED);
1694bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch            }
1695bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch
1696bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch            mErrorConsoleContainer.addView(errorConsole,
169715b8ec6b226f4d57307716e1f495e10a91f8cbf4Romain Guy                    new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
1698bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch                                                  ViewGroup.LayoutParams.WRAP_CONTENT));
1699bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch        }
1700bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch
170139ab28eba0c8c837ac80851ec0dd2af336aa3f85Leon Scroggins        WebView view = t.getWebView();
170255a5bc2a8f3c9a0721eeaa5a45241e00d5da95efLeon Scroggins        view.setEmbeddedTitleBar(mTitleBar);
170358d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        if (t.isInVoiceSearchMode()) {
170458d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins            showVoiceTitleBar(t.getVoiceDisplayTitle());
170558d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        } else {
170658d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins            revertVoiceTitleBar();
170758d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        }
17080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Request focus on the top window.
17090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        t.getTopWindow().requestFocus();
17100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
17110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
17120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Attach a sub window to the main WebView of the given tab.
171322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void attachSubWindow(Tab t) {
1714d0119535d0c490e087be114ae8fd1639bb1945dcPatrick Scott        t.attachSubWindow(mContentView);
1715d0119535d0c490e087be114ae8fd1639bb1945dcPatrick Scott        getTopWindow().requestFocus();
17160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
17170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
17180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Remove the given tab from the content view.
171922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private void removeTabFromContentView(Tab t) {
17202bc69918d97a767a02132090e58718077381ba1aSteve Block        // Remove the container that contains the main WebView.
1721d0119535d0c490e087be114ae8fd1639bb1945dcPatrick Scott        t.removeTabFromContentView(mContentView);
1722bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch
172322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        ErrorConsoleView errorConsole = t.getErrorConsole(false);
172422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (errorConsole != null) {
172522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mErrorConsoleContainer.removeView(errorConsole);
1726bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch        }
1727bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch
172839ab28eba0c8c837ac80851ec0dd2af336aa3f85Leon Scroggins        WebView view = t.getWebView();
1729bb85b9016201d45ea939d7cb7edd0ba6616a111cLeon Scroggins        if (view != null) {
1730bb85b9016201d45ea939d7cb7edd0ba6616a111cLeon Scroggins            view.setEmbeddedTitleBar(null);
1731bb85b9016201d45ea939d7cb7edd0ba6616a111cLeon Scroggins        }
17320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
17330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
17340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Remove the sub window if it exists. Also called by TabControl when the
17350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // user clicks the 'X' to dismiss a sub window.
173622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /* package */ void dismissSubWindow(Tab t) {
1737d0119535d0c490e087be114ae8fd1639bb1945dcPatrick Scott        t.removeSubWindow(mContentView);
173822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // dismiss the subwindow. This will destroy the WebView.
173922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        t.dismissSubWindow();
1740d0119535d0c490e087be114ae8fd1639bb1945dcPatrick Scott        getTopWindow().requestFocus();
17410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
17420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
17431f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins    // A wrapper function of {@link #openTabAndShow(UrlData, boolean, String)}
174425ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima    // that accepts url as string.
174522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private Tab openTabAndShow(String url, boolean closeOnExit, String appId) {
17461f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins        return openTabAndShow(new UrlData(url), closeOnExit, appId);
17470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
17480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
17490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // This method does a ton of stuff. It will attempt to create a new tab
17500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // if we haven't reached MAX_TABS. Otherwise it uses the current tab. If
17511f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins    // url isn't null, it will load the given url.
175222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /* package */Tab openTabAndShow(UrlData urlData, boolean closeOnExit,
175322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            String appId) {
175422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        final Tab currentTab = mTabControl.getCurrentTab();
175522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mTabControl.canCreateNewTab()) {
175622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            final Tab tab = mTabControl.createNewTab(closeOnExit, appId,
175722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    urlData.mUrl);
17581f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins            WebView webview = tab.getWebView();
17590a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins            // If the last tab was removed from the active tabs page, currentTab
17600a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins            // will be null.
17610a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins            if (currentTab != null) {
17620a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins                removeTabFromContentView(currentTab);
17630a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins            }
17648bbd69f50abd537bfe7eb314b3a3e20241ac22bdPatrick Scott            // We must set the new tab as the current tab to reflect the old
17658bbd69f50abd537bfe7eb314b3a3e20241ac22bdPatrick Scott            // animation behavior.
17668bbd69f50abd537bfe7eb314b3a3e20241ac22bdPatrick Scott            mTabControl.setCurrentTab(tab);
1767eb6eef4c45df2d65c3e70660493a147a2be405e3Grace Kloba            attachTabToContentView(tab);
1768160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins            if (!urlData.isEmpty()) {
17699d53da05812f959745810a33bb4e06b273393c42Patrick Scott                loadUrlDataIn(tab, urlData);
17700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
17711f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins            return tab;
177264b80f3efd95d7b5192731e995ccde79c4c6c11fLeon Scroggins        } else {
17731f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins            // Get rid of the subwindow if it exists
17741f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins            dismissSubWindow(currentTab);
17751f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins            if (!urlData.isEmpty()) {
17761f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                // Load the given url.
17779d53da05812f959745810a33bb4e06b273393c42Patrick Scott                loadUrlDataIn(currentTab, urlData);
17780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
177958d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins            return currentTab;
17800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
17810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
17820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
178322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private Tab openTab(String url) {
17840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mSettings.openInBackground()) {
178522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            Tab t = mTabControl.createNewTab();
17860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (t != null) {
17871f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                WebView view = t.getWebView();
178892472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins                loadUrl(view, url);
17890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
1790c9181841c7ed6b9f7dfc953eab8dc7ba1047022cGrace Kloba            return t;
17910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
17921f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins            return openTabAndShow(url, false, null);
17930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
17940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
17950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
17960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private class Copy implements OnMenuItemClickListener {
17970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        private CharSequence mText;
17980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
17990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public boolean onMenuItemClick(MenuItem item) {
18000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            copy(mText);
18010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return true;
18020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
18030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
18040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public Copy(CharSequence toCopy) {
18050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mText = toCopy;
18060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
18070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
18080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
18090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private class Download implements OnMenuItemClickListener {
18100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        private String mText;
18110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
18120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public boolean onMenuItemClick(MenuItem item) {
18130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            onDownloadStartNoStream(mText, null, null, null, -1);
18140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return true;
18150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
18160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
18170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public Download(String toDownload) {
18180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mText = toDownload;
18190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
18200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
18210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
18224f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch    private class SetAsWallpaper extends Thread implements
18234f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch            OnMenuItemClickListener, DialogInterface.OnCancelListener {
18244f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch        private URL mUrl;
18254f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch        private ProgressDialog mWallpaperProgress;
18264f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch        private boolean mCanceled = false;
18274f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch
18284f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch        public SetAsWallpaper(String url) {
18294f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch            try {
18304f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                mUrl = new URL(url);
18314f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch            } catch (MalformedURLException e) {
18324f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                mUrl = null;
18334f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch            }
18344f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch        }
18354f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch
18364f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch        public void onCancel(DialogInterface dialog) {
18374f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch            mCanceled = true;
18384f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch        }
18394f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch
18404f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch        public boolean onMenuItemClick(MenuItem item) {
18414f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch            if (mUrl != null) {
18424f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                // The user may have tried to set a image with a large file size as their
18434f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                // background so it may take a few moments to perform the operation. Display
18444f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                // a progress spinner while it is working.
18454f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                mWallpaperProgress = new ProgressDialog(BrowserActivity.this);
18464f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                mWallpaperProgress.setIndeterminate(true);
18474f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                mWallpaperProgress.setMessage(getText(R.string.progress_dialog_setting_wallpaper));
18484f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                mWallpaperProgress.setCancelable(true);
18494f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                mWallpaperProgress.setOnCancelListener(this);
18504f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                mWallpaperProgress.show();
18514f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                start();
18524f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch            }
18534f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch            return true;
18544f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch        }
18554f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch
18564f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch        public void run() {
18574f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch            Drawable oldWallpaper = BrowserActivity.this.getWallpaper();
18584f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch            try {
18594f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                // TODO: This will cause the resource to be downloaded again, when we
18604f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                // should in most cases be able to grab it from the cache. To fix this
18614f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                // we should query WebCore to see if we can access a cached version and
18624f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                // instead open an input stream on that. This pattern could also be used
18634f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                // in the download manager where the same problem exists.
18644f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                InputStream inputstream = mUrl.openStream();
18654f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                if (inputstream != null) {
18664f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                    setWallpaper(inputstream);
18674f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                }
18684f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch            } catch (IOException e) {
18694f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                Log.e(LOGTAG, "Unable to set new wallpaper");
18704f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                // Act as though the user canceled the operation so we try to
18714f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                // restore the old wallpaper.
18724f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                mCanceled = true;
18734f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch            }
18744f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch
18754f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch            if (mCanceled) {
18764f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                // Restore the old wallpaper if the user cancelled whilst we were setting
18774f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                // the new wallpaper.
18784f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                int width = oldWallpaper.getIntrinsicWidth();
18794f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                int height = oldWallpaper.getIntrinsicHeight();
18804f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                Bitmap bm = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);
18814f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                Canvas canvas = new Canvas(bm);
18824f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                oldWallpaper.setBounds(0, 0, width, height);
18834f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                oldWallpaper.draw(canvas);
18844f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                try {
18854f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                    setWallpaper(bm);
18864f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                } catch (IOException e) {
18874f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                    Log.e(LOGTAG, "Unable to restore old wallpaper.");
18884f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                }
18894f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                mCanceled = false;
18904f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch            }
18914f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch
18924f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch            if (mWallpaperProgress.isShowing()) {
18934f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                mWallpaperProgress.dismiss();
18944f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch            }
18954f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch        }
18964f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch    }
18974f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch
18980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void copy(CharSequence text) {
18990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        try {
19000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            IClipboard clip = IClipboard.Stub.asInterface(ServiceManager.getService("clipboard"));
19010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (clip != null) {
19020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                clip.setClipboardText(text);
19030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
19040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } catch (android.os.RemoteException e) {
19050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Log.e(LOGTAG, "Copy failed", e);
19060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
19070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
19080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
19090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
19100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Resets the browser title-view to whatever it must be
19110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * (for example, if we had a loading error)
19120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * When we have a new page, we call resetTitle, when we
19130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * have to reset the titlebar to whatever it used to be
19140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * (for example, if the user chose to stop loading), we
19150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * call resetTitleAndRevertLockIcon.
19160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
19170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /* package */ void resetTitleAndRevertLockIcon() {
191822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mTabControl.getCurrentTab().revertLockIcon();
191922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        updateLockIconToLatest();
19200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        resetTitleIconAndProgress();
19210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
19220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
19230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
19240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Reset the title, favicon, and progress.
19250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
19260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void resetTitleIconAndProgress() {
19270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebView current = mTabControl.getCurrentWebView();
19280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (current == null) {
19290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
19300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
19310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        resetTitleAndIcon(current);
19320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        int progress = current.getProgress();
193322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        current.getWebChromeClient().onProgressChanged(current, progress);
19340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
19350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
19360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Reset the title and the icon based on the given item.
19370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void resetTitleAndIcon(WebView view) {
19380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebHistoryItem item = view.copyBackForwardList().getCurrentItem();
19390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (item != null) {
194068579393973f745fc65a2781061af9bb8f2d7020Leon Scroggins            setUrlTitle(item.getUrl(), item.getTitle());
19410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            setFavicon(item.getFavicon());
19420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
194368579393973f745fc65a2781061af9bb8f2d7020Leon Scroggins            setUrlTitle(null, null);
19440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            setFavicon(null);
19450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
19460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
19470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
19480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
19490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Sets a title composed of the URL and the title string.
19500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param url The URL of the site being loaded.
19510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param title The title of the site being loaded.
19520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
195322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void setUrlTitle(String url, String title) {
19540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mUrl = url;
19550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mTitle = title;
19560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
195758d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        // If we are in voice search mode, the title has already been set.
195858d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        if (mTabControl.getCurrentTab().isInVoiceSearchMode()) return;
195958d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        mTitleBar.setDisplayTitle(url);
196058d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        mFakeTitleBar.setDisplayTitle(url);
19610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
19620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
19630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
19640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param url The URL to build a title version of the URL from.
19650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @return The title version of the URL or null if fails.
19660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * The title version of the URL can be either the URL hostname,
19670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * or the hostname with an "https://" prefix (for secure URLs),
19680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * or an empty string if, for example, the URL in question is a
19690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * file:// URL with no hostname.
19700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
197132e14a6deccfa75490b3032bb4ddd5ae90f89de8Leon Scroggins    /* package */ static String buildTitleUrl(String url) {
19720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String titleUrl = null;
19730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
19740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (url != null) {
19750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            try {
19760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // parse the url string
19770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                URL urlObj = new URL(url);
19780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (urlObj != null) {
19790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    titleUrl = "";
19800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
19810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    String protocol = urlObj.getProtocol();
19820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    String host = urlObj.getHost();
19830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
19840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    if (host != null && 0 < host.length()) {
19850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        titleUrl = host;
19860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        if (protocol != null) {
19870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            // if a secure site, add an "https://" prefix!
19880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            if (protocol.equalsIgnoreCase("https")) {
19890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                titleUrl = protocol + "://" + host;
19900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            }
19910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }
19920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
19930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
19940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } catch (MalformedURLException e) {}
19950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
19960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
19970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return titleUrl;
19980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
19990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
20000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Set the favicon in the title bar.
200122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void setFavicon(Bitmap icon) {
200268579393973f745fc65a2781061af9bb8f2d7020Leon Scroggins        mTitleBar.setFavicon(icon);
2003fe87bd3a3897e4bad65bb3d284659ae2f4e57570Leon Scroggins        mFakeTitleBar.setFavicon(icon);
20040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
20050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
20060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
20070a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins     * Close the tab, remove its associated title bar, and adjust mTabControl's
20080a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins     * current tab to a valid value.
20091f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins     */
201022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /* package */ void closeTab(Tab t) {
20110a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins        int currentIndex = mTabControl.getCurrentIndex();
20120a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins        int removeIndex = mTabControl.getTabIndex(t);
20131f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins        mTabControl.removeTab(t);
20140a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins        if (currentIndex >= removeIndex && currentIndex != 0) {
20150a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins            currentIndex--;
20160a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins        }
20170a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins        mTabControl.setCurrentTab(mTabControl.getTab(currentIndex));
2018a5bf1deca120315a2643ea5b010f94d853461b15Andrei Popescu        resetTitleIconAndProgress();
20190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
20200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
2021dcc5eeb63eadd597587a0b2b49998c267b0bcc11Leon Scroggins    /* package */ void goBackOnePageOrQuit() {
202222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        Tab current = mTabControl.getCurrentTab();
20230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (current == null) {
20240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            /*
20250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project             * Instead of finishing the activity, simply push this to the back
20260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project             * of the stack and let ActivityManager to choose the foreground
20270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project             * activity. As BrowserActivity is singleTask, it will be always the
20280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project             * root of the task. So we can use either true or false for
20290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project             * moveTaskToBack().
20300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project             */
20310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            moveTaskToBack(true);
203200d85e74921459b34e70eb93368245b4c0a9bf5fGrace Kloba            return;
20330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
20340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebView w = current.getWebView();
20350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (w.canGoBack()) {
20360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            w.goBack();
20370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
20380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Check to see if we are closing a window that was created by
20390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // another window. If so, we switch back to that window.
204022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            Tab parent = current.getParentTab();
20410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (parent != null) {
20421f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                switchToTab(mTabControl.getTabIndex(parent));
20431f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                // Now we close the other tab
20441f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                closeTab(current);
20450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } else {
20460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (current.closeOnExit()) {
204722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    // force the tab's inLoad() to be false as we are going to
204822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    // either finish the activity or remove the tab. This will
204922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    // ensure pauseWebViewTimers() taking action.
205022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    mTabControl.getCurrentTab().clearInLoad();
20510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    if (mTabControl.getTabCount() == 1) {
20520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        finish();
20530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        return;
20540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
20557bfa63b55644fbf2da1fe6a24b3be0267529202cMike Reed                    // call pauseWebViewTimers() now, we won't be able to call
20567bfa63b55644fbf2da1fe6a24b3be0267529202cMike Reed                    // it in onPause() as the WebView won't be valid.
2057ec1b5ad8d8283b1fbbc5d7fa1cd50ef95b9e594dGrace Kloba                    // Temporarily change mActivityInPause to be true as
2058ec1b5ad8d8283b1fbbc5d7fa1cd50ef95b9e594dGrace Kloba                    // pauseWebViewTimers() will do nothing if mActivityInPause
2059ec1b5ad8d8283b1fbbc5d7fa1cd50ef95b9e594dGrace Kloba                    // is false.
2060918e1d78b2db6ef21c71a07868572d9cda498476Grace Kloba                    boolean savedState = mActivityInPause;
2061918e1d78b2db6ef21c71a07868572d9cda498476Grace Kloba                    if (savedState) {
2062ec1b5ad8d8283b1fbbc5d7fa1cd50ef95b9e594dGrace Kloba                        Log.e(LOGTAG, "BrowserActivity is already paused "
2063ec1b5ad8d8283b1fbbc5d7fa1cd50ef95b9e594dGrace Kloba                                + "while handing goBackOnePageOrQuit.");
2064918e1d78b2db6ef21c71a07868572d9cda498476Grace Kloba                    }
2065918e1d78b2db6ef21c71a07868572d9cda498476Grace Kloba                    mActivityInPause = true;
20667bfa63b55644fbf2da1fe6a24b3be0267529202cMike Reed                    pauseWebViewTimers();
2067918e1d78b2db6ef21c71a07868572d9cda498476Grace Kloba                    mActivityInPause = savedState;
20680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    removeTabFromContentView(current);
20690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    mTabControl.removeTab(current);
20700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
20710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                /*
20720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                 * Instead of finishing the activity, simply push this to the back
20730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                 * of the stack and let ActivityManager to choose the foreground
20740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                 * activity. As BrowserActivity is singleTask, it will be always the
20750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                 * root of the task. So we can use either true or false for
20760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                 * moveTaskToBack().
20770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                 */
20780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                moveTaskToBack(true);
20790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
20800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
20810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
20820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
208322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    boolean isMenuDown() {
208422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return mMenuIsDown;
208522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
208622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
20875942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba    @Override
20885942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba    public boolean onKeyDown(int keyCode, KeyEvent event) {
2089f65b50ddd2f7ed1205002d74082fff1ac2336d5cLeon Scroggins        // Even if MENU is already held down, we need to call to super to open
2090f65b50ddd2f7ed1205002d74082fff1ac2336d5cLeon Scroggins        // the IME on long press.
2091f65b50ddd2f7ed1205002d74082fff1ac2336d5cLeon Scroggins        if (KeyEvent.KEYCODE_MENU == keyCode) {
2092f65b50ddd2f7ed1205002d74082fff1ac2336d5cLeon Scroggins            mMenuIsDown = true;
2093f65b50ddd2f7ed1205002d74082fff1ac2336d5cLeon Scroggins            return super.onKeyDown(keyCode, event);
2094f65b50ddd2f7ed1205002d74082fff1ac2336d5cLeon Scroggins        }
20955942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba        // The default key mode is DEFAULT_KEYS_SEARCH_LOCAL. As the MENU is
20965942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba        // still down, we don't want to trigger the search. Pretend to consume
20975942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba        // the key and do nothing.
20985942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba        if (mMenuIsDown) return true;
20995942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba
21005942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba        switch(keyCode) {
21015942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba            case KeyEvent.KEYCODE_SPACE:
2102da0fe556a00773ce2af25eb6dcc5442bd08c7addGrace Kloba                // WebView/WebTextView handle the keys in the KeyDown. As
2103da0fe556a00773ce2af25eb6dcc5442bd08c7addGrace Kloba                // the Activity's shortcut keys are only handled when WebView
2104da0fe556a00773ce2af25eb6dcc5442bd08c7addGrace Kloba                // doesn't, have to do it in onKeyDown instead of onKeyUp.
2105da0fe556a00773ce2af25eb6dcc5442bd08c7addGrace Kloba                if (event.isShiftPressed()) {
2106da0fe556a00773ce2af25eb6dcc5442bd08c7addGrace Kloba                    getTopWindow().pageUp(false);
2107da0fe556a00773ce2af25eb6dcc5442bd08c7addGrace Kloba                } else {
2108da0fe556a00773ce2af25eb6dcc5442bd08c7addGrace Kloba                    getTopWindow().pageDown(false);
2109da0fe556a00773ce2af25eb6dcc5442bd08c7addGrace Kloba                }
21105942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                return true;
21115942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba            case KeyEvent.KEYCODE_BACK:
21125942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                if (event.getRepeatCount() == 0) {
21135942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                    event.startTracking();
21145942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                    return true;
21155942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                } else if (mCustomView == null && mActiveTabsPage == null
21165942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                        && event.isLongPress()) {
21175942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                    bookmarksOrHistoryPicker(true);
21185942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                    return true;
21190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
21205942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                break;
21210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
21225942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba        return super.onKeyDown(keyCode, event);
21230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
21240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
21255942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba    @Override
21265942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba    public boolean onKeyUp(int keyCode, KeyEvent event) {
21275942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba        switch(keyCode) {
21285942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba            case KeyEvent.KEYCODE_MENU:
21295942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                mMenuIsDown = false;
21305942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                break;
21315942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba            case KeyEvent.KEYCODE_BACK:
21325942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                if (event.isTracking() && !event.isCanceled()) {
21335942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                    if (mCustomView != null) {
21345942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                        // if a custom view is showing, hide it
213522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        mTabControl.getCurrentWebView().getWebChromeClient()
213622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                .onHideCustomView();
21375942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                    } else if (mActiveTabsPage != null) {
21385942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                        // if tab page is showing, hide it
21395942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                        removeActiveTabPage(true);
21400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    } else {
21415942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                        WebView subwindow = mTabControl.getCurrentSubWindow();
21425942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                        if (subwindow != null) {
21435942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                            if (subwindow.canGoBack()) {
21445942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                                subwindow.goBack();
21455942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                            } else {
21465942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                                dismissSubWindow(mTabControl.getCurrentTab());
21475942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                            }
21485942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                        } else {
21495942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                            goBackOnePageOrQuit();
21505942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                        }
21510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
21525942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                    return true;
21535942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                }
21545942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                break;
21550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
21565942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba        return super.onKeyUp(keyCode, event);
21570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
21580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
215968579393973f745fc65a2781061af9bb8f2d7020Leon Scroggins    /* package */ void stopLoading() {
2160b7cc8b439dc595dc48e1c2183b35d23ad72dfbe5Ben Murdoch        mDidStopLoad = true;
21610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        resetTitleAndRevertLockIcon();
21620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebView w = getTopWindow();
21630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        w.stopLoading();
216422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // FIXME: before refactor, it is using mWebViewClient. So I keep the
216522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // same logic here. But for subwindow case, should we call into the main
216622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // WebView's onPageFinished as we never call its onPageStarted and if
216722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // the page finishes itself, we don't call onPageFinished.
216822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mTabControl.getCurrentWebView().getWebViewClient().onPageFinished(w,
216922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                w.getUrl());
21700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
21710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        cancelStopToast();
21720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mStopToast = Toast
21730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .makeText(this, R.string.stopping, Toast.LENGTH_SHORT);
21740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mStopToast.show();
21750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
21760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
217722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    boolean didUserStopLoading() {
217822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return mDidStopLoad;
217922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
218022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
21810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void cancelStopToast() {
21820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mStopToast != null) {
21830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mStopToast.cancel();
21840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mStopToast = null;
21850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
21860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
21870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
218822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // called by a UI or non-UI thread to post the message
218922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    public void postMessage(int what, int arg1, int arg2, Object obj,
219022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            long delayMillis) {
219122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mHandler.sendMessageDelayed(mHandler.obtainMessage(what, arg1, arg2,
219222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                obj), delayMillis);
219322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
219422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
219522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // called by a UI or non-UI thread to remove the message
219622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void removeMessages(int what, Object object) {
219722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mHandler.removeMessages(what, object);
21980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
21990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
22000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // public message ids
22010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public final static int LOAD_URL                = 1001;
22020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public final static int STOP_LOAD               = 1002;
22030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
22040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Message Ids
22050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private static final int FOCUS_NODE_HREF         = 102;
220692c18a52ca7a79c114028b5ba22c3dfe443bd1a4Grace Kloba    private static final int RELEASE_WAKELOCK        = 107;
22070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
220822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    static final int UPDATE_BOOKMARK_THUMBNAIL       = 108;
22092694e23a55d5ca526fc29534a80a200e2c58698bBen Murdoch
22100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Private handler for handling javascript and saving passwords
22110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private Handler mHandler = new Handler() {
22120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
22130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public void handleMessage(Message msg) {
22140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            switch (msg.what) {
22150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                case FOCUS_NODE_HREF:
22162694e23a55d5ca526fc29534a80a200e2c58698bBen Murdoch                {
22170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    String url = (String) msg.getData().get("url");
221890d088caeee718f89755ee9c25249ba6da15ab97Ben Murdoch                    String title = (String) msg.getData().get("title");
22190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    if (url == null || url.length() == 0) {
22200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        break;
22210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
22220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    HashMap focusNodeMap = (HashMap) msg.obj;
22230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    WebView view = (WebView) focusNodeMap.get("webview");
22240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // Only apply the action if the top window did not change.
22250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    if (getTopWindow() != view) {
22260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        break;
22270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
22280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    switch (msg.arg1) {
22290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        case R.id.open_context_menu_id:
22300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        case R.id.view_image_context_menu_id:
223192472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins                            loadUrlFromContext(getTopWindow(), url);
22320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            break;
22330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        case R.id.open_newtab_context_menu_id:
223422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            final Tab parent = mTabControl.getCurrentTab();
223522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            final Tab newTab = openTab(url);
2236c9181841c7ed6b9f7dfc953eab8dc7ba1047022cGrace Kloba                            if (newTab != parent) {
2237c9181841c7ed6b9f7dfc953eab8dc7ba1047022cGrace Kloba                                parent.addChildTab(newTab);
2238c9181841c7ed6b9f7dfc953eab8dc7ba1047022cGrace Kloba                            }
22390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            break;
22400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        case R.id.bookmark_context_menu_id:
22410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            Intent intent = new Intent(BrowserActivity.this,
22420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    AddBookmarkPage.class);
22430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            intent.putExtra("url", url);
224490d088caeee718f89755ee9c25249ba6da15ab97Ben Murdoch                            intent.putExtra("title", title);
22450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            startActivity(intent);
22460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            break;
22470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        case R.id.share_link_context_menu_id:
22483e20445506307d2c8d699e1d17fb82a0cedde1d0Leon Scroggins                            sharePage(BrowserActivity.this, title, url, null,
224996afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                                    null);
22500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            break;
22510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        case R.id.copy_link_context_menu_id:
22520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            copy(url);
22530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            break;
22540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        case R.id.save_link_context_menu_id:
22550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        case R.id.download_context_menu_id:
22560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            onDownloadStartNoStream(url, null, null, null, -1);
22570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            break;
22580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
22590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    break;
22602694e23a55d5ca526fc29534a80a200e2c58698bBen Murdoch                }
22610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
22620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                case LOAD_URL:
226392472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins                    loadUrlFromContext(getTopWindow(), (String) msg.obj);
22640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    break;
22650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
22660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                case STOP_LOAD:
22670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    stopLoading();
22680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    break;
22690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
22700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                case RELEASE_WAKELOCK:
22710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    if (mWakeLock.isHeld()) {
22720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        mWakeLock.release();
22735d0e02e646e46b14289168f75c2a8f6ed43cac54Grace Kloba                        // if we reach here, Browser should be still in the
22745d0e02e646e46b14289168f75c2a8f6ed43cac54Grace Kloba                        // background loading after WAKELOCK_TIMEOUT (5-min).
22755d0e02e646e46b14289168f75c2a8f6ed43cac54Grace Kloba                        // To avoid burning the battery, stop loading.
22765d0e02e646e46b14289168f75c2a8f6ed43cac54Grace Kloba                        mTabControl.stopAllLoading();
22770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
22780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    break;
22792694e23a55d5ca526fc29534a80a200e2c58698bBen Murdoch
22802694e23a55d5ca526fc29534a80a200e2c58698bBen Murdoch                case UPDATE_BOOKMARK_THUMBNAIL:
22812694e23a55d5ca526fc29534a80a200e2c58698bBen Murdoch                    WebView view = (WebView) msg.obj;
22822694e23a55d5ca526fc29534a80a200e2c58698bBen Murdoch                    if (view != null) {
22832694e23a55d5ca526fc29534a80a200e2c58698bBen Murdoch                        updateScreenshot(view);
22842694e23a55d5ca526fc29534a80a200e2c58698bBen Murdoch                    }
22852694e23a55d5ca526fc29534a80a200e2c58698bBen Murdoch                    break;
22860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
22870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
22880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    };
22890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
229096afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins    /**
229196afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins     * Share a page, providing the title, url, favicon, and a screenshot.  Uses
229296afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins     * an {@link Intent} to launch the Activity chooser.
229396afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins     * @param c Context used to launch a new Activity.
229496afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins     * @param title Title of the page.  Stored in the Intent with
229503e6d39560d7de359782485d4c863d600b34fb51Paul Westbrook     *          {@link Intent#EXTRA_SUBJECT}
229696afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins     * @param url URL of the page.  Stored in the Intent with
229796afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins     *          {@link Intent#EXTRA_TEXT}
229896afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins     * @param favicon Bitmap of the favicon for the page.  Stored in the Intent
229996afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins     *          with {@link Browser#EXTRA_SHARE_FAVICON}
230096afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins     * @param screenshot Bitmap of a screenshot of the page.  Stored in the
230196afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins     *          Intent with {@link Browser#EXTRA_SHARE_SCREENSHOT}
230296afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins     */
230396afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins    public static final void sharePage(Context c, String title, String url,
230496afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins            Bitmap favicon, Bitmap screenshot) {
230596afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins        Intent send = new Intent(Intent.ACTION_SEND);
230696afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins        send.setType("text/plain");
230796afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins        send.putExtra(Intent.EXTRA_TEXT, url);
230803e6d39560d7de359782485d4c863d600b34fb51Paul Westbrook        send.putExtra(Intent.EXTRA_SUBJECT, title);
230996afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins        send.putExtra(Browser.EXTRA_SHARE_FAVICON, favicon);
231096afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins        send.putExtra(Browser.EXTRA_SHARE_SCREENSHOT, screenshot);
231196afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins        try {
231296afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins            c.startActivity(Intent.createChooser(send, c.getString(
231396afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                    R.string.choosertitle_sharevia)));
231496afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins        } catch(android.content.ActivityNotFoundException ex) {
231596afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins            // if no app handles it, do nothing
231696afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins        }
231796afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins    }
231896afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins
231989c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins    private void updateScreenshot(WebView view) {
232089c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins        // If this is a bookmarked site, add a screenshot to the database.
232189c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins        // FIXME: When should we update?  Every time?
232289c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins        // FIXME: Would like to make sure there is actually something to
232389c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins        // draw, but the API for that (WebViewCore.pictureReady()) is not
232489c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins        // currently accessible here.
2325aac7aa6fcfcb519755987ec126be066323f589c8Ben Murdoch
2326cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott        final Bitmap bm = createScreenshot(view);
2327cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott        if (bm == null) {
2328cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott            return;
2329cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott        }
2330cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott
2331cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott        final ContentResolver cr = getContentResolver();
2332cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott        final String url = view.getUrl();
2333cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott        final String originalUrl = view.getOriginalUrl();
2334cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott
2335cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott        new AsyncTask<Void, Void, Void>() {
2336cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott            @Override
2337cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott            protected Void doInBackground(Void... unused) {
2338cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott                Cursor c = null;
2339cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott                try {
2340cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott                    c = BrowserBookmarksAdapter.queryBookmarksForUrl(
2341cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott                            cr, originalUrl, url, true);
2342cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott                    if (c != null) {
2343cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott                        if (c.moveToFirst()) {
2344cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott                            ContentValues values = new ContentValues();
2345cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott                            final ByteArrayOutputStream os
2346cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott                                    = new ByteArrayOutputStream();
2347cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott                            bm.compress(Bitmap.CompressFormat.PNG, 100, os);
2348cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott                            values.put(Browser.BookmarkColumns.THUMBNAIL,
2349cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott                                    os.toByteArray());
2350cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott                            do {
2351cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott                                cr.update(ContentUris.withAppendedId(
2352cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott                                        Browser.BOOKMARKS_URI, c.getInt(0)),
2353cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott                                        values, null, null);
2354cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott                            } while (c.moveToNext());
2355cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott                        }
23564580057e772b60433272af5cd691825748892693Leon Scroggins                    }
2357cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott                } catch (IllegalStateException e) {
2358cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott                    // Ignore
2359cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott                } finally {
2360cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott                    if (c != null) c.close();
236189c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins                }
2362cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott                return null;
236389c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins            }
2364cb192b548d227e202d9a9d724e65493cbec91ab9Patrick Scott        }.execute();
236589c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins    }
236689c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins
236706ec5f2d8735d1ba17b779deb0f8da032e0a62eaLeon Scroggins    /**
2368f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins     * Values for the size of the thumbnail created when taking a screenshot.
2369f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins     * Lazily initialized.  Instead of using these directly, use
2370f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins     * getDesiredThumbnailWidth() or getDesiredThumbnailHeight().
237106ec5f2d8735d1ba17b779deb0f8da032e0a62eaLeon Scroggins     */
2372f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins    private static int THUMBNAIL_WIDTH = 0;
2373f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins    private static int THUMBNAIL_HEIGHT = 0;
2374f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins
2375f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins    /**
2376f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins     * Return the desired width for thumbnail screenshots, which are stored in
2377f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins     * the database, and used on the bookmarks screen.
2378f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins     * @param context Context for finding out the density of the screen.
2379f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins     * @return int desired width for thumbnail screenshot.
2380f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins     */
2381f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins    /* package */ static int getDesiredThumbnailWidth(Context context) {
2382f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins        if (THUMBNAIL_WIDTH == 0) {
2383f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins            float density = context.getResources().getDisplayMetrics().density;
2384f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins            THUMBNAIL_WIDTH = (int) (90 * density);
2385f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins            THUMBNAIL_HEIGHT = (int) (80 * density);
2386f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins        }
2387f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins        return THUMBNAIL_WIDTH;
2388f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins    }
2389f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins
2390f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins    /**
2391f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins     * Return the desired height for thumbnail screenshots, which are stored in
2392f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins     * the database, and used on the bookmarks screen.
2393f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins     * @param context Context for finding out the density of the screen.
2394f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins     * @return int desired height for thumbnail screenshot.
2395f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins     */
2396f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins    /* package */ static int getDesiredThumbnailHeight(Context context) {
2397f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins        // To ensure that they are both initialized.
2398f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins        getDesiredThumbnailWidth(context);
2399f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins        return THUMBNAIL_HEIGHT;
2400f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins    }
240106ec5f2d8735d1ba17b779deb0f8da032e0a62eaLeon Scroggins
2402dcc2b6f08dd5677bc6ba761a9ba6f1c655113051Ben Murdoch    private Bitmap createScreenshot(WebView view) {
2403dcc2b6f08dd5677bc6ba761a9ba6f1c655113051Ben Murdoch        Picture thumbnail = view.capturePicture();
24044580057e772b60433272af5cd691825748892693Leon Scroggins        if (thumbnail == null) {
24054580057e772b60433272af5cd691825748892693Leon Scroggins            return null;
24064580057e772b60433272af5cd691825748892693Leon Scroggins        }
2407f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins        Bitmap bm = Bitmap.createBitmap(getDesiredThumbnailWidth(this),
2408ab168ba86162b4e89e74d0a077b9c618437cbce4Cary Clark                getDesiredThumbnailHeight(this), Bitmap.Config.RGB_565);
2409dcc2b6f08dd5677bc6ba761a9ba6f1c655113051Ben Murdoch        Canvas canvas = new Canvas(bm);
2410dcc2b6f08dd5677bc6ba761a9ba6f1c655113051Ben Murdoch        // May need to tweak these values to determine what is the
2411dcc2b6f08dd5677bc6ba761a9ba6f1c655113051Ben Murdoch        // best scale factor
24122694e23a55d5ca526fc29534a80a200e2c58698bBen Murdoch        int thumbnailWidth = thumbnail.getWidth();
2413ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch        int thumbnailHeight = thumbnail.getHeight();
2414ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch        float scaleFactorX = 1.0f;
2415ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch        float scaleFactorY = 1.0f;
24162694e23a55d5ca526fc29534a80a200e2c58698bBen Murdoch        if (thumbnailWidth > 0) {
2417ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch            scaleFactorX = (float) getDesiredThumbnailWidth(this) /
24182694e23a55d5ca526fc29534a80a200e2c58698bBen Murdoch                    (float)thumbnailWidth;
2419ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch        } else {
2420ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch            return null;
242106ec5f2d8735d1ba17b779deb0f8da032e0a62eaLeon Scroggins        }
2422ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch
2423ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch        if (view.getWidth() > view.getHeight() &&
2424ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch                thumbnailHeight < view.getHeight() && thumbnailHeight > 0) {
2425ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch            // If the device is in landscape and the page is shorter
2426ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch            // than the height of the view, stretch the thumbnail to fill the
2427ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch            // space.
2428ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch            scaleFactorY = (float) getDesiredThumbnailHeight(this) /
2429ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch                    (float)thumbnailHeight;
2430ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch        } else {
2431ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch            // In the portrait case, this looks nice.
2432ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch            scaleFactorY = scaleFactorX;
2433ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch        }
2434ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch
2435ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch        canvas.scale(scaleFactorX, scaleFactorY);
2436ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch
2437dcc2b6f08dd5677bc6ba761a9ba6f1c655113051Ben Murdoch        thumbnail.draw(canvas);
2438dcc2b6f08dd5677bc6ba761a9ba6f1c655113051Ben Murdoch        return bm;
2439dcc2b6f08dd5677bc6ba761a9ba6f1c655113051Ben Murdoch    }
2440dcc2b6f08dd5677bc6ba761a9ba6f1c655113051Ben Murdoch
24410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // -------------------------------------------------------------------------
244222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // Helper function for WebViewClient.
24430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    //-------------------------------------------------------------------------
24440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
24450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Use in overrideUrlLoading
24460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /* package */ final static String SCHEME_WTAI = "wtai://wp/";
24470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /* package */ final static String SCHEME_WTAI_MC = "wtai://wp/mc;";
24480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /* package */ final static String SCHEME_WTAI_SD = "wtai://wp/sd;";
24490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /* package */ final static String SCHEME_WTAI_AP = "wtai://wp/ap;";
24500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
245192472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins    // Keep this initial progress in sync with initialProgressValue (* 100)
245292472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins    // in ProgressTracker.cpp
245392472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins    private final static int INITIAL_PROGRESS = 10;
245492472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins
245522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void onPageStarted(WebView view, String url, Bitmap favicon) {
245622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // when BrowserActivity just starts, onPageStarted may be called before
245722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // onResume as it is triggered from onCreate. Call resumeWebViewTimers
245822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // to start the timer. As we won't switch tabs while an activity is in
245922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // pause state, we can ensure calling resume and pause in pair.
246022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mActivityInPause) resumeWebViewTimers();
246122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
246222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        resetLockIcon(url);
246322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        setUrlTitle(url, null);
246422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        setFavicon(favicon);
24658cf8f682e90f004d4b8028d2f5b74f72c0cf4e19Leon Scroggins        // Show some progress so that the user knows the page is beginning to
24668cf8f682e90f004d4b8028d2f5b74f72c0cf4e19Leon Scroggins        // load
246792472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins        onProgressChanged(view, INITIAL_PROGRESS);
246822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mDidStopLoad = false;
246922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (!mIsNetworkUp) createAndShowNetworkDialog();
2470211ba54a3052f7e68bf8af035ea1ef4e9445130cLeon Scroggins III        if (view.getFindIsUp()) {
2471211ba54a3052f7e68bf8af035ea1ef4e9445130cLeon Scroggins III            closeFind();
2472211ba54a3052f7e68bf8af035ea1ef4e9445130cLeon Scroggins III        }
247322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mSettings.isTracing()) {
247422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            String host;
247522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            try {
247622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                WebAddress uri = new WebAddress(url);
247722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                host = uri.mHost;
247822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            } catch (android.net.ParseException ex) {
247922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                host = "browser";
248022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
248122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            host = host.replace('.', '_');
248222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            host += ".trace";
248322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mInTrace = true;
248422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            Debug.startMethodTracing(host, 20 * 1024 * 1024);
248515525d48024d325c8a52766d8ca727191251a8d4Patrick Scott        }
248615525d48024d325c8a52766d8ca727191251a8d4Patrick Scott
248722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Performance probe
248822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (false) {
248922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mStart = SystemClock.uptimeMillis();
249022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mProcessStart = Process.getElapsedCpuTime();
249122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            long[] sysCpu = new long[7];
249222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (Process.readProcFile("/proc/stat", SYSTEM_CPU_FORMAT, null,
249322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    sysCpu, null)) {
249422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                mUserStart = sysCpu[0] + sysCpu[1];
249522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                mSystemStart = sysCpu[2];
249622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                mIdleStart = sysCpu[3];
249722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                mIrqStart = sysCpu[4] + sysCpu[5] + sysCpu[6];
249822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
249922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mUiStart = SystemClock.currentThreadTimeMillis();
25000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
25010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
25020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
250322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void onPageFinished(WebView view, String url) {
250422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Reset the title and icon in case we stopped a provisional load.
250522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        resetTitleAndIcon(view);
250622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Update the lock icon image only once we are done loading
250722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        updateLockIconToLatest();
250822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // pause the WebView timer and release the wake lock if it is finished
250922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // while BrowserActivity is in pause state.
251022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mActivityInPause && pauseWebViewTimers()) {
251122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (mWakeLock.isHeld()) {
251222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                mHandler.removeMessages(RELEASE_WAKELOCK);
251322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                mWakeLock.release();
251422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
251522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
251622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
251722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Performance probe
251822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (false) {
251922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            long[] sysCpu = new long[7];
252022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (Process.readProcFile("/proc/stat", SYSTEM_CPU_FORMAT, null,
252122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    sysCpu, null)) {
252222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                String uiInfo = "UI thread used "
252322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        + (SystemClock.currentThreadTimeMillis() - mUiStart)
252422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        + " ms";
252522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                if (LOGD_ENABLED) {
252622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    Log.d(LOGTAG, uiInfo);
252722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                }
252822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                //The string that gets written to the log
252922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                String performanceString = "It took total "
253022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        + (SystemClock.uptimeMillis() - mStart)
253122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        + " ms clock time to load the page."
253222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        + "\nbrowser process used "
253322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        + (Process.getElapsedCpuTime() - mProcessStart)
253422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        + " ms, user processes used "
253522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        + (sysCpu[0] + sysCpu[1] - mUserStart) * 10
253622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        + " ms, kernel used "
253722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        + (sysCpu[2] - mSystemStart) * 10
253822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        + " ms, idle took " + (sysCpu[3] - mIdleStart) * 10
253922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        + " ms and irq took "
254022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        + (sysCpu[4] + sysCpu[5] + sysCpu[6] - mIrqStart)
254122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        * 10 + " ms, " + uiInfo;
254222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                if (LOGD_ENABLED) {
254322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    Log.d(LOGTAG, performanceString + "\nWebpage: " + url);
25440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
254522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                if (url != null) {
254622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    // strip the url to maintain consistency
254722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    String newUrl = new String(url);
254822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    if (newUrl.startsWith("http://www.")) {
254922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        newUrl = newUrl.substring(11);
255022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    } else if (newUrl.startsWith("http://")) {
255122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        newUrl = newUrl.substring(7);
255222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    } else if (newUrl.startsWith("https://www.")) {
255322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        newUrl = newUrl.substring(12);
255422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    } else if (newUrl.startsWith("https://")) {
255522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        newUrl = newUrl.substring(8);
25560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
255731a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort                    if (LOGD_ENABLED) {
255822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        Log.d(LOGTAG, newUrl + " loaded");
25590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
25600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
25610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
256222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         }
25630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
256422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mInTrace) {
256522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mInTrace = false;
256622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            Debug.stopMethodTracing();
25670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
256822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
25690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
257022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    boolean shouldOverrideUrlLoading(WebView view, String url) {
257122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (url.startsWith(SCHEME_WTAI)) {
257222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // wtai://wp/mc;number
257322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // number=string(phone-number)
257422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (url.startsWith(SCHEME_WTAI_MC)) {
257522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                Intent intent = new Intent(Intent.ACTION_VIEW,
257622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        Uri.parse(WebView.SCHEME_TEL +
257722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        url.substring(SCHEME_WTAI_MC.length())));
257822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                startActivity(intent);
257922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                return true;
25800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
258122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // wtai://wp/sd;dtmf
258222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // dtmf=string(dialstring)
258322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (url.startsWith(SCHEME_WTAI_SD)) {
258422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                // TODO: only send when there is active voice connection
25859918943559193e3e047a1c18442e2cdb0fe22b15Dianne Hackborn                return false;
25869918943559193e3e047a1c18442e2cdb0fe22b15Dianne Hackborn            }
258722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // wtai://wp/ap;number;name
258822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // number=string(phone-number)
258922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // name=string
259022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (url.startsWith(SCHEME_WTAI_AP)) {
259122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                // TODO
25920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                return false;
25930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
25940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
25950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
259622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // The "about:" schemes are internal to the browser; don't want these to
259722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // be dispatched to other apps.
259822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (url.startsWith("about:")) {
259922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            return false;
26000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
26010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
260222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        Intent intent;
260322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // perform generic parsing of the URI to turn it into an Intent.
260422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        try {
260522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            intent = Intent.parseUri(url, Intent.URI_INTENT_SCHEME);
260622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        } catch (URISyntaxException ex) {
260722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            Log.w("Browser", "Bad URI " + url + ": " + ex.getMessage());
260822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            return false;
26090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
26100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
261122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // check whether the intent can be resolved. If not, we will see
261222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // whether we can download it from the Market.
261322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (getPackageManager().resolveActivity(intent, 0) == null) {
261422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            String packagename = intent.getPackage();
261522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (packagename != null) {
261622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                intent = new Intent(Intent.ACTION_VIEW, Uri
261722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        .parse("market://search?q=pname:" + packagename));
261822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                intent.addCategory(Intent.CATEGORY_BROWSABLE);
261922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                startActivity(intent);
262022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                return true;
26210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } else {
26220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                return false;
26230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
26240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
26250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
262622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // sanitize the Intent, ensuring web pages can not bypass browser
262722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // security (only access to BROWSABLE activities).
262822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        intent.addCategory(Intent.CATEGORY_BROWSABLE);
262922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        intent.setComponent(null);
263022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        try {
263122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (startActivityIfNeeded(intent, -1)) {
26320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                return true;
26330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
263422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        } catch (ActivityNotFoundException ex) {
263522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // ignore the error. If no application can handle the URL,
263622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // eg about:blank, assume the browser can handle it.
263722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
26380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
263922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mMenuIsDown) {
264022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            openTab(url);
264122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            closeOptionsMenu();
26420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return true;
26430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
264422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return false;
264522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
26460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
264722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // -------------------------------------------------------------------------
264822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // Helper function for WebChromeClient
264922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // -------------------------------------------------------------------------
26500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
265122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void onProgressChanged(WebView view, int newProgress) {
265222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mFakeTitleBar.setProgress(newProgress);
265322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
265422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (newProgress == 100) {
265522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // onProgressChanged() may continue to be called after the main
265622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // frame has finished loading, as any remaining sub frames continue
265722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // to load. We'll only get called once though with newProgress as
265822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // 100 when everything is loaded. (onPageFinished is called once
265922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // when the main frame completes loading regardless of the state of
266022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // any sub frames so calls to onProgressChanges may continue after
266122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // onPageFinished has executed)
266222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (mInLoad) {
266322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                mInLoad = false;
2664a27ff19e24cb1c9fef5624dbc4554548349b5b31Leon Scroggins                updateInLoadMenuItems();
266522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                // If the options menu is open, leave the title bar
266622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                if (!mOptionsMenuOpen || !mIconView) {
266722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    hideFakeTitleBar();
26680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
26690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
2670aa37e7fdb52d0180b8eea25d53950c5c0791f968Leon Scroggins        } else {
2671aa37e7fdb52d0180b8eea25d53950c5c0791f968Leon Scroggins            if (!mInLoad) {
2672aa37e7fdb52d0180b8eea25d53950c5c0791f968Leon Scroggins                // onPageFinished may have already been called but a subframe is
2673aa37e7fdb52d0180b8eea25d53950c5c0791f968Leon Scroggins                // still loading and updating the progress. Reset mInLoad and
2674aa37e7fdb52d0180b8eea25d53950c5c0791f968Leon Scroggins                // update the menu items.
2675aa37e7fdb52d0180b8eea25d53950c5c0791f968Leon Scroggins                mInLoad = true;
2676aa37e7fdb52d0180b8eea25d53950c5c0791f968Leon Scroggins                updateInLoadMenuItems();
2677aa37e7fdb52d0180b8eea25d53950c5c0791f968Leon Scroggins            }
2678aa37e7fdb52d0180b8eea25d53950c5c0791f968Leon Scroggins            // When the page first begins to load, the Activity may still be
2679aa37e7fdb52d0180b8eea25d53950c5c0791f968Leon Scroggins            // paused, in which case showFakeTitleBar will do nothing.  Call
2680aa37e7fdb52d0180b8eea25d53950c5c0791f968Leon Scroggins            // again as the page continues to load so that it will be shown.
2681aa37e7fdb52d0180b8eea25d53950c5c0791f968Leon Scroggins            // (Calling it will the fake title bar is already showing will also
2682aa37e7fdb52d0180b8eea25d53950c5c0791f968Leon Scroggins            // do nothing.
268322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (!mOptionsMenuOpen || mIconView) {
268422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                // This page has begun to load, so show the title bar
268522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                showFakeTitleBar();
26863918d4443ff38ef1870e02aa51a8b29f8352bb1aPatrick Scott            }
26870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
268822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
2689092dd5d22d7f2ee0efcc68bd6e5a3afd1ea98953Ben Murdoch
269022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void onShowCustomView(View view, WebChromeClient.CustomViewCallback callback) {
26918ff57db0a8dc8eb659fbcdcd4a856208609e6070Derek Sollenberger        // if a view already exists then immediately terminate the new one
26928ff57db0a8dc8eb659fbcdcd4a856208609e6070Derek Sollenberger        if (mCustomView != null) {
26938ff57db0a8dc8eb659fbcdcd4a856208609e6070Derek Sollenberger            callback.onCustomViewHidden();
269422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            return;
26958ff57db0a8dc8eb659fbcdcd4a856208609e6070Derek Sollenberger        }
26962bc69918d97a767a02132090e58718077381ba1aSteve Block
269722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Add the custom view to its container.
269822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mCustomViewContainer.addView(view, COVER_SCREEN_GRAVITY_CENTER);
269922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mCustomView = view;
270022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mCustomViewCallback = callback;
270122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Save the menu state and set it to empty while the custom
270222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // view is showing.
270322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mOldMenuState = mMenuState;
270422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mMenuState = EMPTY_MENU;
270522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Hide the content view.
270622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mContentView.setVisibility(View.GONE);
270722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Finally show the custom view container.
2708163ab74e2f85b53a1a374c49677073fb64d35f28Andrei Popescu        setStatusBarVisibility(false);
270922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mCustomViewContainer.setVisibility(View.VISIBLE);
271022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mCustomViewContainer.bringToFront();
271122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
271222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
271322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void onHideCustomView() {
271422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mCustomView == null)
271522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            return;
27162bc69918d97a767a02132090e58718077381ba1aSteve Block
271722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Hide the custom view.
271822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mCustomView.setVisibility(View.GONE);
271922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Remove the custom view from its container.
272022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mCustomViewContainer.removeView(mCustomView);
272122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mCustomView = null;
272222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Reset the old menu state.
272322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mMenuState = mOldMenuState;
272422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mOldMenuState = EMPTY_MENU;
272522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mCustomViewContainer.setVisibility(View.GONE);
272622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mCustomViewCallback.onCustomViewHidden();
272722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Show the content view.
2728163ab74e2f85b53a1a374c49677073fb64d35f28Andrei Popescu        setStatusBarVisibility(true);
272922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mContentView.setVisibility(View.VISIBLE);
273022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
2731540035dfd1347c78eeec10ec0847e18fcc50ef36Andrei Popescu
273222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    Bitmap getDefaultVideoPoster() {
273322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mDefaultVideoPoster == null) {
273422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mDefaultVideoPoster = BitmapFactory.decodeResource(
273522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    getResources(), R.drawable.default_video_poster);
2736540035dfd1347c78eeec10ec0847e18fcc50ef36Andrei Popescu        }
273722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return mDefaultVideoPoster;
273822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
2739540035dfd1347c78eeec10ec0847e18fcc50ef36Andrei Popescu
274022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    View getVideoLoadingProgressView() {
274122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mVideoProgressView == null) {
274222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            LayoutInflater inflater = LayoutInflater.from(BrowserActivity.this);
274322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mVideoProgressView = inflater.inflate(
274422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    R.layout.video_loading_progress, null);
2745540035dfd1347c78eeec10ec0847e18fcc50ef36Andrei Popescu        }
274622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return mVideoProgressView;
274722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
27480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
27498d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins    /*
27508d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins     * The Object used to inform the WebView of the file to upload.
27518d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins     */
27528d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins    private ValueCallback<Uri> mUploadMessage;
27538d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins
275422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void openFileChooser(ValueCallback<Uri> uploadMsg) {
275522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mUploadMessage != null) return;
275622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mUploadMessage = uploadMsg;
275722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        Intent i = new Intent(Intent.ACTION_GET_CONTENT);
275822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        i.addCategory(Intent.CATEGORY_OPENABLE);
275922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        i.setType("*/*");
276022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        BrowserActivity.this.startActivityForResult(Intent.createChooser(i,
276122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                getString(R.string.choose_upload)), FILE_SELECTED);
276222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
276322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
276422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // -------------------------------------------------------------------------
276522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // Implement functions for DownloadListener
276622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // -------------------------------------------------------------------------
276722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
27680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
27690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Notify the host application a download should be done, or that
27700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * the data should be streamed if a streaming viewer is available.
27710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param url The full url to the content that should be downloaded
27720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param contentDisposition Content-disposition http header, if
27730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *                           present.
27740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param mimetype The mimetype of the content reported by the server
27750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param contentLength The file size reported by the server
27760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
27770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public void onDownloadStart(String url, String userAgent,
27780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            String contentDisposition, String mimetype, long contentLength) {
27790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // if we're dealing wih A/V content that's not explicitly marked
27800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        //     for download, check if it's streamable.
27810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (contentDisposition == null
2782e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                || !contentDisposition.regionMatches(
2783e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                        true, 0, "attachment", 0, 10)) {
27840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // query the package manager to see if there's a registered handler
27850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            //     that matches.
27860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Intent intent = new Intent(Intent.ACTION_VIEW);
27870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            intent.setDataAndType(Uri.parse(url), mimetype);
2788e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott            ResolveInfo info = getPackageManager().resolveActivity(intent,
2789e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                    PackageManager.MATCH_DEFAULT_ONLY);
2790e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott            if (info != null) {
2791e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                ComponentName myName = getComponentName();
2792e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                // If we resolved to ourselves, we don't want to attempt to
2793e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                // load the url only to try and download it again.
2794e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                if (!myName.getPackageName().equals(
2795e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                        info.activityInfo.packageName)
2796e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                        || !myName.getClassName().equals(
2797e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                                info.activityInfo.name)) {
2798e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                    // someone (other than us) knows how to handle this mime
2799e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                    // type with this scheme, don't download.
2800e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                    try {
2801e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                        startActivity(intent);
2802e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                        return;
2803e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                    } catch (ActivityNotFoundException ex) {
2804e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                        if (LOGD_ENABLED) {
2805e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                            Log.d(LOGTAG, "activity not found for " + mimetype
2806e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                                    + " over " + Uri.parse(url).getScheme(),
2807e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                                    ex);
2808e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                        }
2809e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                        // Best behavior is to fall back to a download in this
2810e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                        // case
28110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
28120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
28130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
28140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
28150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        onDownloadStartNoStream(url, userAgent, contentDisposition, mimetype, contentLength);
28160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
28170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
2818fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen    // This is to work around the fact that java.net.URI throws Exceptions
2819fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen    // instead of just encoding URL's properly
2820fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen    // Helper method for onDownloadStartNoStream
2821fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen    private static String encodePath(String path) {
2822fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen        char[] chars = path.toCharArray();
2823fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen
2824fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen        boolean needed = false;
2825fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen        for (char c : chars) {
2826fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen            if (c == '[' || c == ']') {
2827fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen                needed = true;
2828fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen                break;
2829fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen            }
2830fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen        }
2831fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen        if (needed == false) {
2832fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen            return path;
2833fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen        }
2834fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen
2835fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen        StringBuilder sb = new StringBuilder("");
2836fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen        for (char c : chars) {
2837fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen            if (c == '[' || c == ']') {
2838fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen                sb.append('%');
2839fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen                sb.append(Integer.toHexString(c));
2840fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen            } else {
2841fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen                sb.append(c);
2842fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen            }
2843fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen        }
2844fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen
2845fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen        return sb.toString();
2846fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen    }
2847fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen
28480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
28490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Notify the host application a download should be done, even if there
28500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * is a streaming viewer available for thise type.
28510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param url The full url to the content that should be downloaded
28520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param contentDisposition Content-disposition http header, if
28530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *                           present.
28540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param mimetype The mimetype of the content reported by the server
28550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param contentLength The file size reported by the server
28560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
28570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /*package */ void onDownloadStartNoStream(String url, String userAgent,
28580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            String contentDisposition, String mimetype, long contentLength) {
28590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
28600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String filename = URLUtil.guessFileName(url,
28610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                contentDisposition, mimetype);
28620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
28630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Check to see if we have an SDCard
28640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String status = Environment.getExternalStorageState();
28650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (!status.equals(Environment.MEDIA_MOUNTED)) {
28660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            int title;
28670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            String msg;
28680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
28690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Check to see if the SDCard is busy, same as the music app
28700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (status.equals(Environment.MEDIA_SHARED)) {
28710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                msg = getString(R.string.download_sdcard_busy_dlg_msg);
28720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                title = R.string.download_sdcard_busy_dlg_title;
28730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } else {
28740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                msg = getString(R.string.download_no_sdcard_dlg_msg, filename);
28750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                title = R.string.download_no_sdcard_dlg_title;
28760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
28770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
28780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            new AlertDialog.Builder(this)
28790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setTitle(title)
28800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setIcon(android.R.drawable.ic_dialog_alert)
28810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setMessage(msg)
28820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setPositiveButton(R.string.ok, null)
28830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .show();
28840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
28850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
28860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
2887fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen        // java.net.URI is a lot stricter than KURL so we have to encode some
2888fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen        // extra characters. Fix for b 2538060 and b 1634719
2889fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen        WebAddress webAddress;
28900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        try {
2891fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen            webAddress = new WebAddress(url);
2892fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen            webAddress.mPath = encodePath(webAddress.mPath);
28930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } catch (Exception e) {
2894fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen            // This only happens for very bad urls, we want to chatch the
2895fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen            // exception here
2896fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen            Log.e(LOGTAG, "Exception trying to parse url:" + url);
28970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
28980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
28990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
29000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // XXX: Have to use the old url since the cookies were stored using the
29010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // old percent-encoded url.
29020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String cookies = CookieManager.getInstance().getCookie(url);
29030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
29040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        ContentValues values = new ContentValues();
2905fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen        values.put(Downloads.Impl.COLUMN_URI, webAddress.toString());
29061e5bad97ca8fb9b12501f4f747941d02f03e1362Jean-Baptiste Queru        values.put(Downloads.Impl.COLUMN_COOKIE_DATA, cookies);
29071e5bad97ca8fb9b12501f4f747941d02f03e1362Jean-Baptiste Queru        values.put(Downloads.Impl.COLUMN_USER_AGENT, userAgent);
29081e5bad97ca8fb9b12501f4f747941d02f03e1362Jean-Baptiste Queru        values.put(Downloads.Impl.COLUMN_NOTIFICATION_PACKAGE,
29090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                getPackageName());
29101e5bad97ca8fb9b12501f4f747941d02f03e1362Jean-Baptiste Queru        values.put(Downloads.Impl.COLUMN_NOTIFICATION_CLASS,
2911a563d09392905140893d7a017dd63721577e1953Leon Scroggins                OpenDownloadReceiver.class.getCanonicalName());
29121e5bad97ca8fb9b12501f4f747941d02f03e1362Jean-Baptiste Queru        values.put(Downloads.Impl.COLUMN_VISIBILITY,
29131e5bad97ca8fb9b12501f4f747941d02f03e1362Jean-Baptiste Queru                Downloads.Impl.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
29141e5bad97ca8fb9b12501f4f747941d02f03e1362Jean-Baptiste Queru        values.put(Downloads.Impl.COLUMN_MIME_TYPE, mimetype);
29151e5bad97ca8fb9b12501f4f747941d02f03e1362Jean-Baptiste Queru        values.put(Downloads.Impl.COLUMN_FILE_NAME_HINT, filename);
2916fa52d17a04294c245d6b00180bbe03560390c967Kristian Monsen        values.put(Downloads.Impl.COLUMN_DESCRIPTION, webAddress.mHost);
29170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (contentLength > 0) {
29181e5bad97ca8fb9b12501f4f747941d02f03e1362Jean-Baptiste Queru            values.put(Downloads.Impl.COLUMN_TOTAL_BYTES, contentLength);
29190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
29200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mimetype == null) {
29210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // We must have long pressed on a link or image to download it. We
29220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // are not sure of the mimetype in this case, so do a head request
29230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            new FetchUrlMimeType(this).execute(values);
29240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
29250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            final Uri contentUri =
29261e5bad97ca8fb9b12501f4f747941d02f03e1362Jean-Baptiste Queru                    getContentResolver().insert(Downloads.Impl.CONTENT_URI, values);
29270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
29289191a7f745c965cf57df94d0628890b413c710c9Leon Scroggins        Toast.makeText(this, R.string.download_pending, Toast.LENGTH_SHORT)
29299191a7f745c965cf57df94d0628890b413c710c9Leon Scroggins                .show();
29300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
29310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
293222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // -------------------------------------------------------------------------
293322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
29340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
29350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Resets the lock icon. This method is called when we start a new load and
29360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * know the url to be loaded.
29370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
29380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void resetLockIcon(String url) {
29390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Save the lock-icon state (we revert to it if the load gets cancelled)
294022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mTabControl.getCurrentTab().resetLockIcon(url);
29410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        updateLockIconImage(LOCK_ICON_UNSECURE);
29420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
29430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
29440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
29453bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     * Update the lock icon to correspond to our latest state.
29463bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     */
294722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private void updateLockIconToLatest() {
294822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        updateLockIconImage(mTabControl.getCurrentTab().getLockIconType());
29493bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    }
29503bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins
29513bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    /**
29520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Updates the lock-icon image in the title-bar.
29530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
29540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void updateLockIconImage(int lockIconType) {
29550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        Drawable d = null;
29560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (lockIconType == LOCK_ICON_SECURE) {
29570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            d = mSecLockIcon;
29580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else if (lockIconType == LOCK_ICON_MIXED) {
29590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            d = mMixLockIcon;
29600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
296168579393973f745fc65a2781061af9bb8f2d7020Leon Scroggins        mTitleBar.setLock(d);
2962fe87bd3a3897e4bad65bb3d284659ae2f4e57570Leon Scroggins        mFakeTitleBar.setLock(d);
29630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
29640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
29650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
29660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Displays a page-info dialog.
29670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param tab The tab to show info about
29680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param fromShowSSLCertificateOnError The flag that indicates whether
29690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * this dialog was opened from the SSL-certificate-on-error dialog or
29700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * not. This is important, since we need to know whether to return to
29710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * the parent dialog or simply dismiss.
29720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
297322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private void showPageInfo(final Tab tab,
29740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                              final boolean fromShowSSLCertificateOnError) {
29750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final LayoutInflater factory = LayoutInflater
29760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .from(this);
29770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
29780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final View pageInfoView = factory.inflate(R.layout.page_info, null);
29790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
29800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final WebView view = tab.getWebView();
29810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
29820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String url = null;
29830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String title = null;
29840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
29850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (view == null) {
29860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            url = tab.getUrl();
29870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            title = tab.getTitle();
29880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else if (view == mTabControl.getCurrentWebView()) {
29890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project             // Use the cached title and url if this is the current WebView
29900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            url = mUrl;
29910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            title = mTitle;
29920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
29930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            url = view.getUrl();
29940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            title = view.getTitle();
29950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
29960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
29970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (url == null) {
29980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            url = "";
29990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
30000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (title == null) {
30010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            title = "";
30020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
30030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
30040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        ((TextView) pageInfoView.findViewById(R.id.address)).setText(url);
30050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        ((TextView) pageInfoView.findViewById(R.id.title)).setText(title);
30060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
30070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mPageInfoView = tab;
3008c7b92f811dfa3572578ddc6714c98a03936d9ce5Leon Scroggins        mPageInfoFromShowSSLCertificateOnError = fromShowSSLCertificateOnError;
30090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
30100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        AlertDialog.Builder alertDialogBuilder =
30110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            new AlertDialog.Builder(this)
30120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            .setTitle(R.string.page_info).setIcon(android.R.drawable.ic_dialog_info)
30130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            .setView(pageInfoView)
30140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            .setPositiveButton(
30150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                R.string.ok,
30160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                new DialogInterface.OnClickListener() {
30170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    public void onClick(DialogInterface dialog,
30180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        int whichButton) {
30190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        mPageInfoDialog = null;
30200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        mPageInfoView = null;
30210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
30220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        // if we came here from the SSL error dialog
30230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        if (fromShowSSLCertificateOnError) {
30240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            // go back to the SSL error dialog
30250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            showSSLCertificateOnError(
30260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorView,
30270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorHandler,
30280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorError);
30290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }
30300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
30310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                })
30320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            .setOnCancelListener(
30330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                new DialogInterface.OnCancelListener() {
30340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    public void onCancel(DialogInterface dialog) {
30350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        mPageInfoDialog = null;
30360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        mPageInfoView = null;
30370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
30380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        // if we came here from the SSL error dialog
30390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        if (fromShowSSLCertificateOnError) {
30400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            // go back to the SSL error dialog
30410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            showSSLCertificateOnError(
30420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorView,
30430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorHandler,
30440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorError);
30450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }
30460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
30470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                });
30480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
30490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // if we have a main top-level page SSL certificate set or a certificate
30500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // error
30510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (fromShowSSLCertificateOnError ||
30520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                (view != null && view.getCertificate() != null)) {
30530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // add a 'View Certificate' button
30540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            alertDialogBuilder.setNeutralButton(
30550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                R.string.view_certificate,
30560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                new DialogInterface.OnClickListener() {
30570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    public void onClick(DialogInterface dialog,
30580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        int whichButton) {
30590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        mPageInfoDialog = null;
30600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        mPageInfoView = null;
30610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
30620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        // if we came here from the SSL error dialog
30630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        if (fromShowSSLCertificateOnError) {
30640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            // go back to the SSL error dialog
30650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            showSSLCertificateOnError(
30660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorView,
30670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorHandler,
30680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorError);
30690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        } else {
30700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            // otherwise, display the top-most certificate from
30710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            // the chain
30720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            if (view.getCertificate() != null) {
30730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                showSSLCertificate(tab);
30740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            }
30750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }
30760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
30770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                });
30780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
30790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
30800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mPageInfoDialog = alertDialogBuilder.show();
30810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
30820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
30830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project       /**
30840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Displays the main top-level page SSL certificate dialog
30850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * (accessible from the Page-Info dialog).
30860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param tab The tab to show certificate for.
30870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
308822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private void showSSLCertificate(final Tab tab) {
30890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final View certificateView =
30900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                inflateCertificateView(tab.getWebView().getCertificate());
30910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (certificateView == null) {
30920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
30930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
30940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
30950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        LayoutInflater factory = LayoutInflater.from(this);
30960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
30970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final LinearLayout placeholder =
30980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                (LinearLayout)certificateView.findViewById(R.id.placeholder);
30990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
31000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        LinearLayout ll = (LinearLayout) factory.inflate(
31010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            R.layout.ssl_success, placeholder);
31020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        ((TextView)ll.findViewById(R.id.success))
31030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            .setText(R.string.ssl_certificate_is_valid);
31040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
31050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mSSLCertificateView = tab;
31060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mSSLCertificateDialog =
31070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            new AlertDialog.Builder(this)
31080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setTitle(R.string.ssl_certificate).setIcon(
31090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    R.drawable.ic_dialog_browser_certificate_secure)
31100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setView(certificateView)
31110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setPositiveButton(R.string.ok,
31120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new DialogInterface.OnClickListener() {
31130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            public void onClick(DialogInterface dialog,
31140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    int whichButton) {
31150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateDialog = null;
31160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateView = null;
31170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
31180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                showPageInfo(tab, false);
31190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            }
31200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        })
31210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setOnCancelListener(
31220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new DialogInterface.OnCancelListener() {
31230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            public void onCancel(DialogInterface dialog) {
31240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateDialog = null;
31250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateView = null;
31260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
31270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                showPageInfo(tab, false);
31280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            }
31290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        })
31300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .show();
31310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
31320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
31330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
31340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Displays the SSL error certificate dialog.
31350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param view The target web-view.
31360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param handler The SSL error handler responsible for cancelling the
31370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * connection that resulted in an SSL error or proceeding per user request.
31380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param error The SSL error object.
31390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
314022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void showSSLCertificateOnError(
31410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final WebView view, final SslErrorHandler handler, final SslError error) {
31420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
31430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final View certificateView =
31440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            inflateCertificateView(error.getCertificate());
31450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (certificateView == null) {
31460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
31470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
31480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
31490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        LayoutInflater factory = LayoutInflater.from(this);
31500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
31510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final LinearLayout placeholder =
31520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                (LinearLayout)certificateView.findViewById(R.id.placeholder);
31530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
31540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (error.hasError(SslError.SSL_UNTRUSTED)) {
31550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            LinearLayout ll = (LinearLayout)factory
31560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .inflate(R.layout.ssl_warning, placeholder);
31570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((TextView)ll.findViewById(R.id.warning))
31580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setText(R.string.ssl_untrusted);
31590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
31600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
31610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (error.hasError(SslError.SSL_IDMISMATCH)) {
31620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            LinearLayout ll = (LinearLayout)factory
31630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .inflate(R.layout.ssl_warning, placeholder);
31640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((TextView)ll.findViewById(R.id.warning))
31650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setText(R.string.ssl_mismatch);
31660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
31670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
31680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (error.hasError(SslError.SSL_EXPIRED)) {
31690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            LinearLayout ll = (LinearLayout)factory
31700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .inflate(R.layout.ssl_warning, placeholder);
31710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((TextView)ll.findViewById(R.id.warning))
31720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setText(R.string.ssl_expired);
31730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
31740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
31750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (error.hasError(SslError.SSL_NOTYETVALID)) {
31760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            LinearLayout ll = (LinearLayout)factory
31770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .inflate(R.layout.ssl_warning, placeholder);
31780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((TextView)ll.findViewById(R.id.warning))
31790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setText(R.string.ssl_not_yet_valid);
31800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
31810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
31820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mSSLCertificateOnErrorHandler = handler;
31830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mSSLCertificateOnErrorView = view;
31840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mSSLCertificateOnErrorError = error;
31850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mSSLCertificateOnErrorDialog =
31860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            new AlertDialog.Builder(this)
31870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setTitle(R.string.ssl_certificate).setIcon(
31880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    R.drawable.ic_dialog_browser_certificate_partially_secure)
31890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setView(certificateView)
31900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setPositiveButton(R.string.ok,
31910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new DialogInterface.OnClickListener() {
31920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            public void onClick(DialogInterface dialog,
31930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    int whichButton) {
31940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorDialog = null;
31950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorView = null;
31960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorHandler = null;
31970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorError = null;
31980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
319922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                view.getWebViewClient().onReceivedSslError(
320022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                                view, handler, error);
32010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            }
32020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        })
32030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                 .setNeutralButton(R.string.page_info_view,
32040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new DialogInterface.OnClickListener() {
32050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            public void onClick(DialogInterface dialog,
32060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    int whichButton) {
32070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorDialog = null;
32080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
32090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                // do not clear the dialog state: we will
32100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                // need to show the dialog again once the
32110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                // user is done exploring the page-info details
32120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
32130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                showPageInfo(mTabControl.getTabFromView(view),
32140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        true);
32150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            }
32160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        })
32170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setOnCancelListener(
32180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new DialogInterface.OnCancelListener() {
32190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            public void onCancel(DialogInterface dialog) {
32200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorDialog = null;
32210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorView = null;
32220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorHandler = null;
32230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorError = null;
32240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
322522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                view.getWebViewClient().onReceivedSslError(
322622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                                view, handler, error);
32270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            }
32280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        })
32290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .show();
32300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
32310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
32320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
32330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Inflates the SSL certificate view (helper method).
32340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param certificate The SSL certificate.
32350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @return The resultant certificate view with issued-to, issued-by,
32360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * issued-on, expires-on, and possibly other fields set.
32370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * If the input certificate is null, returns null.
32380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
32390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private View inflateCertificateView(SslCertificate certificate) {
32400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (certificate == null) {
32410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return null;
32420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
32430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
32440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        LayoutInflater factory = LayoutInflater.from(this);
32450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
32460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        View certificateView = factory.inflate(
32470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            R.layout.ssl_certificate, null);
32480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
32490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // issued to:
32500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        SslCertificate.DName issuedTo = certificate.getIssuedTo();
32510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (issuedTo != null) {
32520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((TextView) certificateView.findViewById(R.id.to_common))
32530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setText(issuedTo.getCName());
32540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((TextView) certificateView.findViewById(R.id.to_org))
32550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setText(issuedTo.getOName());
32560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((TextView) certificateView.findViewById(R.id.to_org_unit))
32570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setText(issuedTo.getUName());
32580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
32590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
32600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // issued by:
32610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        SslCertificate.DName issuedBy = certificate.getIssuedBy();
32620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (issuedBy != null) {
32630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((TextView) certificateView.findViewById(R.id.by_common))
32640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setText(issuedBy.getCName());
32650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((TextView) certificateView.findViewById(R.id.by_org))
32660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setText(issuedBy.getOName());
32670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((TextView) certificateView.findViewById(R.id.by_org_unit))
32680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setText(issuedBy.getUName());
32690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
32700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
32710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // issued on:
327295a2e4ab94514e4e41033b0d27a0e66855cff8ebBrian Carlstrom        String issuedOn = formatCertificateDate(
327395a2e4ab94514e4e41033b0d27a0e66855cff8ebBrian Carlstrom            certificate.getValidNotBeforeDate());
32740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        ((TextView) certificateView.findViewById(R.id.issued_on))
32750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            .setText(issuedOn);
32760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
32770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // expires on:
327895a2e4ab94514e4e41033b0d27a0e66855cff8ebBrian Carlstrom        String expiresOn = formatCertificateDate(
327995a2e4ab94514e4e41033b0d27a0e66855cff8ebBrian Carlstrom            certificate.getValidNotAfterDate());
32800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        ((TextView) certificateView.findViewById(R.id.expires_on))
32810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            .setText(expiresOn);
32820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
32830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return certificateView;
32840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
32850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
32860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
328795a2e4ab94514e4e41033b0d27a0e66855cff8ebBrian Carlstrom     * Formats the certificate date to a properly localized date string.
32880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @return Properly localized version of the certificate date string and
328995a2e4ab94514e4e41033b0d27a0e66855cff8ebBrian Carlstrom     * the "" if it fails to localize.
32900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
329195a2e4ab94514e4e41033b0d27a0e66855cff8ebBrian Carlstrom    private String formatCertificateDate(Date certificateDate) {
329295a2e4ab94514e4e41033b0d27a0e66855cff8ebBrian Carlstrom      if (certificateDate == null) {
329395a2e4ab94514e4e41033b0d27a0e66855cff8ebBrian Carlstrom          return "";
32940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project      }
329595a2e4ab94514e4e41033b0d27a0e66855cff8ebBrian Carlstrom      String formattedDate = DateFormat.getDateFormat(this).format(certificateDate);
329695a2e4ab94514e4e41033b0d27a0e66855cff8ebBrian Carlstrom      if (formattedDate == null) {
329795a2e4ab94514e4e41033b0d27a0e66855cff8ebBrian Carlstrom          return "";
329895a2e4ab94514e4e41033b0d27a0e66855cff8ebBrian Carlstrom      }
329995a2e4ab94514e4e41033b0d27a0e66855cff8ebBrian Carlstrom      return formattedDate;
33000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
33010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
33020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
33030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Displays an http-authentication dialog.
33040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
330522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void showHttpAuthentication(final HttpAuthHandler handler,
33060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            final String host, final String realm, final String title,
33070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            final String name, final String password, int focusId) {
33080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        LayoutInflater factory = LayoutInflater.from(this);
33090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final View v = factory
33100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .inflate(R.layout.http_authentication, null);
33110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (name != null) {
33120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((EditText) v.findViewById(R.id.username_edit)).setText(name);
33130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
33140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (password != null) {
33150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((EditText) v.findViewById(R.id.password_edit)).setText(password);
33160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
33170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
33180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String titleText = title;
33190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (titleText == null) {
33200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            titleText = getText(R.string.sign_in_to).toString().replace(
33210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    "%s1", host).replace("%s2", realm);
33220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
33230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
33240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mHttpAuthHandler = handler;
33250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        AlertDialog dialog = new AlertDialog.Builder(this)
33260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setTitle(titleText)
33270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setIcon(android.R.drawable.ic_dialog_alert)
33280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setView(v)
33290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setPositiveButton(R.string.action,
33300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new DialogInterface.OnClickListener() {
33310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                             public void onClick(DialogInterface dialog,
33320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                     int whichButton) {
33330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                String nm = ((EditText) v
33340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        .findViewById(R.id.username_edit))
33350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        .getText().toString();
33360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                String pw = ((EditText) v
33370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        .findViewById(R.id.password_edit))
33380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        .getText().toString();
33390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                BrowserActivity.this.setHttpAuthUsernamePassword
33400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        (host, realm, nm, pw);
33410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                handler.proceed(nm, pw);
33420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mHttpAuthenticationDialog = null;
33430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mHttpAuthHandler = null;
33440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            }})
33450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setNegativeButton(R.string.cancel,
33460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new DialogInterface.OnClickListener() {
33470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            public void onClick(DialogInterface dialog,
33480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    int whichButton) {
33490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                handler.cancel();
33500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                BrowserActivity.this.resetTitleAndRevertLockIcon();
33510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mHttpAuthenticationDialog = null;
33520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mHttpAuthHandler = null;
33530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            }})
33540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setOnCancelListener(new DialogInterface.OnCancelListener() {
33550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        public void onCancel(DialogInterface dialog) {
33560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            handler.cancel();
33570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            BrowserActivity.this.resetTitleAndRevertLockIcon();
33580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            mHttpAuthenticationDialog = null;
33590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            mHttpAuthHandler = null;
33600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }})
33610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .create();
33620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Make the IME appear when the dialog is displayed if applicable.
33630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        dialog.getWindow().setSoftInputMode(
33640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);
33650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        dialog.show();
33660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (focusId != 0) {
33670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            dialog.findViewById(focusId).requestFocus();
33680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
33690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            v.findViewById(R.id.username_edit).requestFocus();
33700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
33710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mHttpAuthenticationDialog = dialog;
33720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
33730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
33740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public int getProgress() {
33750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebView w = mTabControl.getCurrentWebView();
33760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (w != null) {
33770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return w.getProgress();
33780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
33790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return 100;
33800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
33810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
33820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
33830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
33840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Set HTTP authentication password.
33850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *
33860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param host The host for the password
33870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param realm The realm for the password
33880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param username The username for the password. If it is null, it means
33890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *            password can't be saved.
33900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param password The password
33910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
33920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public void setHttpAuthUsernamePassword(String host, String realm,
33930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                            String username,
33940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                            String password) {
339595a53b25504f12c3a5f8ecbbfcff7ac1dc047e4fSteve Block        WebView w = getTopWindow();
33960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (w != null) {
33970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            w.setHttpAuthUsernamePassword(host, realm, username, password);
33980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
33990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
34000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
34010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
34020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * connectivity manager says net has come or gone... inform the user
34030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param up true if net has come up, false if net has gone down
34040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
34050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public void onNetworkToggle(boolean up) {
34060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (up == mIsNetworkUp) {
34070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
34080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else if (up) {
34090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mIsNetworkUp = true;
34100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (mAlertDialog != null) {
34110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mAlertDialog.cancel();
34120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mAlertDialog = null;
34130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
34140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
34150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mIsNetworkUp = false;
3416eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott            if (mInLoad) {
3417eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott                createAndShowNetworkDialog();
3418eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott           }
34190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
34200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebView w = mTabControl.getCurrentWebView();
34210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (w != null) {
34220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            w.setNetworkAvailable(up);
34230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
34240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
34250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
342622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    boolean isNetworkUp() {
342722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return mIsNetworkUp;
342822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
342922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
3430eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott    // This method shows the network dialog alerting the user that the net is
3431eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott    // down. It will only show the dialog if mAlertDialog is null.
3432eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott    private void createAndShowNetworkDialog() {
3433eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott        if (mAlertDialog == null) {
3434eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott            mAlertDialog = new AlertDialog.Builder(this)
3435eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott                    .setTitle(R.string.loadSuspendedTitle)
3436eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott                    .setMessage(R.string.loadSuspended)
3437eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott                    .setPositiveButton(R.string.ok, null)
3438eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott                    .show();
3439eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott        }
3440eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott    }
3441eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott
34420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    @Override
34430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    protected void onActivityResult(int requestCode, int resultCode,
34440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    Intent intent) {
3445bb394f3e134b6e5898ef7ae861b75e95e618688fGrace Kloba        if (getTopWindow() == null) return;
3446bb394f3e134b6e5898ef7ae861b75e95e618688fGrace Kloba
34470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        switch (requestCode) {
34480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case COMBO_PAGE:
34490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (resultCode == RESULT_OK && intent != null) {
34500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    String data = intent.getAction();
34510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    Bundle extras = intent.getExtras();
34520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    if (extras != null && extras.getBoolean("new_window", false)) {
345325d3547e0df084f963e38c6a93c99b02bd619de3Leon Scroggins                        openTab(data);
34540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    } else {
345522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        final Tab currentTab =
34560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mTabControl.getCurrentTab();
34571f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                        dismissSubWindow(currentTab);
34581f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                        if (data != null && data.length() != 0) {
345992472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins                            loadUrl(getTopWindow(), data);
34600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }
34610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
34620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
3463fde9746ac3055848e110c35f19ec5893c621f766Leon Scroggins                // Deliberately fall through to PREFERENCES_PAGE, since the
3464fde9746ac3055848e110c35f19ec5893c621f766Leon Scroggins                // same extra may be attached to the COMBO_PAGE
3465fde9746ac3055848e110c35f19ec5893c621f766Leon Scroggins            case PREFERENCES_PAGE:
3466fde9746ac3055848e110c35f19ec5893c621f766Leon Scroggins                if (resultCode == RESULT_OK && intent != null) {
3467fde9746ac3055848e110c35f19ec5893c621f766Leon Scroggins                    String action = intent.getStringExtra(Intent.EXTRA_TEXT);
3468fde9746ac3055848e110c35f19ec5893c621f766Leon Scroggins                    if (BrowserSettings.PREF_CLEAR_HISTORY.equals(action)) {
3469fde9746ac3055848e110c35f19ec5893c621f766Leon Scroggins                        mTabControl.removeParentChildRelationShips();
3470fde9746ac3055848e110c35f19ec5893c621f766Leon Scroggins                    }
3471fde9746ac3055848e110c35f19ec5893c621f766Leon Scroggins                }
34720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
34738d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins            // Choose a file from the file picker.
34748d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins            case FILE_SELECTED:
34758d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins                if (null == mUploadMessage) break;
34768d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins                Uri result = intent == null || resultCode != RESULT_OK ? null
34778d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins                        : intent.getData();
34788d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins                mUploadMessage.onReceiveValue(result);
34798d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins                mUploadMessage = null;
34808d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins                break;
34810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            default:
34820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
34830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
3484304442375719effd41dbd53ae62de7a8d0cec7d9Leon Scroggins        getTopWindow().requestFocus();
34850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
34860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
34870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /*
34880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * This method is called as a result of the user selecting the options
3489f08809b2cf7e502fef5965691a7fb6d7cf0322afLeon Scroggins     * menu to see the download window. It shows the download window on top of
3490f08809b2cf7e502fef5965691a7fb6d7cf0322afLeon Scroggins     * the current window.
34910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
3492f08809b2cf7e502fef5965691a7fb6d7cf0322afLeon Scroggins    private void viewDownloads(Uri downloadRecord) {
34930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        Intent intent = new Intent(this,
34940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                BrowserDownloadPage.class);
34950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        intent.setData(downloadRecord);
349622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        startActivityForResult(intent, BrowserActivity.DOWNLOAD_PAGE);
34970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
34980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
34990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
3500160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins    /**
3501160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins     * Open the Go page.
3502160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins     * @param startWithHistory If true, open starting on the history tab.
3503160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins     *                         Otherwise, start with the bookmarks tab.
3504160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins     */
3505304442375719effd41dbd53ae62de7a8d0cec7d9Leon Scroggins    /* package */ void bookmarksOrHistoryPicker(boolean startWithHistory) {
35060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebView current = mTabControl.getCurrentWebView();
35070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (current == null) {
35080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
35090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
35100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        Intent intent = new Intent(this,
35110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                CombinedBookmarkHistoryActivity.class);
35120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String title = current.getTitle();
35130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String url = current.getUrl();
3514dcc2b6f08dd5677bc6ba761a9ba6f1c655113051Ben Murdoch        Bitmap thumbnail = createScreenshot(current);
3515dcc2b6f08dd5677bc6ba761a9ba6f1c655113051Ben Murdoch
35160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Just in case the user opens bookmarks before a page finishes loading
35170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // so the current history item, and therefore the page, is null.
35180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (null == url) {
35190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            url = mLastEnteredUrl;
35200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // This can happen.
35210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (null == url) {
35220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                url = mSettings.getHomePage();
35230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
35240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
35250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // In case the web page has not yet received its associated title.
35260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (title == null) {
35270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            title = url;
35280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
35290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        intent.putExtra("title", title);
35300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        intent.putExtra("url", url);
3531dcc2b6f08dd5677bc6ba761a9ba6f1c655113051Ben Murdoch        intent.putExtra("thumbnail", thumbnail);
3532304442375719effd41dbd53ae62de7a8d0cec7d9Leon Scroggins        // Disable opening in a new window if we have maxed out the windows
353322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        intent.putExtra("disable_new_window", !mTabControl.canCreateNewTab());
35343918d4443ff38ef1870e02aa51a8b29f8352bb1aPatrick Scott        intent.putExtra("touch_icon_url", current.getTouchIconUrl());
35350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (startWithHistory) {
35360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            intent.putExtra(CombinedBookmarkHistoryActivity.STARTING_TAB,
35370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    CombinedBookmarkHistoryActivity.HISTORY_TAB);
35380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
35390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        startActivityForResult(intent, COMBO_PAGE);
35400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
35410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
35420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Called when loading from context menu or LOAD_URL message
354392472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins    private void loadUrlFromContext(WebView view, String url) {
35440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // In case the user enters nothing.
35450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (url != null && url.length() != 0 && view != null) {
35460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            url = smartUrlFilter(url);
354722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (!view.getWebViewClient().shouldOverrideUrlLoading(view, url)) {
354892472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins                loadUrl(view, url);
35490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
35500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
35510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
35520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
355392472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins    /**
355492472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins     * Load the URL into the given WebView and update the title bar
355592472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins     * to reflect the new load.  Call this instead of WebView.loadUrl
355692472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins     * directly.
355792472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins     * @param view The WebView used to load url.
355892472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins     * @param url The URL to load.
355992472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins     */
356092472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins    private void loadUrl(WebView view, String url) {
356192472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins        updateTitleBarForNewLoad(view, url);
356292472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins        view.loadUrl(url);
356392472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins    }
356492472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins
356592472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins    /**
356692472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins     * Load UrlData into a Tab and update the title bar to reflect the new
356792472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins     * load.  Call this instead of UrlData.loadIn directly.
356892472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins     * @param t The Tab used to load.
356992472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins     * @param data The UrlData being loaded.
357092472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins     */
357192472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins    private void loadUrlDataIn(Tab t, UrlData data) {
357292472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins        updateTitleBarForNewLoad(t.getWebView(), data.mUrl);
357392472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins        data.loadIn(t);
357492472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins    }
357592472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins
357692472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins    /**
357792472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins     * If the WebView is the top window, update the title bar to reflect
357892472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins     * loading the new URL.  i.e. set its text, clear the favicon (which
357992472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins     * will be set once the page begins loading), and set the progress to
358092472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins     * INITIAL_PROGRESS to show that the page has begun to load. Called
358192472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins     * by loadUrl and loadUrlDataIn.
358292472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins     * @param view The WebView that is starting a load.
358392472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins     * @param url The URL that is being loaded.
358492472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins     */
358592472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins    private void updateTitleBarForNewLoad(WebView view, String url) {
358692472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins        if (view == getTopWindow()) {
358792472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins            setUrlTitle(url, null);
358892472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins            setFavicon(null);
358992472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins            onProgressChanged(view, INITIAL_PROGRESS);
359092472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins        }
359192472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins    }
359292472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins
35930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private String smartUrlFilter(Uri inUri) {
35940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (inUri != null) {
35950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return smartUrlFilter(inUri.toString());
35960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
35970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return null;
35980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
35990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
3600b34f87a2e13af13d697130482af01b537ab7c5fdFeng Qian    protected static final Pattern ACCEPTED_URI_SCHEMA = Pattern.compile(
36010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            "(?i)" + // switch on case insensitive matching
36020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            "(" +    // begin group for schema
36030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            "(?:http|https|file):\\/\\/" +
360425ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima            "|(?:inline|data|about|content|javascript):" +
36050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ")" +
36060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            "(.*)" );
36070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
36080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
36090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Attempts to determine whether user input is a URL or search
36100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * terms.  Anything with a space is passed to search.
36110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *
36120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Converts to lowercase any mistakenly uppercased schema (i.e.,
36130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * "Http://" converts to "http://"
36140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *
36150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @return Original or modified URL
36160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *
36170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
36180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    String smartUrlFilter(String url) {
36190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
36200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String inUrl = url.trim();
36210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        boolean hasSpace = inUrl.indexOf(' ') != -1;
36220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
36230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        Matcher matcher = ACCEPTED_URI_SCHEMA.matcher(inUrl);
36240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (matcher.matches()) {
36250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // force scheme to lowercase
36260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            String scheme = matcher.group(1);
36270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            String lcScheme = scheme.toLowerCase();
36280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (!lcScheme.equals(scheme)) {
3629123ecfb21e7ca670e3d04efe58780b3bac54a9a1Mitsuru Oshima                inUrl = lcScheme + matcher.group(2);
3630123ecfb21e7ca670e3d04efe58780b3bac54a9a1Mitsuru Oshima            }
3631123ecfb21e7ca670e3d04efe58780b3bac54a9a1Mitsuru Oshima            if (hasSpace) {
3632123ecfb21e7ca670e3d04efe58780b3bac54a9a1Mitsuru Oshima                inUrl = inUrl.replace(" ", "%20");
36330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
36340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return inUrl;
36350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
36360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (hasSpace) {
3637565505b1a2c1d3099496af5910760087602e994aSatish Sampath            // FIXME: Is this the correct place to add to searches?
3638565505b1a2c1d3099496af5910760087602e994aSatish Sampath            // what if someone else calls this function?
3639565505b1a2c1d3099496af5910760087602e994aSatish Sampath            int shortcut = parseUrlShortcut(inUrl);
3640565505b1a2c1d3099496af5910760087602e994aSatish Sampath            if (shortcut != SHORTCUT_INVALID) {
3641565505b1a2c1d3099496af5910760087602e994aSatish Sampath                Browser.addSearchUrl(mResolver, inUrl);
3642565505b1a2c1d3099496af5910760087602e994aSatish Sampath                String query = inUrl.substring(2);
3643565505b1a2c1d3099496af5910760087602e994aSatish Sampath                switch (shortcut) {
3644565505b1a2c1d3099496af5910760087602e994aSatish Sampath                case SHORTCUT_GOOGLE_SEARCH:
364547fdfdb989ffb79590a39c40792be995de32e521Grace Kloba                    return URLUtil.composeSearchUrl(query, QuickSearch_G, QUERY_PLACE_HOLDER);
3646565505b1a2c1d3099496af5910760087602e994aSatish Sampath                case SHORTCUT_WIKIPEDIA_SEARCH:
3647565505b1a2c1d3099496af5910760087602e994aSatish Sampath                    return URLUtil.composeSearchUrl(query, QuickSearch_W, QUERY_PLACE_HOLDER);
3648565505b1a2c1d3099496af5910760087602e994aSatish Sampath                case SHORTCUT_DICTIONARY_SEARCH:
3649565505b1a2c1d3099496af5910760087602e994aSatish Sampath                    return URLUtil.composeSearchUrl(query, QuickSearch_D, QUERY_PLACE_HOLDER);
3650565505b1a2c1d3099496af5910760087602e994aSatish Sampath                case SHORTCUT_GOOGLE_MOBILE_LOCAL_SEARCH:
36510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // FIXME: we need location in this case
3652565505b1a2c1d3099496af5910760087602e994aSatish Sampath                    return URLUtil.composeSearchUrl(query, QuickSearch_L, QUERY_PLACE_HOLDER);
36530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
36540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
36550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
36565ee906c089567bca705e18561357510d7b55cb5aDan Egnor            if (Patterns.WEB_URL.matcher(inUrl).matches()) {
36570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                return URLUtil.guessUrl(inUrl);
36580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
36590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
36600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
36610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        Browser.addSearchUrl(mResolver, inUrl);
366247fdfdb989ffb79590a39c40792be995de32e521Grace Kloba        return URLUtil.composeSearchUrl(inUrl, QuickSearch_G, QUERY_PLACE_HOLDER);
36630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
36640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
3665bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch    /* package */ void setShouldShowErrorConsole(boolean flag) {
3666bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch        if (flag == mShouldShowErrorConsole) {
3667bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch            // Nothing to do.
3668bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch            return;
3669bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch        }
3670bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch
3671bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch        mShouldShowErrorConsole = flag;
3672bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch
367322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        ErrorConsoleView errorConsole = mTabControl.getCurrentTab()
367422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                .getErrorConsole(true);
3675bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch
3676bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch        if (flag) {
3677bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch            // Setting the show state of the console will cause it's the layout to be inflated.
3678bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch            if (errorConsole.numberOfErrors() > 0) {
3679bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch                errorConsole.showConsole(ErrorConsoleView.SHOW_MINIMIZED);
3680bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch            } else {
3681bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch                errorConsole.showConsole(ErrorConsoleView.SHOW_NONE);
3682bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch            }
3683bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch
3684bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch            // Now we can add it to the main view.
3685bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch            mErrorConsoleContainer.addView(errorConsole,
368615b8ec6b226f4d57307716e1f495e10a91f8cbf4Romain Guy                    new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
3687bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch                                                  ViewGroup.LayoutParams.WRAP_CONTENT));
3688bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch        } else {
3689bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch            mErrorConsoleContainer.removeView(errorConsole);
3690bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch        }
3691bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch
3692bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch    }
3693bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch
369422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    boolean shouldShowErrorConsole() {
369522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return mShouldShowErrorConsole;
369622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
369722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
3698163ab74e2f85b53a1a374c49677073fb64d35f28Andrei Popescu    private void setStatusBarVisibility(boolean visible) {
3699163ab74e2f85b53a1a374c49677073fb64d35f28Andrei Popescu        int flag = visible ? 0 : WindowManager.LayoutParams.FLAG_FULLSCREEN;
3700163ab74e2f85b53a1a374c49677073fb64d35f28Andrei Popescu        getWindow().setFlags(flag, WindowManager.LayoutParams.FLAG_FULLSCREEN);
3701163ab74e2f85b53a1a374c49677073fb64d35f28Andrei Popescu    }
3702163ab74e2f85b53a1a374c49677073fb64d35f28Andrei Popescu
370356199cc25e7ee0455ec2a8099098b66b8554f677Andrei Popescu
370456199cc25e7ee0455ec2a8099098b66b8554f677Andrei Popescu    private void sendNetworkType(String type, String subtype) {
370556199cc25e7ee0455ec2a8099098b66b8554f677Andrei Popescu        WebView w = mTabControl.getCurrentWebView();
370656199cc25e7ee0455ec2a8099098b66b8554f677Andrei Popescu        if (w != null) {
370756199cc25e7ee0455ec2a8099098b66b8554f677Andrei Popescu            w.setNetworkType(type, subtype);
370856199cc25e7ee0455ec2a8099098b66b8554f677Andrei Popescu        }
370956199cc25e7ee0455ec2a8099098b66b8554f677Andrei Popescu    }
371056199cc25e7ee0455ec2a8099098b66b8554f677Andrei Popescu
371130995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu    private void packageChanged(String packageName, boolean wasAdded) {
371230995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu        WebView w = mTabControl.getCurrentWebView();
371330995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu        if (w == null) {
371430995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu            return;
371530995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu        }
371630995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu
371730995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu        if (wasAdded) {
371830995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu            w.addPackageName(packageName);
371930995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu        } else {
372030995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu            w.removePackageName(packageName);
372130995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu        }
372230995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu    }
372330995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu
372430995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu    private void addPackageNames(Set<String> packageNames) {
372530995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu        WebView w = mTabControl.getCurrentWebView();
372630995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu        if (w == null) {
372730995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu            return;
372830995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu        }
372930995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu
373030995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu        w.addPackageNames(packageNames);
373130995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu    }
373230995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu
373330995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu    private void getInstalledPackages() {
373430995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu        AsyncTask<Void, Void, Set<String> > task =
373530995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu            new AsyncTask<Void, Void, Set<String> >() {
373630995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu            protected Set<String> doInBackground(Void... unused) {
373730995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu                Set<String> installedPackages = new HashSet<String>();
373830995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu                PackageManager pm = BrowserActivity.this.getPackageManager();
373930995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu                if (pm != null) {
374030995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu                    List<PackageInfo> packages = pm.getInstalledPackages(0);
374130995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu                    for (PackageInfo p : packages) {
374230995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu                        if (BrowserActivity.this.sGoogleApps.contains(p.packageName)) {
374330995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu                            installedPackages.add(p.packageName);
374430995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu                        }
374530995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu                    }
374630995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu                }
374730995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu
374830995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu                return installedPackages;
374930995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu            }
375030995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu
375130995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu            // Executes on the UI thread
375230995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu            protected void onPostExecute(Set<String> installedPackages) {
375330995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu                addPackageNames(installedPackages);
375430995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu            }
375530995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu        };
375630995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu        task.execute();
375730995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu    }
375830995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu
3759eb6eef4c45df2d65c3e70660493a147a2be405e3Grace Kloba    final static int LOCK_ICON_UNSECURE = 0;
3760eb6eef4c45df2d65c3e70660493a147a2be405e3Grace Kloba    final static int LOCK_ICON_SECURE   = 1;
3761eb6eef4c45df2d65c3e70660493a147a2be405e3Grace Kloba    final static int LOCK_ICON_MIXED    = 2;
37620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
37630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private BrowserSettings mSettings;
37640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private TabControl      mTabControl;
37650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private ContentResolver mResolver;
37660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private FrameLayout     mContentView;
3767adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu    private View            mCustomView;
3768adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu    private FrameLayout     mCustomViewContainer;
3769c9b5556351b59caec77b4eec1ad30652fec6a4d9Andrei Popescu    private WebChromeClient.CustomViewCallback mCustomViewCallback;
37700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
37710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // FIXME, temp address onPrepareMenu performance problem. When we move everything out of
37720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // view, we should rewrite this.
37730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private int mCurrentMenuState = 0;
37740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private int mMenuState = R.id.MAIN_MENU;
3775adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu    private int mOldMenuState = EMPTY_MENU;
37760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private static final int EMPTY_MENU = -1;
37770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private Menu mMenu;
37780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
37790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private FindDialog mFindDialog;
37800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Used to prevent chording to result in firing two shortcuts immediately
37810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // one after another.  Fixes bug 1211714.
37820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    boolean mCanChord;
37830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
37840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private boolean mInLoad;
37850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private boolean mIsNetworkUp;
3786b7cc8b439dc595dc48e1c2183b35d23ad72dfbe5Ben Murdoch    private boolean mDidStopLoad;
37870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
37881f10cbfca5bf96e1466e0ed3ce1dbcd6fcfd0608Cary Clark    /* package */ boolean mActivityInPause = true;
37890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
37900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private boolean mMenuIsDown;
37910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
37920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private static boolean mInTrace;
37930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
37940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Performance probe
37950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private static final int[] SYSTEM_CPU_FORMAT = new int[] {
37960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Process.PROC_SPACE_TERM | Process.PROC_COMBINE,
37970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Process.PROC_SPACE_TERM | Process.PROC_OUT_LONG, // 1: user time
37980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Process.PROC_SPACE_TERM | Process.PROC_OUT_LONG, // 2: nice time
37990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Process.PROC_SPACE_TERM | Process.PROC_OUT_LONG, // 3: sys time
38000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Process.PROC_SPACE_TERM | Process.PROC_OUT_LONG, // 4: idle time
38010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Process.PROC_SPACE_TERM | Process.PROC_OUT_LONG, // 5: iowait time
38020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Process.PROC_SPACE_TERM | Process.PROC_OUT_LONG, // 6: irq time
38030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Process.PROC_SPACE_TERM | Process.PROC_OUT_LONG  // 7: softirq time
38040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    };
38050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
38060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private long mStart;
38070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private long mProcessStart;
38080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private long mUserStart;
38090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private long mSystemStart;
38100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private long mIdleStart;
38110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private long mIrqStart;
38120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
38130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private long mUiStart;
38140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
38150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private Drawable    mMixLockIcon;
38160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private Drawable    mSecLockIcon;
38170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
38180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /* hold a ref so we can auto-cancel if necessary */
38190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private AlertDialog mAlertDialog;
38200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
38210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // The up-to-date URL and title (these can be different from those stored
38220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // in WebView, since it takes some time for the information in WebView to
38230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // get updated)
38240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private String mUrl;
38250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private String mTitle;
38260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
38270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // As PageInfo has different style for landscape / portrait, we have
38280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // to re-open it when configuration changed
38290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private AlertDialog mPageInfoDialog;
383022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private Tab mPageInfoView;
38310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // If the Page-Info dialog is launched from the SSL-certificate-on-error
38320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // dialog, we should not just dismiss it, but should get back to the
38330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // SSL-certificate-on-error dialog. This flag is used to store this state
3834c7b92f811dfa3572578ddc6714c98a03936d9ce5Leon Scroggins    private boolean mPageInfoFromShowSSLCertificateOnError;
38350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
38360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // as SSLCertificateOnError has different style for landscape / portrait,
38370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // we have to re-open it when configuration changed
38380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private AlertDialog mSSLCertificateOnErrorDialog;
38390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private WebView mSSLCertificateOnErrorView;
38400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private SslErrorHandler mSSLCertificateOnErrorHandler;
38410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private SslError mSSLCertificateOnErrorError;
38420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
38430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // as SSLCertificate has different style for landscape / portrait, we
38440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // have to re-open it when configuration changed
38450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private AlertDialog mSSLCertificateDialog;
384622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private Tab mSSLCertificateView;
38470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
38480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // as HttpAuthentication has different style for landscape / portrait, we
38490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // have to re-open it when configuration changed
38500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private AlertDialog mHttpAuthenticationDialog;
38510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private HttpAuthHandler mHttpAuthHandler;
38520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
38530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /*package*/ static final FrameLayout.LayoutParams COVER_SCREEN_PARAMS =
38540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                            new FrameLayout.LayoutParams(
385515b8ec6b226f4d57307716e1f495e10a91f8cbf4Romain Guy                                            ViewGroup.LayoutParams.MATCH_PARENT,
385615b8ec6b226f4d57307716e1f495e10a91f8cbf4Romain Guy                                            ViewGroup.LayoutParams.MATCH_PARENT);
3857adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu    /*package*/ static final FrameLayout.LayoutParams COVER_SCREEN_GRAVITY_CENTER =
3858adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu                                            new FrameLayout.LayoutParams(
385915b8ec6b226f4d57307716e1f495e10a91f8cbf4Romain Guy                                            ViewGroup.LayoutParams.MATCH_PARENT,
386015b8ec6b226f4d57307716e1f495e10a91f8cbf4Romain Guy                                            ViewGroup.LayoutParams.MATCH_PARENT,
3861adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu                                            Gravity.CENTER);
386247fdfdb989ffb79590a39c40792be995de32e521Grace Kloba    // Google search
386347fdfdb989ffb79590a39c40792be995de32e521Grace Kloba    final static String QuickSearch_G = "http://www.google.com/m?q=%s";
38640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Wikipedia search
38650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    final static String QuickSearch_W = "http://en.wikipedia.org/w/index.php?search=%s&go=Go";
38660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Dictionary search
38670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    final static String QuickSearch_D = "http://dictionary.reference.com/search?q=%s";
38680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Google Mobile Local search
38690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    final static String QuickSearch_L = "http://www.google.com/m/search?site=local&q=%s&near=mountain+view";
38700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
38710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    final static String QUERY_PLACE_HOLDER = "%s";
38720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
38730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // "source" parameter for Google search through search key
38740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    final static String GOOGLE_SEARCH_SOURCE_SEARCHKEY = "browser-key";
38750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // "source" parameter for Google search through goto menu
38760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    final static String GOOGLE_SEARCH_SOURCE_GOTO = "browser-goto";
38770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // "source" parameter for Google search through simplily type
38780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    final static String GOOGLE_SEARCH_SOURCE_TYPE = "browser-type";
38790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // "source" parameter for Google search suggested by the browser
38800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    final static String GOOGLE_SEARCH_SOURCE_SUGGEST = "browser-suggest";
38810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // "source" parameter for Google search from unknown source
38820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    final static String GOOGLE_SEARCH_SOURCE_UNKNOWN = "unknown";
38830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
38840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private final static String LOGTAG = "browser";
38850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
38860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private String mLastEnteredUrl;
38870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
38880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private PowerManager.WakeLock mWakeLock;
38890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private final static int WAKELOCK_TIMEOUT = 5 * 60 * 1000; // 5 minutes
38900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
38910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private Toast mStopToast;
38920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
389368579393973f745fc65a2781061af9bb8f2d7020Leon Scroggins    private TitleBar mTitleBar;
389481db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins
3895bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch    private LinearLayout mErrorConsoleContainer = null;
3896bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch    private boolean mShouldShowErrorConsole = false;
3897bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch
38980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // As the ids are dynamically created, we can't guarantee that they will
38990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // be in sequence, so this static array maps ids to a window number.
39000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    final static private int[] WINDOW_SHORTCUT_ID_ARRAY =
39010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    { R.id.window_one_menu_id, R.id.window_two_menu_id, R.id.window_three_menu_id,
39020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project      R.id.window_four_menu_id, R.id.window_five_menu_id, R.id.window_six_menu_id,
39030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project      R.id.window_seven_menu_id, R.id.window_eight_menu_id };
39040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
39050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // monitor platform changes
39060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private IntentFilter mNetworkStateChangedFilter;
39070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private BroadcastReceiver mNetworkStateIntentReceiver;
39080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
3909b4da0ad0351996f639b50f9f29b123a9b5c24fd0Grace Kloba    private BroadcastReceiver mPackageInstallationReceiver;
3910b4da0ad0351996f639b50f9f29b123a9b5c24fd0Grace Kloba
3911a7611811e0d744a7220b7bf80c8f795af5ea53edBjorn Bringert    private SystemAllowGeolocationOrigins mSystemAllowGeolocationOrigins;
3912a7611811e0d744a7220b7bf80c8f795af5ea53edBjorn Bringert
39130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // activity requestCode
391478a98e459323f938e97789a6131beddbebb459ceNicolas Roard    final static int COMBO_PAGE                 = 1;
391578a98e459323f938e97789a6131beddbebb459ceNicolas Roard    final static int DOWNLOAD_PAGE              = 2;
391678a98e459323f938e97789a6131beddbebb459ceNicolas Roard    final static int PREFERENCES_PAGE           = 3;
39178d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins    final static int FILE_SELECTED              = 4;
39180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
3919540035dfd1347c78eeec10ec0847e18fcc50ef36Andrei Popescu    // the default <video> poster
3920540035dfd1347c78eeec10ec0847e18fcc50ef36Andrei Popescu    private Bitmap mDefaultVideoPoster;
3921540035dfd1347c78eeec10ec0847e18fcc50ef36Andrei Popescu    // the video progress view
3922540035dfd1347c78eeec10ec0847e18fcc50ef36Andrei Popescu    private View mVideoProgressView;
3923540035dfd1347c78eeec10ec0847e18fcc50ef36Andrei Popescu
392430995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu    // The Google packages we monitor for the navigator.isApplicationInstalled()
392530995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu    // API. Add as needed.
392630995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu    private static Set<String> sGoogleApps;
392730995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu    static {
392830995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu        sGoogleApps = new HashSet<String>();
392930995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu        sGoogleApps.add("com.google.android.youtube");
393030995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu    }
393130995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu
393225ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima    /**
393325ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima     * A UrlData class to abstract how the content will be set to WebView.
393425ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima     * This base class uses loadUrl to show the content.
393525ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima     */
39366eac63e78d43d04e31c4d16830c44c4d9df82639Leon Scroggins    /* package */ static class UrlData {
3937068e48b469f5abca53ee3da38f933cf2c25c93b8Grace Kloba        final String mUrl;
3938068e48b469f5abca53ee3da38f933cf2c25c93b8Grace Kloba        final Map<String, String> mHeaders;
393958d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        final Intent mVoiceIntent;
394060e095c190496d42327f8ec2ef990c044d15a76fGrace Kloba
394125ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima        UrlData(String url) {
394225ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima            this.mUrl = url;
3943068e48b469f5abca53ee3da38f933cf2c25c93b8Grace Kloba            this.mHeaders = null;
394458d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins            this.mVoiceIntent = null;
394525ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima        }
394660e095c190496d42327f8ec2ef990c044d15a76fGrace Kloba
394758d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        UrlData(String url, Map<String, String> headers, Intent intent) {
3948068e48b469f5abca53ee3da38f933cf2c25c93b8Grace Kloba            this.mUrl = url;
3949068e48b469f5abca53ee3da38f933cf2c25c93b8Grace Kloba            this.mHeaders = headers;
3950a1cc3fdce19a336c251297c61cd83ac6cf767cd1Leon Scroggins            if (RecognizerResultsIntent.ACTION_VOICE_SEARCH_RESULTS
3951a1cc3fdce19a336c251297c61cd83ac6cf767cd1Leon Scroggins                    .equals(intent.getAction())) {
395258d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins                this.mVoiceIntent = intent;
395358d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins            } else {
395458d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins                this.mVoiceIntent = null;
395558d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins            }
395660e095c190496d42327f8ec2ef990c044d15a76fGrace Kloba        }
395760e095c190496d42327f8ec2ef990c044d15a76fGrace Kloba
395825ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima        boolean isEmpty() {
395958d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins            return mVoiceIntent == null && (mUrl == null || mUrl.length() == 0);
396025ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima        }
396125ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima
396292472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins        /**
396392472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins         * Load this UrlData into the given Tab.  Use loadUrlDataIn to update
396492472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins         * the title bar as well.
396592472e83d198d741f0d242ea87ebb57395505cadLeon Scroggins         */
396658d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        public void loadIn(Tab t) {
396758d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins            if (mVoiceIntent != null) {
396858d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins                t.activateVoiceSearchMode(mVoiceIntent);
396958d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins            } else {
397058d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins                t.getWebView().loadUrl(mUrl, mHeaders);
397158d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins            }
397225ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima        }
397325ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima    };
397425ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima
39751f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins    /* package */ static final UrlData EMPTY_URL_DATA = new UrlData(null);
39760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project}
3977