BrowserActivity.java revision 7a8b88b0e0f20544df5ee34b798398603261b733
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;
760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.view.ContextMenu;
770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.view.Gravity;
780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.view.KeyEvent;
790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.view.LayoutInflater;
800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.view.Menu;
810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.view.MenuInflater;
820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.view.MenuItem;
830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.view.View;
840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.view.ViewGroup;
850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.view.Window;
860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.view.WindowManager;
870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.view.ContextMenu.ContextMenuInfo;
880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.view.MenuItem.OnMenuItemClickListener;
890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.webkit.CookieManager;
900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.webkit.CookieSyncManager;
910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.webkit.DownloadListener;
920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.webkit.HttpAuthHandler;
93b4da0ad0351996f639b50f9f29b123a9b5c24fd0Grace Klobaimport android.webkit.PluginManager;
940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.webkit.SslErrorHandler;
950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.webkit.URLUtil;
96cb6cc864e53f7d916622daf3b2cec133b36d6a55Leon Clarkeimport android.webkit.ValueCallback;
970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.webkit.WebChromeClient;
980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.webkit.WebHistoryItem;
990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.webkit.WebIconDatabase;
1000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.webkit.WebView;
1010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.widget.EditText;
1020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.widget.FrameLayout;
1030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.widget.LinearLayout;
1040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.widget.TextView;
1050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.widget.Toast;
106752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintanaimport android.accounts.Account;
107752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintanaimport android.accounts.AccountManager;
108752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintanaimport android.accounts.AccountManagerFuture;
109752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintanaimport android.accounts.AuthenticatorException;
110752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintanaimport android.accounts.OperationCanceledException;
111752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintanaimport android.accounts.AccountManagerCallback;
1120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
1135ee906c089567bca705e18561357510d7b55cb5aDan Egnorimport com.android.common.Patterns;
1145ee906c089567bca705e18561357510d7b55cb5aDan Egnor
115716d4f542daec3588f45cbc5cb3acc825233b8a1Doug Zongkerimport com.google.android.gsf.GoogleLoginServiceConstants;
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;
12900f54c589fd38431efd42ea2a551a49e64d595d5Grace Klobaimport java.util.Iterator;
130068e48b469f5abca53ee3da38f933cf2c25c93b8Grace Klobaimport java.util.Map;
1310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport java.util.regex.Matcher;
1320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport java.util.regex.Pattern;
1330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
1340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectpublic class BrowserActivity extends Activity
135752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana    implements View.OnCreateContextMenuListener, DownloadListener,
136752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana        AccountManagerCallback<Account[]> {
1370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
13831a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort    /* Define some aliases to make these debugging flags easier to refer to.
13931a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort     * This file imports android.provider.Browser, so we can't just refer to "Browser.DEBUG".
14031a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort     */
14131a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort    private final static boolean DEBUG = com.android.browser.Browser.DEBUG;
14231a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort    private final static boolean LOGV_ENABLED = com.android.browser.Browser.LOGV_ENABLED;
14331a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort    private final static boolean LOGD_ENABLED = com.android.browser.Browser.LOGD_ENABLED;
14431a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort
145565505b1a2c1d3099496af5910760087602e994aSatish Sampath    // These are single-character shortcuts for searching popular sources.
146565505b1a2c1d3099496af5910760087602e994aSatish Sampath    private static final int SHORTCUT_INVALID = 0;
147565505b1a2c1d3099496af5910760087602e994aSatish Sampath    private static final int SHORTCUT_GOOGLE_SEARCH = 1;
148565505b1a2c1d3099496af5910760087602e994aSatish Sampath    private static final int SHORTCUT_WIKIPEDIA_SEARCH = 2;
149565505b1a2c1d3099496af5910760087602e994aSatish Sampath    private static final int SHORTCUT_DICTIONARY_SEARCH = 3;
150565505b1a2c1d3099496af5910760087602e994aSatish Sampath    private static final int SHORTCUT_GOOGLE_MOBILE_LOCAL_SEARCH = 4;
151565505b1a2c1d3099496af5910760087602e994aSatish Sampath
152752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana    private Account[] mAccountsGoogle;
153752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana    private Account[] mAccountsPreferHosted;
1540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
155752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana    private void startReadOfGoogleAccounts() {
156752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana        mAccountsGoogle = null;
157752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana        mAccountsPreferHosted = null;
1580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
159752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana        AccountManager.get(this).getAccountsByTypeAndFeatures(
160752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana                GoogleLoginServiceConstants.ACCOUNT_TYPE,
161752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana                new String[]{GoogleLoginServiceConstants.FEATURE_LEGACY_HOSTED_OR_GOOGLE},
162752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana                this, null);
163752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana    }
164752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana
165752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana    /** This implements AccountManagerCallback<Account[]> */
166752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana    public void run(AccountManagerFuture<Account[]> accountManagerFuture) {
167752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana        try {
168752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana            if (mAccountsGoogle == null) {
169752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana                mAccountsGoogle = accountManagerFuture.getResult();
170752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana
171752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana                AccountManager.get(this).getAccountsByTypeAndFeatures(
172752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana                        GoogleLoginServiceConstants.ACCOUNT_TYPE,
173752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana                        new String[]{GoogleLoginServiceConstants.FEATURE_LEGACY_GOOGLE},
174752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana                        this, null);
175752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana            } else {
176752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana                mAccountsPreferHosted = accountManagerFuture.getResult();
177752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana                setupHomePage();
1780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
179752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana        } catch (OperationCanceledException e) {
180752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana            setupHomePage();
181752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana        } catch (IOException e) {
182752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana            setupHomePage();
183752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana        } catch (AuthenticatorException e) {
184752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana            setupHomePage();
185752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana        }
186752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana    }
187752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana
188752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana    private void setupHomePage() {
189752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana        // get the default home page
190752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana        String homepage = mSettings.getHomePage();
191752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana
192752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana        if (mAccountsPreferHosted != null && mAccountsGoogle != null) {
193752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana            // three cases:
194752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana            //
195752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana            //   hostedUser == googleUser
196752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana            //      The device has only a google account
197752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana            //
198752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana            //   hostedUser != googleUser
199752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana            //      The device has a hosted account and a google account
200752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana            //
201752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana            //   hostedUser != null, googleUser == null
202752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana            //      The device has only a hosted account (so far)
203752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana            String hostedUser = mAccountsPreferHosted.length == 0
204752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana                    ? null
205752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana                    : mAccountsPreferHosted[0].name;
206752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana            String googleUser = mAccountsGoogle.length == 0 ? null : mAccountsGoogle[0].name;
207752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana
208752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana            // developers might have no accounts at all
209752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana            if (hostedUser == null) return;
210752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana
211752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana            if (googleUser == null || !hostedUser.equals(googleUser)) {
212752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana                String domain = hostedUser.substring(hostedUser.lastIndexOf('@')+1);
213752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana                homepage = homepage.replace("?", "/a/" + domain + "?");
2140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
215752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana        }
2160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
217752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana        mSettings.setHomePage(BrowserActivity.this, homepage);
218752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana        resumeAfterCredentials();
2190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
2200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
221a977124eb29b195127fd161120ebbc58b255fb48Cary Clark    private static class ClearThumbnails extends AsyncTask<File, Void, Void> {
2220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        @Override
2230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public Void doInBackground(File... files) {
2240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (files != null) {
2250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                for (File f : files) {
226d6be1758b38d5b066ff10b6af906aa66c63670cdCary Clark                    if (!f.delete()) {
227d6be1758b38d5b066ff10b6af906aa66c63670cdCary Clark                      Log.e(LOGTAG, f.getPath() + " was not deleted");
228d6be1758b38d5b066ff10b6af906aa66c63670cdCary Clark                    }
2290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
2300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
2310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return null;
2320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
2330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
2340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
2353bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    /**
2363bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     * This layout holds everything you see below the status bar, including the
2373bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     * error console, the custom view container, and the webviews.
2383bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     */
2393bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    private FrameLayout mBrowserFrameLayout;
24081db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins
24122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    @Override
24222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    public void onCreate(Bundle icicle) {
24331a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort        if (LOGV_ENABLED) {
2440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Log.v(LOGTAG, this + " onStart");
2450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
2460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        super.onCreate(icicle);
2470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // test the browser in OpenGL
2480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // requestWindowFeature(Window.FEATURE_OPENGL);
2490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
250d334bf564b72416e77e707d25f8c55cfe1d85709Mike Reed        // enable this to test the browser in 32bit
251d334bf564b72416e77e707d25f8c55cfe1d85709Mike Reed        if (false) {
252d334bf564b72416e77e707d25f8c55cfe1d85709Mike Reed            getWindow().setFormat(PixelFormat.RGBX_8888);
253d334bf564b72416e77e707d25f8c55cfe1d85709Mike Reed            BitmapFactory.setDefaultConfig(Bitmap.Config.ARGB_8888);
254d334bf564b72416e77e707d25f8c55cfe1d85709Mike Reed        }
255d334bf564b72416e77e707d25f8c55cfe1d85709Mike Reed
2560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        setDefaultKeyMode(DEFAULT_KEYS_SEARCH_LOCAL);
2570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
2580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mResolver = getContentResolver();
2590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
2600923d69a8ca45222cabd82a80eaa88da9f132e9aGrace Kloba        // If this was a web search request, pass it on to the default web
2610923d69a8ca45222cabd82a80eaa88da9f132e9aGrace Kloba        // search provider and finish this activity.
2620923d69a8ca45222cabd82a80eaa88da9f132e9aGrace Kloba        if (handleWebSearchIntent(getIntent())) {
2630923d69a8ca45222cabd82a80eaa88da9f132e9aGrace Kloba            finish();
2640923d69a8ca45222cabd82a80eaa88da9f132e9aGrace Kloba            return;
2650923d69a8ca45222cabd82a80eaa88da9f132e9aGrace Kloba        }
2660923d69a8ca45222cabd82a80eaa88da9f132e9aGrace Kloba
2670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mSecLockIcon = Resources.getSystem().getDrawable(
2680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                android.R.drawable.ic_secure);
2690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mMixLockIcon = Resources.getSystem().getDrawable(
2700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                android.R.drawable.ic_partial_secure);
2710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
27281db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins        FrameLayout frameLayout = (FrameLayout) getWindow().getDecorView()
27381db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins                .findViewById(com.android.internal.R.id.content);
2743bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins        mBrowserFrameLayout = (FrameLayout) LayoutInflater.from(this)
2753bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                .inflate(R.layout.custom_screen, null);
2763bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins        mContentView = (FrameLayout) mBrowserFrameLayout.findViewById(
2773bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                R.id.main_content);
2783bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins        mErrorConsoleContainer = (LinearLayout) mBrowserFrameLayout
2793bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                .findViewById(R.id.error_console);
2803bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins        mCustomViewContainer = (FrameLayout) mBrowserFrameLayout
2813bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                .findViewById(R.id.fullscreen_custom_content);
2823bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins        frameLayout.addView(mBrowserFrameLayout, COVER_SCREEN_PARAMS);
28368579393973f745fc65a2781061af9bb8f2d7020Leon Scroggins        mTitleBar = new TitleBar(this);
284fe87bd3a3897e4bad65bb3d284659ae2f4e57570Leon Scroggins        mFakeTitleBar = new TitleBar(this);
2850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
2860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Create the tab control and our initial tab
2870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mTabControl = new TabControl(this);
2880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
2890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Open the icon database and retain all the bookmark urls for favicons
2900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        retainIconsOnStartup();
2910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
2920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Keep a settings instance handy.
2930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mSettings = BrowserSettings.getInstance();
2940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mSettings.setTabControl(mTabControl);
2950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mSettings.loadFromDb(this);
2960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
2970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
2980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "Browser");
2990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
300a34f686112fb4f9fbea00b8c2c47153d34e93e41Grace Kloba        /* enables registration for changes in network status from
301a34f686112fb4f9fbea00b8c2c47153d34e93e41Grace Kloba           http stack */
302a34f686112fb4f9fbea00b8c2c47153d34e93e41Grace Kloba        mNetworkStateChangedFilter = new IntentFilter();
303a34f686112fb4f9fbea00b8c2c47153d34e93e41Grace Kloba        mNetworkStateChangedFilter.addAction(
304a34f686112fb4f9fbea00b8c2c47153d34e93e41Grace Kloba                ConnectivityManager.CONNECTIVITY_ACTION);
305a34f686112fb4f9fbea00b8c2c47153d34e93e41Grace Kloba        mNetworkStateIntentReceiver = new BroadcastReceiver() {
306a34f686112fb4f9fbea00b8c2c47153d34e93e41Grace Kloba                @Override
307a34f686112fb4f9fbea00b8c2c47153d34e93e41Grace Kloba                public void onReceive(Context context, Intent intent) {
308a34f686112fb4f9fbea00b8c2c47153d34e93e41Grace Kloba                    if (intent.getAction().equals(
309a34f686112fb4f9fbea00b8c2c47153d34e93e41Grace Kloba                            ConnectivityManager.CONNECTIVITY_ACTION)) {
3107d899d6f5364a5b20716497a3be5e2f778a2bc0eRobert Greenwalt                        boolean noConnectivity = intent.getBooleanExtra(
3117d899d6f5364a5b20716497a3be5e2f778a2bc0eRobert Greenwalt                                ConnectivityManager.EXTRA_NO_CONNECTIVITY, false);
31256199cc25e7ee0455ec2a8099098b66b8554f677Andrei Popescu                        if (!noConnectivity) {
31356199cc25e7ee0455ec2a8099098b66b8554f677Andrei Popescu                            NetworkInfo info = intent.getParcelableExtra(
31456199cc25e7ee0455ec2a8099098b66b8554f677Andrei Popescu                                    ConnectivityManager.EXTRA_NETWORK_INFO);
31556199cc25e7ee0455ec2a8099098b66b8554f677Andrei Popescu                            String typeName = info.getTypeName();
31656199cc25e7ee0455ec2a8099098b66b8554f677Andrei Popescu                            String subtypeName = info.getSubtypeName();
31756199cc25e7ee0455ec2a8099098b66b8554f677Andrei Popescu                            sendNetworkType(typeName.toLowerCase(),
31856199cc25e7ee0455ec2a8099098b66b8554f677Andrei Popescu                                    (subtypeName != null ? subtypeName.toLowerCase() : ""));
31956199cc25e7ee0455ec2a8099098b66b8554f677Andrei Popescu                        }
3207d899d6f5364a5b20716497a3be5e2f778a2bc0eRobert Greenwalt                        onNetworkToggle(!noConnectivity);
321a34f686112fb4f9fbea00b8c2c47153d34e93e41Grace Kloba                    }
322a34f686112fb4f9fbea00b8c2c47153d34e93e41Grace Kloba                }
323a34f686112fb4f9fbea00b8c2c47153d34e93e41Grace Kloba            };
324a34f686112fb4f9fbea00b8c2c47153d34e93e41Grace Kloba
325615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba        IntentFilter filter = new IntentFilter(Intent.ACTION_PACKAGE_ADDED);
326615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba        filter.addAction(Intent.ACTION_PACKAGE_REMOVED);
327615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba        filter.addDataScheme("package");
328615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba        mPackageInstallationReceiver = new BroadcastReceiver() {
329615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba            @Override
330615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba            public void onReceive(Context context, Intent intent) {
331615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                final String action = intent.getAction();
332615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                final String packageName = intent.getData()
333615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                        .getSchemeSpecificPart();
334615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                final boolean replacing = intent.getBooleanExtra(
335615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                        Intent.EXTRA_REPLACING, false);
336615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                if (Intent.ACTION_PACKAGE_REMOVED.equals(action) && replacing) {
337615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                    // if it is replacing, refreshPlugins() when adding
338615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                    return;
339615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                }
340615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                PackageManager pm = BrowserActivity.this.getPackageManager();
341615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                PackageInfo pkgInfo = null;
342615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                try {
343615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                    pkgInfo = pm.getPackageInfo(packageName,
344615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                            PackageManager.GET_PERMISSIONS);
345615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                } catch (PackageManager.NameNotFoundException e) {
346615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                    return;
347615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                }
348615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                if (pkgInfo != null) {
349615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                    String permissions[] = pkgInfo.requestedPermissions;
350615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                    if (permissions == null) {
351615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                        return;
352615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                    }
353615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                    boolean permissionOk = false;
354615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                    for (String permit : permissions) {
355615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                        if (PluginManager.PLUGIN_PERMISSION.equals(permit)) {
356615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                            permissionOk = true;
357615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                            break;
358615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                        }
359615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                    }
360615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                    if (permissionOk) {
361615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                        PluginManager.getInstance(BrowserActivity.this)
362615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                                .refreshPlugins(
363615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                                        Intent.ACTION_PACKAGE_ADDED
364615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                                                .equals(action));
365615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                    }
366615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                }
367615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba            }
368615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba        };
369615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba        registerReceiver(mPackageInstallationReceiver, filter);
370615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba
3710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (!mTabControl.restoreState(icicle)) {
3720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // clear up the thumbnail directory if we can't restore the state as
3730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // none of the files in the directory are referenced any more.
3740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            new ClearThumbnails().execute(
3750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    mTabControl.getThumbnailDir().listFiles());
376aab3f09b5c2d39b19067e57635614080b2403a46Grace Kloba            // there is no quit on Android. But if we can't restore the state,
377aab3f09b5c2d39b19067e57635614080b2403a46Grace Kloba            // we can treat it as a new Browser, remove the old session cookies.
378aab3f09b5c2d39b19067e57635614080b2403a46Grace Kloba            CookieManager.getInstance().removeSessionCookie();
3790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            final Intent intent = getIntent();
3800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            final Bundle extra = intent.getExtras();
3810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Create an initial tab.
3820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // If the intent is ACTION_VIEW and data is not null, the Browser is
3830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // invoked to view the content by another application. In this case,
3840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // the tab will be close when exit.
38525ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima            UrlData urlData = getUrlDataFromIntent(intent);
38625ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima
38758d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins            String action = intent.getAction();
38822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            final Tab t = mTabControl.createNewTab(
38958d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins                    (Intent.ACTION_VIEW.equals(action) &&
39058d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins                    intent.getData() != null)
391a1cc3fdce19a336c251297c61cd83ac6cf767cd1Leon Scroggins                    || RecognizerResultsIntent.ACTION_VOICE_SEARCH_RESULTS
392a1cc3fdce19a336c251297c61cd83ac6cf767cd1Leon Scroggins                    .equals(action),
39325ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima                    intent.getStringExtra(Browser.EXTRA_APPLICATION_ID), urlData.mUrl);
3940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mTabControl.setCurrentTab(t);
3950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            attachTabToContentView(t);
3960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            WebView webView = t.getWebView();
3970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (extra != null) {
3980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                int scale = extra.getInt(Browser.INITIAL_ZOOM_LEVEL, 0);
3990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (scale > 0 && scale <= 1000) {
4000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    webView.setInitialScale(scale);
4010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
4020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
4030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // If we are not restoring from an icicle, then there is a high
4040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // likely hood this is the first run. So, check to see if the
4050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // homepage needs to be configured and copy any plugins from our
4060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // asset directory to the data partition.
4070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if ((extra == null || !extra.getBoolean("testing"))
4080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    && !mSettings.isLoginInitialized()) {
409752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana                startReadOfGoogleAccounts();
4100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
4110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
41225ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima            if (urlData.isEmpty()) {
413304442375719effd41dbd53ae62de7a8d0cec7d9Leon Scroggins                if (mSettings.isLoginInitialized()) {
414304442375719effd41dbd53ae62de7a8d0cec7d9Leon Scroggins                    webView.loadUrl(mSettings.getHomePage());
415304442375719effd41dbd53ae62de7a8d0cec7d9Leon Scroggins                } else {
416304442375719effd41dbd53ae62de7a8d0cec7d9Leon Scroggins                    waitForCredentials();
417304442375719effd41dbd53ae62de7a8d0cec7d9Leon Scroggins                }
4180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } else {
41958d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins                urlData.loadIn(t);
4200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
4210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
4220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // TabControl.restoreState() will create a new tab even if
4231f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins            // restoring the state fails.
4240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            attachTabToContentView(mTabControl.getCurrentTab());
4250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
426615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba
427b3c02da4553b1a629b16377970fdabae28394c94Feng Qian        // Read JavaScript flags if it exists.
428b3c02da4553b1a629b16377970fdabae28394c94Feng Qian        String jsFlags = mSettings.getJsFlags();
429b3c02da4553b1a629b16377970fdabae28394c94Feng Qian        if (jsFlags.trim().length() != 0) {
430b3c02da4553b1a629b16377970fdabae28394c94Feng Qian            mTabControl.getCurrentWebView().setJsFlags(jsFlags);
431b3c02da4553b1a629b16377970fdabae28394c94Feng Qian        }
4320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
4330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
43458d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    /**
43558d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins     * Feed the previously stored results strings to the BrowserProvider so that
43658d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins     * the SearchDialog will show them instead of the standard searches.
43758d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins     * @param result String to show on the editable line of the SearchDialog.
43858d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins     */
43958d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    /* package */ void showVoiceSearchResults(String result) {
44058d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        ContentProviderClient client = mResolver.acquireContentProviderClient(
44158d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins                Browser.BOOKMARKS_URI);
44258d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        ContentProvider prov = client.getLocalContentProvider();
44358d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        BrowserProvider bp = (BrowserProvider) prov;
44458d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        bp.setQueryResults(mTabControl.getCurrentTab().getVoiceSearchResults());
44558d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        client.release();
44658d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins
44758d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        startSearch(result, false,
44858d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins                createGoogleSearchSourceBundle(GOOGLE_SEARCH_SOURCE_SEARCHKEY),
44958d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins                false);
45058d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    }
45158d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins
4520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    @Override
4530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    protected void onNewIntent(Intent intent) {
45422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        Tab current = mTabControl.getCurrentTab();
4550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // When a tab is closed on exit, the current tab index is set to -1.
4560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Reset before proceed as Browser requires the current tab to be set.
4570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (current == null) {
4580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Try to reset the tab in case the index was incorrect.
4590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            current = mTabControl.getTab(0);
4600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (current == null) {
4610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // No tabs at all so just ignore this intent.
4620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                return;
4630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
4640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mTabControl.setCurrentTab(current);
4650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            attachTabToContentView(current);
4660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            resetTitleAndIcon(current.getWebView());
4670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
4680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final String action = intent.getAction();
4690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final int flags = intent.getFlags();
4700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (Intent.ACTION_MAIN.equals(action) ||
4710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                (flags & Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY) != 0) {
4720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // just resume the browser
4730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
4740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
475a1cc3fdce19a336c251297c61cd83ac6cf767cd1Leon Scroggins        boolean activateVoiceSearch = RecognizerResultsIntent
476a1cc3fdce19a336c251297c61cd83ac6cf767cd1Leon Scroggins                .ACTION_VOICE_SEARCH_RESULTS.equals(action);
4770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (Intent.ACTION_VIEW.equals(action)
4780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                || Intent.ACTION_SEARCH.equals(action)
4790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                || MediaStore.INTENT_ACTION_MEDIA_SEARCH.equals(action)
48058d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins                || Intent.ACTION_WEB_SEARCH.equals(action)
48158d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins                || activateVoiceSearch) {
482565505b1a2c1d3099496af5910760087602e994aSatish Sampath            // If this was a search request (e.g. search query directly typed into the address bar),
483565505b1a2c1d3099496af5910760087602e994aSatish Sampath            // pass it on to the default web search provider.
484565505b1a2c1d3099496af5910760087602e994aSatish Sampath            if (handleWebSearchIntent(intent)) {
485565505b1a2c1d3099496af5910760087602e994aSatish Sampath                return;
486565505b1a2c1d3099496af5910760087602e994aSatish Sampath            }
487565505b1a2c1d3099496af5910760087602e994aSatish Sampath
48825ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima            UrlData urlData = getUrlDataFromIntent(intent);
48925ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima            if (urlData.isEmpty()) {
49025ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima                urlData = new UrlData(mSettings.getHomePage());
4910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
49225ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima
493cc63403643786905262f505ab5266d8e80b9924cGrace Kloba            final String appId = intent
494cc63403643786905262f505ab5266d8e80b9924cGrace Kloba                    .getStringExtra(Browser.EXTRA_APPLICATION_ID);
49558d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins            if ((Intent.ACTION_VIEW.equals(action) || activateVoiceSearch)
496cc63403643786905262f505ab5266d8e80b9924cGrace Kloba                    && !getPackageName().equals(appId)
497cc63403643786905262f505ab5266d8e80b9924cGrace Kloba                    && (flags & Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT) != 0) {
49822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                Tab appTab = mTabControl.getTabFromId(appId);
499f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                if (appTab != null) {
500f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    Log.i(LOGTAG, "Reusing tab for " + appId);
501f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    // Dismiss the subwindow if applicable.
502f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    dismissSubWindow(appTab);
503f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    // Since we might kill the WebView, remove it from the
504f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    // content view first.
505f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    removeTabFromContentView(appTab);
506f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    // Recreate the main WebView after destroying the old one.
507f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    // If the WebView has the same original url and is on that
508f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    // page, it can be reused.
509f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    boolean needsLoad =
51025ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima                            mTabControl.recreateWebView(appTab, urlData.mUrl);
511bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch
512f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    if (current != appTab) {
5131f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                        switchToTab(mTabControl.getTabIndex(appTab));
5141f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                        if (needsLoad) {
51558d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins                            urlData.loadIn(appTab);
5161f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                        }
517f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    } else {
5181f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                        // If the tab was the current tab, we have to attach
5191f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                        // it to the view system again.
5201f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                        attachTabToContentView(appTab);
5211f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                        if (needsLoad) {
52258d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins                            urlData.loadIn(appTab);
523f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                        }
524f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    }
525f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    return;
526cd11589fc3930906d4b9b7dd18aa52a9f1eb0c8aPatrick Scott                } else {
527cd11589fc3930906d4b9b7dd18aa52a9f1eb0c8aPatrick Scott                    // No matching application tab, try to find a regular tab
528cd11589fc3930906d4b9b7dd18aa52a9f1eb0c8aPatrick Scott                    // with a matching url.
529cd11589fc3930906d4b9b7dd18aa52a9f1eb0c8aPatrick Scott                    appTab = mTabControl.findUnusedTabWithUrl(urlData.mUrl);
53025515f8bd458a2471d13d876cfb0e18d8ff2a00fLeon Scroggins                    if (appTab != null) {
53125515f8bd458a2471d13d876cfb0e18d8ff2a00fLeon Scroggins                        if (current != appTab) {
53225515f8bd458a2471d13d876cfb0e18d8ff2a00fLeon Scroggins                            switchToTab(mTabControl.getTabIndex(appTab));
53325515f8bd458a2471d13d876cfb0e18d8ff2a00fLeon Scroggins                        }
53425515f8bd458a2471d13d876cfb0e18d8ff2a00fLeon Scroggins                        // Otherwise, we are already viewing the correct tab.
535cd11589fc3930906d4b9b7dd18aa52a9f1eb0c8aPatrick Scott                    } else {
536cd11589fc3930906d4b9b7dd18aa52a9f1eb0c8aPatrick Scott                        // if FLAG_ACTIVITY_BROUGHT_TO_FRONT flag is on, the url
537cd11589fc3930906d4b9b7dd18aa52a9f1eb0c8aPatrick Scott                        // will be opened in a new tab unless we have reached
538cd11589fc3930906d4b9b7dd18aa52a9f1eb0c8aPatrick Scott                        // MAX_TABS. Then the url will be opened in the current
539cd11589fc3930906d4b9b7dd18aa52a9f1eb0c8aPatrick Scott                        // tab. If a new tab is created, it will have "true" for
540cd11589fc3930906d4b9b7dd18aa52a9f1eb0c8aPatrick Scott                        // exit on close.
5411f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                        openTabAndShow(urlData, true, appId);
542cd11589fc3930906d4b9b7dd18aa52a9f1eb0c8aPatrick Scott                    }
543f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                }
5440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } else {
545638d3f45791a31d0b290e180b93bad49576eb6d3Grace Kloba                if (!urlData.isEmpty()
546638d3f45791a31d0b290e180b93bad49576eb6d3Grace Kloba                        && urlData.mUrl.startsWith("about:debug")) {
547638d3f45791a31d0b290e180b93bad49576eb6d3Grace Kloba                    if ("about:debug.dom".equals(urlData.mUrl)) {
548638d3f45791a31d0b290e180b93bad49576eb6d3Grace Kloba                        current.getWebView().dumpDomTree(false);
549638d3f45791a31d0b290e180b93bad49576eb6d3Grace Kloba                    } else if ("about:debug.dom.file".equals(urlData.mUrl)) {
550638d3f45791a31d0b290e180b93bad49576eb6d3Grace Kloba                        current.getWebView().dumpDomTree(true);
551638d3f45791a31d0b290e180b93bad49576eb6d3Grace Kloba                    } else if ("about:debug.render".equals(urlData.mUrl)) {
552638d3f45791a31d0b290e180b93bad49576eb6d3Grace Kloba                        current.getWebView().dumpRenderTree(false);
553638d3f45791a31d0b290e180b93bad49576eb6d3Grace Kloba                    } else if ("about:debug.render.file".equals(urlData.mUrl)) {
554638d3f45791a31d0b290e180b93bad49576eb6d3Grace Kloba                        current.getWebView().dumpRenderTree(true);
555638d3f45791a31d0b290e180b93bad49576eb6d3Grace Kloba                    } else if ("about:debug.display".equals(urlData.mUrl)) {
556638d3f45791a31d0b290e180b93bad49576eb6d3Grace Kloba                        current.getWebView().dumpDisplayTree();
5579b78e1d1e0bd819ae03df5594d4a56519e5d87c7Mike Reed                    } else if (urlData.mUrl.startsWith("about:debug.drag")) {
5589b78e1d1e0bd819ae03df5594d4a56519e5d87c7Mike Reed                        int index = urlData.mUrl.codePointAt(16) - '0';
5599b78e1d1e0bd819ae03df5594d4a56519e5d87c7Mike Reed                        if (index <= 0 || index > 9) {
5609b78e1d1e0bd819ae03df5594d4a56519e5d87c7Mike Reed                            current.getWebView().setDragTracker(null);
5619b78e1d1e0bd819ae03df5594d4a56519e5d87c7Mike Reed                        } else {
5629b78e1d1e0bd819ae03df5594d4a56519e5d87c7Mike Reed                            current.getWebView().setDragTracker(new MeshTracker(index));
5639b78e1d1e0bd819ae03df5594d4a56519e5d87c7Mike Reed                        }
564638d3f45791a31d0b290e180b93bad49576eb6d3Grace Kloba                    } else {
565638d3f45791a31d0b290e180b93bad49576eb6d3Grace Kloba                        mSettings.toggleDebugSettings();
566638d3f45791a31d0b290e180b93bad49576eb6d3Grace Kloba                    }
5670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    return;
5680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
5691f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                // Get rid of the subwindow if it exists
5701f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                dismissSubWindow(current);
57158d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins                urlData.loadIn(current);
5720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
5730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
5740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
5750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
576565505b1a2c1d3099496af5910760087602e994aSatish Sampath    private int parseUrlShortcut(String url) {
577565505b1a2c1d3099496af5910760087602e994aSatish Sampath        if (url == null) return SHORTCUT_INVALID;
578565505b1a2c1d3099496af5910760087602e994aSatish Sampath
579565505b1a2c1d3099496af5910760087602e994aSatish Sampath        // FIXME: quick search, need to be customized by setting
580565505b1a2c1d3099496af5910760087602e994aSatish Sampath        if (url.length() > 2 && url.charAt(1) == ' ') {
581565505b1a2c1d3099496af5910760087602e994aSatish Sampath            switch (url.charAt(0)) {
582565505b1a2c1d3099496af5910760087602e994aSatish Sampath            case 'g': return SHORTCUT_GOOGLE_SEARCH;
583565505b1a2c1d3099496af5910760087602e994aSatish Sampath            case 'w': return SHORTCUT_WIKIPEDIA_SEARCH;
584565505b1a2c1d3099496af5910760087602e994aSatish Sampath            case 'd': return SHORTCUT_DICTIONARY_SEARCH;
585565505b1a2c1d3099496af5910760087602e994aSatish Sampath            case 'l': return SHORTCUT_GOOGLE_MOBILE_LOCAL_SEARCH;
586565505b1a2c1d3099496af5910760087602e994aSatish Sampath            }
587565505b1a2c1d3099496af5910760087602e994aSatish Sampath        }
588565505b1a2c1d3099496af5910760087602e994aSatish Sampath        return SHORTCUT_INVALID;
589565505b1a2c1d3099496af5910760087602e994aSatish Sampath    }
590565505b1a2c1d3099496af5910760087602e994aSatish Sampath
591565505b1a2c1d3099496af5910760087602e994aSatish Sampath    /**
592565505b1a2c1d3099496af5910760087602e994aSatish Sampath     * Launches the default web search activity with the query parameters if the given intent's data
593565505b1a2c1d3099496af5910760087602e994aSatish Sampath     * are identified as plain search terms and not URLs/shortcuts.
594565505b1a2c1d3099496af5910760087602e994aSatish Sampath     * @return true if the intent was handled and web search activity was launched, false if not.
595565505b1a2c1d3099496af5910760087602e994aSatish Sampath     */
596565505b1a2c1d3099496af5910760087602e994aSatish Sampath    private boolean handleWebSearchIntent(Intent intent) {
597565505b1a2c1d3099496af5910760087602e994aSatish Sampath        if (intent == null) return false;
598565505b1a2c1d3099496af5910760087602e994aSatish Sampath
599565505b1a2c1d3099496af5910760087602e994aSatish Sampath        String url = null;
600565505b1a2c1d3099496af5910760087602e994aSatish Sampath        final String action = intent.getAction();
601a1cc3fdce19a336c251297c61cd83ac6cf767cd1Leon Scroggins        if (RecognizerResultsIntent.ACTION_VOICE_SEARCH_RESULTS.equals(
602a1cc3fdce19a336c251297c61cd83ac6cf767cd1Leon Scroggins                action)) {
60358d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins            return false;
60458d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        }
605565505b1a2c1d3099496af5910760087602e994aSatish Sampath        if (Intent.ACTION_VIEW.equals(action)) {
6061e70505659dd9bf0f7e03bce787ba880f9b7a8aaGrace Kloba            Uri data = intent.getData();
6071e70505659dd9bf0f7e03bce787ba880f9b7a8aaGrace Kloba            if (data != null) url = data.toString();
608565505b1a2c1d3099496af5910760087602e994aSatish Sampath        } else if (Intent.ACTION_SEARCH.equals(action)
609565505b1a2c1d3099496af5910760087602e994aSatish Sampath                || MediaStore.INTENT_ACTION_MEDIA_SEARCH.equals(action)
610565505b1a2c1d3099496af5910760087602e994aSatish Sampath                || Intent.ACTION_WEB_SEARCH.equals(action)) {
611565505b1a2c1d3099496af5910760087602e994aSatish Sampath            url = intent.getStringExtra(SearchManager.QUERY);
612565505b1a2c1d3099496af5910760087602e994aSatish Sampath        }
6130485170e03e079eb61b9dd52fc2c98da02fa7b2cBjorn Bringert        return handleWebSearchRequest(url, intent.getBundleExtra(SearchManager.APP_DATA),
6140485170e03e079eb61b9dd52fc2c98da02fa7b2cBjorn Bringert                intent.getStringExtra(SearchManager.EXTRA_DATA_KEY));
615565505b1a2c1d3099496af5910760087602e994aSatish Sampath    }
616565505b1a2c1d3099496af5910760087602e994aSatish Sampath
617565505b1a2c1d3099496af5910760087602e994aSatish Sampath    /**
618565505b1a2c1d3099496af5910760087602e994aSatish Sampath     * Launches the default web search activity with the query parameters if the given url string
619565505b1a2c1d3099496af5910760087602e994aSatish Sampath     * was identified as plain search terms and not URL/shortcut.
620565505b1a2c1d3099496af5910760087602e994aSatish Sampath     * @return true if the request was handled and web search activity was launched, false if not.
621565505b1a2c1d3099496af5910760087602e994aSatish Sampath     */
6220485170e03e079eb61b9dd52fc2c98da02fa7b2cBjorn Bringert    private boolean handleWebSearchRequest(String inUrl, Bundle appData, String extraData) {
623565505b1a2c1d3099496af5910760087602e994aSatish Sampath        if (inUrl == null) return false;
624565505b1a2c1d3099496af5910760087602e994aSatish Sampath
625565505b1a2c1d3099496af5910760087602e994aSatish Sampath        // In general, we shouldn't modify URL from Intent.
626565505b1a2c1d3099496af5910760087602e994aSatish Sampath        // But currently, we get the user-typed URL from search box as well.
627565505b1a2c1d3099496af5910760087602e994aSatish Sampath        String url = fixUrl(inUrl).trim();
628565505b1a2c1d3099496af5910760087602e994aSatish Sampath
629565505b1a2c1d3099496af5910760087602e994aSatish Sampath        // URLs and site specific search shortcuts are handled by the regular flow of control, so
630565505b1a2c1d3099496af5910760087602e994aSatish Sampath        // return early.
6315ee906c089567bca705e18561357510d7b55cb5aDan Egnor        if (Patterns.WEB_URL.matcher(url).matches()
632bc5b9f358a2b75bf3a104b9f5cd477ad2f6f740fSatish Sampath                || ACCEPTED_URI_SCHEMA.matcher(url).matches()
633565505b1a2c1d3099496af5910760087602e994aSatish Sampath                || parseUrlShortcut(url) != SHORTCUT_INVALID) {
634565505b1a2c1d3099496af5910760087602e994aSatish Sampath            return false;
635565505b1a2c1d3099496af5910760087602e994aSatish Sampath        }
636565505b1a2c1d3099496af5910760087602e994aSatish Sampath
637565505b1a2c1d3099496af5910760087602e994aSatish Sampath        Browser.updateVisitedHistory(mResolver, url, false);
638565505b1a2c1d3099496af5910760087602e994aSatish Sampath        Browser.addSearchUrl(mResolver, url);
639565505b1a2c1d3099496af5910760087602e994aSatish Sampath
640565505b1a2c1d3099496af5910760087602e994aSatish Sampath        Intent intent = new Intent(Intent.ACTION_WEB_SEARCH);
641565505b1a2c1d3099496af5910760087602e994aSatish Sampath        intent.addCategory(Intent.CATEGORY_DEFAULT);
642565505b1a2c1d3099496af5910760087602e994aSatish Sampath        intent.putExtra(SearchManager.QUERY, url);
64315e9f2dc92cf1621f95071b3c740f46079aa0f3bSatish Sampath        if (appData != null) {
64415e9f2dc92cf1621f95071b3c740f46079aa0f3bSatish Sampath            intent.putExtra(SearchManager.APP_DATA, appData);
64515e9f2dc92cf1621f95071b3c740f46079aa0f3bSatish Sampath        }
6460485170e03e079eb61b9dd52fc2c98da02fa7b2cBjorn Bringert        if (extraData != null) {
6470485170e03e079eb61b9dd52fc2c98da02fa7b2cBjorn Bringert            intent.putExtra(SearchManager.EXTRA_DATA_KEY, extraData);
6480485170e03e079eb61b9dd52fc2c98da02fa7b2cBjorn Bringert        }
649cc63403643786905262f505ab5266d8e80b9924cGrace Kloba        intent.putExtra(Browser.EXTRA_APPLICATION_ID, getPackageName());
650565505b1a2c1d3099496af5910760087602e994aSatish Sampath        startActivity(intent);
651565505b1a2c1d3099496af5910760087602e994aSatish Sampath
652565505b1a2c1d3099496af5910760087602e994aSatish Sampath        return true;
653565505b1a2c1d3099496af5910760087602e994aSatish Sampath    }
654565505b1a2c1d3099496af5910760087602e994aSatish Sampath
65525ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima    private UrlData getUrlDataFromIntent(Intent intent) {
65658d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        String url = "";
657068e48b469f5abca53ee3da38f933cf2c25c93b8Grace Kloba        Map<String, String> headers = null;
6580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (intent != null) {
6590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            final String action = intent.getAction();
6600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (Intent.ACTION_VIEW.equals(action)) {
6610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                url = smartUrlFilter(intent.getData());
6620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (url != null && url.startsWith("content:")) {
6630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    /* Append mimetype so webview knows how to display */
6640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    String mimeType = intent.resolveType(getContentResolver());
6650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    if (mimeType != null) {
6660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        url += "?" + mimeType;
6670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
6680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
669068e48b469f5abca53ee3da38f933cf2c25c93b8Grace Kloba                if (url != null && url.startsWith("http")) {
67000f54c589fd38431efd42ea2a551a49e64d595d5Grace Kloba                    final Bundle pairs = intent
67100f54c589fd38431efd42ea2a551a49e64d595d5Grace Kloba                            .getBundleExtra(Browser.EXTRA_HEADERS);
6722d508edbf54ea74cd4e89be8b622b1cbd587464aGrace Kloba                    if (pairs != null && !pairs.isEmpty()) {
67300f54c589fd38431efd42ea2a551a49e64d595d5Grace Kloba                        Iterator<String> iter = pairs.keySet().iterator();
674068e48b469f5abca53ee3da38f933cf2c25c93b8Grace Kloba                        headers = new HashMap<String, String>();
67500f54c589fd38431efd42ea2a551a49e64d595d5Grace Kloba                        while (iter.hasNext()) {
67600f54c589fd38431efd42ea2a551a49e64d595d5Grace Kloba                            String key = iter.next();
67700f54c589fd38431efd42ea2a551a49e64d595d5Grace Kloba                            headers.put(key, pairs.getString(key));
678068e48b469f5abca53ee3da38f933cf2c25c93b8Grace Kloba                        }
679068e48b469f5abca53ee3da38f933cf2c25c93b8Grace Kloba                    }
68025ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima                }
6810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } else if (Intent.ACTION_SEARCH.equals(action)
6820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    || MediaStore.INTENT_ACTION_MEDIA_SEARCH.equals(action)
6830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    || Intent.ACTION_WEB_SEARCH.equals(action)) {
6840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                url = intent.getStringExtra(SearchManager.QUERY);
6850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (url != null) {
6860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    mLastEnteredUrl = url;
687b446443e47c334bc3aaae98b67c8dca347da3032Leon Scroggins                    Browser.updateVisitedHistory(mResolver, url, false);
6880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // In general, we shouldn't modify URL from Intent.
6890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // But currently, we get the user-typed URL from search box as well.
6900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    url = fixUrl(url);
6910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    url = smartUrlFilter(url);
6920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    String searchSource = "&source=android-" + GOOGLE_SEARCH_SOURCE_SUGGEST + "&";
6930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    if (url.contains(searchSource)) {
6940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        String source = null;
6950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        final Bundle appData = intent.getBundleExtra(SearchManager.APP_DATA);
6960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        if (appData != null) {
6970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            source = appData.getString(SearchManager.SOURCE);
6980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }
6990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        if (TextUtils.isEmpty(source)) {
7000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            source = GOOGLE_SEARCH_SOURCE_UNKNOWN;
7010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }
7020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        url = url.replace(searchSource, "&source=android-"+source+"&");
7030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
7040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
7050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
7060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
70758d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        return new UrlData(url, headers, intent);
7080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
70958d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    /* package */ void showVoiceTitleBar(String title) {
71058d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        mTitleBar.setInVoiceMode(true);
71158d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        mFakeTitleBar.setInVoiceMode(true);
7120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
71358d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        mTitleBar.setDisplayTitle(title);
71458d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        mFakeTitleBar.setDisplayTitle(title);
71558d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    }
71658d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    /* package */ void revertVoiceTitleBar() {
71758d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        mTitleBar.setInVoiceMode(false);
71858d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        mFakeTitleBar.setInVoiceMode(false);
71958d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins
72058d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        mTitleBar.setDisplayTitle(mTitle);
72158d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        mFakeTitleBar.setDisplayTitle(mTitle);
72258d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    }
7230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /* package */ static String fixUrl(String inUrl) {
724652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark        // FIXME: Converting the url to lower case
725652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark        // duplicates functionality in smartUrlFilter().
726652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark        // However, changing all current callers of fixUrl to
727652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark        // call smartUrlFilter in addition may have unwanted
728652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark        // consequences, and is deferred for now.
729652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark        int colon = inUrl.indexOf(':');
730652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark        boolean allLower = true;
731652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark        for (int index = 0; index < colon; index++) {
732652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark            char ch = inUrl.charAt(index);
733652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark            if (!Character.isLetter(ch)) {
734652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark                break;
735652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark            }
736652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark            allLower &= Character.isLowerCase(ch);
737652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark            if (index == colon - 1 && !allLower) {
738652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark                inUrl = inUrl.substring(0, colon).toLowerCase()
739652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark                        + inUrl.substring(colon);
740652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark            }
741652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark        }
7420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (inUrl.startsWith("http://") || inUrl.startsWith("https://"))
7430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return inUrl;
7440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (inUrl.startsWith("http:") ||
7450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                inUrl.startsWith("https:")) {
7460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (inUrl.startsWith("http:/") || inUrl.startsWith("https:/")) {
7470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                inUrl = inUrl.replaceFirst("/", "//");
7480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } else inUrl = inUrl.replaceFirst(":", "://");
7490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
7500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return inUrl;
7510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
7520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
75322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    @Override
75422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    protected void onResume() {
7550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        super.onResume();
75631a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort        if (LOGV_ENABLED) {
7570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Log.v(LOGTAG, "BrowserActivity.onResume: this=" + this);
7580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
7590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
7600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (!mActivityInPause) {
7610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Log.e(LOGTAG, "BrowserActivity is already resumed.");
7620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
7630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
7640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
7657bfa63b55644fbf2da1fe6a24b3be0267529202cMike Reed        mTabControl.resumeCurrentTab();
7660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mActivityInPause = false;
7677bfa63b55644fbf2da1fe6a24b3be0267529202cMike Reed        resumeWebViewTimers();
7680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
7690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mWakeLock.isHeld()) {
7700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mHandler.removeMessages(RELEASE_WAKELOCK);
7710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mWakeLock.release();
7720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
7730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
7740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mCredsDlg != null) {
7750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (!mHandler.hasMessages(CANCEL_CREDS_REQUEST)) {
7760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project             // In case credential request never comes back
7770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mHandler.sendEmptyMessageDelayed(CANCEL_CREDS_REQUEST, 6000);
7780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
7790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
7800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
7810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        registerReceiver(mNetworkStateIntentReceiver,
7820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                         mNetworkStateChangedFilter);
7830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebView.enablePlatformNotifications();
7840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
7850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
7863bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    /**
7873bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     * Since the actual title bar is embedded in the WebView, and removing it
788fe87bd3a3897e4bad65bb3d284659ae2f4e57570Leon Scroggins     * would change its appearance, use a different TitleBar to show overlayed
789fe87bd3a3897e4bad65bb3d284659ae2f4e57570Leon Scroggins     * at the top of the screen, when the menu is open or the page is loading.
7903bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     */
7913bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    private TitleBar mFakeTitleBar;
7923bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins
7933bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    /**
794d8fd2fcf4eb037fd65ae923c6dbeff6c6ecb4d4fLeon Scroggins     * Holder for the fake title bar.  It will have a foreground shadow, as well
795d8fd2fcf4eb037fd65ae923c6dbeff6c6ecb4d4fLeon Scroggins     * as a white background, so the fake title bar looks like the real one.
796d8fd2fcf4eb037fd65ae923c6dbeff6c6ecb4d4fLeon Scroggins     */
797d8fd2fcf4eb037fd65ae923c6dbeff6c6ecb4d4fLeon Scroggins    private ViewGroup mFakeTitleBarHolder;
798d8fd2fcf4eb037fd65ae923c6dbeff6c6ecb4d4fLeon Scroggins
799d8fd2fcf4eb037fd65ae923c6dbeff6c6ecb4d4fLeon Scroggins    /**
800d8fd2fcf4eb037fd65ae923c6dbeff6c6ecb4d4fLeon Scroggins     * Layout parameters for the fake title bar within mFakeTitleBarHolder
801d8fd2fcf4eb037fd65ae923c6dbeff6c6ecb4d4fLeon Scroggins     */
802d8fd2fcf4eb037fd65ae923c6dbeff6c6ecb4d4fLeon Scroggins    private FrameLayout.LayoutParams mFakeTitleBarParams
803d8fd2fcf4eb037fd65ae923c6dbeff6c6ecb4d4fLeon Scroggins            = new FrameLayout.LayoutParams(
80415b8ec6b226f4d57307716e1f495e10a91f8cbf4Romain Guy            ViewGroup.LayoutParams.MATCH_PARENT,
805d8fd2fcf4eb037fd65ae923c6dbeff6c6ecb4d4fLeon Scroggins            ViewGroup.LayoutParams.WRAP_CONTENT);
806d8fd2fcf4eb037fd65ae923c6dbeff6c6ecb4d4fLeon Scroggins    /**
8073bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     * Keeps track of whether the options menu is open.  This is important in
8083bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     * determining whether to show or hide the title bar overlay.
8093bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     */
8103bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    private boolean mOptionsMenuOpen;
8113bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins
8123bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    /**
8133bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     * Only meaningful when mOptionsMenuOpen is true.  This variable keeps track
8143bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     * of whether the configuration has changed.  The first onMenuOpened call
8153bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     * after a configuration change is simply a reopening of the same menu
8163bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     * (i.e. mIconView did not change).
8173bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     */
8183bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    private boolean mConfigChanged;
8193bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins
8203bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    /**
8213bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     * Whether or not the options menu is in its smaller, icon menu form.  When
8223bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     * true, we want the title bar overlay to be up.  When false, we do not.
8233bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     * Only meaningful if mOptionsMenuOpen is true.
8243bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     */
8253bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    private boolean mIconView;
8263bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins
827a81a764063d2f849fba0cbc3039f86e67c2960ddLeon Scroggins    @Override
828a81a764063d2f849fba0cbc3039f86e67c2960ddLeon Scroggins    public boolean onMenuOpened(int featureId, Menu menu) {
8293bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins        if (Window.FEATURE_OPTIONS_PANEL == featureId) {
8303bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins            if (mOptionsMenuOpen) {
8313bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                if (mConfigChanged) {
8323bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                    // We do not need to make any changes to the state of the
8333bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                    // title bar, since the only thing that happened was a
8343bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                    // change in orientation
8353bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                    mConfigChanged = false;
8363bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                } else {
8373bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                    if (mIconView) {
8383bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                        // Switching the menu to expanded view, so hide the
8393bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                        // title bar.
8403bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                        hideFakeTitleBar();
8413bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                        mIconView = false;
8423bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                    } else {
8433bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                        // Switching the menu back to icon view, so show the
8443bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                        // title bar once again.
8453bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                        showFakeTitleBar();
8463bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                        mIconView = true;
8473bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                    }
8483bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                }
8493bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins            } else {
8503bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                // The options menu is closed, so open it, and show the title
8513bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                showFakeTitleBar();
8523bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                mOptionsMenuOpen = true;
8533bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                mConfigChanged = false;
8543bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                mIconView = true;
8553bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins            }
8563bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins        }
857a81a764063d2f849fba0cbc3039f86e67c2960ddLeon Scroggins        return true;
858a81a764063d2f849fba0cbc3039f86e67c2960ddLeon Scroggins    }
859a81a764063d2f849fba0cbc3039f86e67c2960ddLeon Scroggins
860b94bf27370329abb27e5e33b493d6edb5662b36eLeon Scroggins    /**
861b94bf27370329abb27e5e33b493d6edb5662b36eLeon Scroggins     * Special class used exclusively for the shadow drawn underneath the fake
862b94bf27370329abb27e5e33b493d6edb5662b36eLeon Scroggins     * title bar.  The shadow does not need to be drawn if the WebView
863b94bf27370329abb27e5e33b493d6edb5662b36eLeon Scroggins     * underneath is scrolled to the top, because it will draw directly on top
864b94bf27370329abb27e5e33b493d6edb5662b36eLeon Scroggins     * of the embedded shadow.
865b94bf27370329abb27e5e33b493d6edb5662b36eLeon Scroggins     */
866b94bf27370329abb27e5e33b493d6edb5662b36eLeon Scroggins    private static class Shadow extends View {
867b94bf27370329abb27e5e33b493d6edb5662b36eLeon Scroggins        private WebView mWebView;
868b94bf27370329abb27e5e33b493d6edb5662b36eLeon Scroggins
869b94bf27370329abb27e5e33b493d6edb5662b36eLeon Scroggins        public Shadow(Context context, AttributeSet attrs) {
870b94bf27370329abb27e5e33b493d6edb5662b36eLeon Scroggins            super(context, attrs);
871b94bf27370329abb27e5e33b493d6edb5662b36eLeon Scroggins        }
872b94bf27370329abb27e5e33b493d6edb5662b36eLeon Scroggins
873b94bf27370329abb27e5e33b493d6edb5662b36eLeon Scroggins        public void setWebView(WebView view) {
874b94bf27370329abb27e5e33b493d6edb5662b36eLeon Scroggins            mWebView = view;
875b94bf27370329abb27e5e33b493d6edb5662b36eLeon Scroggins        }
876b94bf27370329abb27e5e33b493d6edb5662b36eLeon Scroggins
877b94bf27370329abb27e5e33b493d6edb5662b36eLeon Scroggins        @Override
878b94bf27370329abb27e5e33b493d6edb5662b36eLeon Scroggins        public void draw(Canvas canvas) {
879b94bf27370329abb27e5e33b493d6edb5662b36eLeon Scroggins            // In general onDraw is the method to override, but we care about
880b94bf27370329abb27e5e33b493d6edb5662b36eLeon Scroggins            // whether or not the background gets drawn, which happens in draw()
881b94bf27370329abb27e5e33b493d6edb5662b36eLeon Scroggins            if (mWebView == null || mWebView.getScrollY() > getHeight()) {
882b94bf27370329abb27e5e33b493d6edb5662b36eLeon Scroggins                super.draw(canvas);
883b94bf27370329abb27e5e33b493d6edb5662b36eLeon Scroggins            }
884b94bf27370329abb27e5e33b493d6edb5662b36eLeon Scroggins            // Need to invalidate so that if the scroll position changes, we
885b94bf27370329abb27e5e33b493d6edb5662b36eLeon Scroggins            // still draw as appropriate.
886b94bf27370329abb27e5e33b493d6edb5662b36eLeon Scroggins            invalidate();
887b94bf27370329abb27e5e33b493d6edb5662b36eLeon Scroggins        }
888b94bf27370329abb27e5e33b493d6edb5662b36eLeon Scroggins    }
889b94bf27370329abb27e5e33b493d6edb5662b36eLeon Scroggins
8903bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    private void showFakeTitleBar() {
891f8de8ecc321fe5b45846adc38d174d5bc2208f20Patrick Scott        final View decor = getWindow().peekDecorView();
892fe87bd3a3897e4bad65bb3d284659ae2f4e57570Leon Scroggins        if (mFakeTitleBar.getParent() == null && mActiveTabsPage == null
893f8de8ecc321fe5b45846adc38d174d5bc2208f20Patrick Scott                && !mActivityInPause && decor != null
894f8de8ecc321fe5b45846adc38d174d5bc2208f20Patrick Scott                && decor.getWindowToken() != null) {
895a04645545690d9f637ccae4d043a5a1b8478a832Cary Clark            Rect visRect = new Rect();
896a04645545690d9f637ccae4d043a5a1b8478a832Cary Clark            if (!mBrowserFrameLayout.getGlobalVisibleRect(visRect)) {
897a04645545690d9f637ccae4d043a5a1b8478a832Cary Clark                if (LOGD_ENABLED) {
898a04645545690d9f637ccae4d043a5a1b8478a832Cary Clark                    Log.d(LOGTAG, "showFakeTitleBar visRect failed");
899a04645545690d9f637ccae4d043a5a1b8478a832Cary Clark                }
900a04645545690d9f637ccae4d043a5a1b8478a832Cary Clark                return;
901a04645545690d9f637ccae4d043a5a1b8478a832Cary Clark            }
9023bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins
9033bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins            WindowManager manager
9043bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                    = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
9053bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins
9063bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins            // Add the title bar to the window manager so it can receive touches
9073bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins            // while the menu is up
9083bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins            WindowManager.LayoutParams params
9093bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                    = new WindowManager.LayoutParams(
91015b8ec6b226f4d57307716e1f495e10a91f8cbf4Romain Guy                    ViewGroup.LayoutParams.MATCH_PARENT,
9113bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                    ViewGroup.LayoutParams.WRAP_CONTENT,
9123bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                    WindowManager.LayoutParams.TYPE_APPLICATION_SUB_PANEL,
9133bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                    WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
914685498685d8424f48d77d26d8d5790da34645f44Leon Scroggins                    PixelFormat.TRANSLUCENT);
9153bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins            params.gravity = Gravity.TOP;
916a27ff19e24cb1c9fef5624dbc4554548349b5b31Leon Scroggins            WebView mainView = mTabControl.getCurrentWebView();
917685498685d8424f48d77d26d8d5790da34645f44Leon Scroggins            boolean atTop = mainView != null && mainView.getScrollY() == 0;
91883932c74ba031eb2f581f1557c1a90f4b5bbb423Leon Scroggins            params.windowAnimations = atTop ? 0 : R.style.TitleBar;
9193bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins            // XXX : Without providing an offset, the fake title bar will be
9203bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins            // placed underneath the status bar.  Use the global visible rect
9213bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins            // of mBrowserFrameLayout to determine the bottom of the status bar
922a04645545690d9f637ccae4d043a5a1b8478a832Cary Clark            params.y = visRect.top;
923685498685d8424f48d77d26d8d5790da34645f44Leon Scroggins            // Add a holder for the title bar.  It also holds a shadow to show
924685498685d8424f48d77d26d8d5790da34645f44Leon Scroggins            // below the title bar.
925d8fd2fcf4eb037fd65ae923c6dbeff6c6ecb4d4fLeon Scroggins            if (mFakeTitleBarHolder == null) {
926d8fd2fcf4eb037fd65ae923c6dbeff6c6ecb4d4fLeon Scroggins                mFakeTitleBarHolder = (ViewGroup) LayoutInflater.from(this)
927d8fd2fcf4eb037fd65ae923c6dbeff6c6ecb4d4fLeon Scroggins                    .inflate(R.layout.title_bar_bg, null);
928d8fd2fcf4eb037fd65ae923c6dbeff6c6ecb4d4fLeon Scroggins            }
929b94bf27370329abb27e5e33b493d6edb5662b36eLeon Scroggins            Shadow shadow = (Shadow) mFakeTitleBarHolder.findViewById(
930b94bf27370329abb27e5e33b493d6edb5662b36eLeon Scroggins                    R.id.shadow);
931b94bf27370329abb27e5e33b493d6edb5662b36eLeon Scroggins            shadow.setWebView(mainView);
932685498685d8424f48d77d26d8d5790da34645f44Leon Scroggins            mFakeTitleBarHolder.addView(mFakeTitleBar, 0, mFakeTitleBarParams);
933d8fd2fcf4eb037fd65ae923c6dbeff6c6ecb4d4fLeon Scroggins            manager.addView(mFakeTitleBarHolder, params);
9343bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins        }
9353bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    }
9363bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins
9373bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    @Override
9383bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    public void onOptionsMenuClosed(Menu menu) {
9393bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins        mOptionsMenuOpen = false;
940a27ff19e24cb1c9fef5624dbc4554548349b5b31Leon Scroggins        if (!mInLoad) {
941a27ff19e24cb1c9fef5624dbc4554548349b5b31Leon Scroggins            hideFakeTitleBar();
942a27ff19e24cb1c9fef5624dbc4554548349b5b31Leon Scroggins        } else if (!mIconView) {
943a27ff19e24cb1c9fef5624dbc4554548349b5b31Leon Scroggins            // The page is currently loading, and we are in expanded mode, so
944a27ff19e24cb1c9fef5624dbc4554548349b5b31Leon Scroggins            // we were not showing the menu.  Show it once again.  It will be
945a27ff19e24cb1c9fef5624dbc4554548349b5b31Leon Scroggins            // removed when the page finishes.
946a27ff19e24cb1c9fef5624dbc4554548349b5b31Leon Scroggins            showFakeTitleBar();
947a27ff19e24cb1c9fef5624dbc4554548349b5b31Leon Scroggins        }
9483bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    }
94922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
9503bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    private void hideFakeTitleBar() {
951fe87bd3a3897e4bad65bb3d284659ae2f4e57570Leon Scroggins        if (mFakeTitleBar.getParent() == null) return;
95220329570ba9409637298da90b83f25801d7a3d55Leon Scroggins        WindowManager.LayoutParams params = (WindowManager.LayoutParams)
95320329570ba9409637298da90b83f25801d7a3d55Leon Scroggins                mFakeTitleBarHolder.getLayoutParams();
95420329570ba9409637298da90b83f25801d7a3d55Leon Scroggins        WebView mainView = mTabControl.getCurrentWebView();
95520329570ba9409637298da90b83f25801d7a3d55Leon Scroggins        // Although we decided whether or not to animate based on the current
95620329570ba9409637298da90b83f25801d7a3d55Leon Scroggins        // scroll position, the scroll position may have changed since the
95720329570ba9409637298da90b83f25801d7a3d55Leon Scroggins        // fake title bar was displayed.  Make sure it has the appropriate
95820329570ba9409637298da90b83f25801d7a3d55Leon Scroggins        // animation/lack thereof before removing.
95920329570ba9409637298da90b83f25801d7a3d55Leon Scroggins        params.windowAnimations = mainView != null && mainView.getScrollY() == 0
96083932c74ba031eb2f581f1557c1a90f4b5bbb423Leon Scroggins                ? 0 : R.style.TitleBar;
9613bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins        WindowManager manager
9623bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                    = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
96320329570ba9409637298da90b83f25801d7a3d55Leon Scroggins        manager.updateViewLayout(mFakeTitleBarHolder, params);
964d8fd2fcf4eb037fd65ae923c6dbeff6c6ecb4d4fLeon Scroggins        mFakeTitleBarHolder.removeView(mFakeTitleBar);
965d8fd2fcf4eb037fd65ae923c6dbeff6c6ecb4d4fLeon Scroggins        manager.removeView(mFakeTitleBarHolder);
9663bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    }
9673bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins
9680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
969c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins     * Special method for the fake title bar to call when displaying its context
970c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins     * menu, since it is in its own Window, and its parent does not show a
971c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins     * context menu.
972c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins     */
973c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins    /* package */ void showTitleBarContextMenu() {
97465f4a3ce9e5c4a5227bbcbb995e5e15f1f85d3d7Cary Clark        if (null == mTitleBar.getParent()) {
97565f4a3ce9e5c4a5227bbcbb995e5e15f1f85d3d7Cary Clark            return;
97665f4a3ce9e5c4a5227bbcbb995e5e15f1f85d3d7Cary Clark        }
977c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins        openContextMenu(mTitleBar);
978c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins    }
979c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins
980b2b19f501ee05448ca81bddaaca70e9b2f51cb54Leon Scroggins    @Override
981b2b19f501ee05448ca81bddaaca70e9b2f51cb54Leon Scroggins    public void onContextMenuClosed(Menu menu) {
982b2b19f501ee05448ca81bddaaca70e9b2f51cb54Leon Scroggins        super.onContextMenuClosed(menu);
983b2b19f501ee05448ca81bddaaca70e9b2f51cb54Leon Scroggins        if (mInLoad) {
984b2b19f501ee05448ca81bddaaca70e9b2f51cb54Leon Scroggins            showFakeTitleBar();
985b2b19f501ee05448ca81bddaaca70e9b2f51cb54Leon Scroggins        }
986b2b19f501ee05448ca81bddaaca70e9b2f51cb54Leon Scroggins    }
987b2b19f501ee05448ca81bddaaca70e9b2f51cb54Leon Scroggins
988c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins    /**
9890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *  onSaveInstanceState(Bundle map)
9900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *  onSaveInstanceState is called right before onStop(). The map contains
9910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *  the saved state.
9920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
99322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    @Override
99422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    protected void onSaveInstanceState(Bundle outState) {
99531a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort        if (LOGV_ENABLED) {
9960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Log.v(LOGTAG, "BrowserActivity.onSaveInstanceState: this=" + this);
9970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
9980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // the default implementation requires each view to have an id. As the
9990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // browser handles the state itself and it doesn't use id for the views,
10000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // don't call the default implementation. Otherwise it will trigger the
10010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // warning like this, "couldn't save which view has focus because the
10020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // focused view XXX has no id".
10030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
10040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Save all the tabs
10050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mTabControl.saveState(outState);
10060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
10070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
100822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    @Override
100922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    protected void onPause() {
10100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        super.onPause();
10110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
10120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mActivityInPause) {
10130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Log.e(LOGTAG, "BrowserActivity is already paused.");
10140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
10150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
10160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
10177bfa63b55644fbf2da1fe6a24b3be0267529202cMike Reed        mTabControl.pauseCurrentTab();
10180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mActivityInPause = true;
10197bfa63b55644fbf2da1fe6a24b3be0267529202cMike Reed        if (mTabControl.getCurrentIndex() >= 0 && !pauseWebViewTimers()) {
10200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mWakeLock.acquire();
10210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mHandler.sendMessageDelayed(mHandler
10220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    .obtainMessage(RELEASE_WAKELOCK), WAKELOCK_TIMEOUT);
10230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
10240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
10250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Clear the credentials toast if it is up
10260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mCredsDlg != null && mCredsDlg.isShowing()) {
10270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mCredsDlg.dismiss();
10280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
10290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mCredsDlg = null;
10300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
1031a2ab6a7dc0f7023c1d7ebb1cbad397c5dc3d6453Leon Scroggins        // FIXME: This removes the active tabs page and resets the menu to
1032a2ab6a7dc0f7023c1d7ebb1cbad397c5dc3d6453Leon Scroggins        // MAIN_MENU.  A better solution might be to do this work in onNewIntent
1033a2ab6a7dc0f7023c1d7ebb1cbad397c5dc3d6453Leon Scroggins        // but then we would need to save it in onSaveInstanceState and restore
1034a2ab6a7dc0f7023c1d7ebb1cbad397c5dc3d6453Leon Scroggins        // it in onCreate/onRestoreInstanceState
1035a2ab6a7dc0f7023c1d7ebb1cbad397c5dc3d6453Leon Scroggins        if (mActiveTabsPage != null) {
1036a2ab6a7dc0f7023c1d7ebb1cbad397c5dc3d6453Leon Scroggins            removeActiveTabPage(true);
1037a2ab6a7dc0f7023c1d7ebb1cbad397c5dc3d6453Leon Scroggins        }
1038a2ab6a7dc0f7023c1d7ebb1cbad397c5dc3d6453Leon Scroggins
10390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        cancelStopToast();
10400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
10410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // unregister network state listener
10420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        unregisterReceiver(mNetworkStateIntentReceiver);
10430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebView.disablePlatformNotifications();
10440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
10450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
104622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    @Override
104722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    protected void onDestroy() {
104831a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort        if (LOGV_ENABLED) {
10490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Log.v(LOGTAG, "BrowserActivity.onDestroy: this=" + this);
10500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
10510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        super.onDestroy();
10520923d69a8ca45222cabd82a80eaa88da9f132e9aGrace Kloba
10538d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins        if (mUploadMessage != null) {
10548d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins            mUploadMessage.onReceiveValue(null);
10558d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins            mUploadMessage = null;
10568d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins        }
10578d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins
10580923d69a8ca45222cabd82a80eaa88da9f132e9aGrace Kloba        if (mTabControl == null) return;
10590923d69a8ca45222cabd82a80eaa88da9f132e9aGrace Kloba
10601fc98a322e9df6b0e797c26de6b2cb23d69ad5d3Grace Kloba        // Remove the fake title bar if it is there
10611fc98a322e9df6b0e797c26de6b2cb23d69ad5d3Grace Kloba        hideFakeTitleBar();
10621fc98a322e9df6b0e797c26de6b2cb23d69ad5d3Grace Kloba
10630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Remove the current tab and sub window
106422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        Tab t = mTabControl.getCurrentTab();
1065fb5e77fac7b8b311fe72827183f8988f5ee92a5fPatrick Scott        if (t != null) {
1066fb5e77fac7b8b311fe72827183f8988f5ee92a5fPatrick Scott            dismissSubWindow(t);
1067fb5e77fac7b8b311fe72827183f8988f5ee92a5fPatrick Scott            removeTabFromContentView(t);
1068fb5e77fac7b8b311fe72827183f8988f5ee92a5fPatrick Scott        }
10690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Destroy all the tabs
10700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mTabControl.destroy();
10710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebIconDatabase.getInstance().close();
10720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
1073b4da0ad0351996f639b50f9f29b123a9b5c24fd0Grace Kloba        unregisterReceiver(mPackageInstallationReceiver);
10740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
10750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
10760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    @Override
10770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public void onConfigurationChanged(Configuration newConfig) {
10783bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins        mConfigChanged = true;
10790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        super.onConfigurationChanged(newConfig);
10800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
10810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mPageInfoDialog != null) {
10820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mPageInfoDialog.dismiss();
10830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            showPageInfo(
10840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mPageInfoView,
1085c7b92f811dfa3572578ddc6714c98a03936d9ce5Leon Scroggins                mPageInfoFromShowSSLCertificateOnError);
10860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
10870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mSSLCertificateDialog != null) {
10880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mSSLCertificateDialog.dismiss();
10890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            showSSLCertificate(
10900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mSSLCertificateView);
10910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
10920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mSSLCertificateOnErrorDialog != null) {
10930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mSSLCertificateOnErrorDialog.dismiss();
10940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            showSSLCertificateOnError(
10950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mSSLCertificateOnErrorView,
10960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mSSLCertificateOnErrorHandler,
10970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mSSLCertificateOnErrorError);
10980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
10990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mHttpAuthenticationDialog != null) {
11000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            String title = ((TextView) mHttpAuthenticationDialog
11010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    .findViewById(com.android.internal.R.id.alertTitle)).getText()
11020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    .toString();
11030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            String name = ((TextView) mHttpAuthenticationDialog
11040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    .findViewById(R.id.username_edit)).getText().toString();
11050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            String password = ((TextView) mHttpAuthenticationDialog
11060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    .findViewById(R.id.password_edit)).getText().toString();
11070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            int focusId = mHttpAuthenticationDialog.getCurrentFocus()
11080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    .getId();
11090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mHttpAuthenticationDialog.dismiss();
11100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            showHttpAuthentication(mHttpAuthHandler, null, null, title,
11110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    name, password, focusId);
11120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
11130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
11140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
111522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    @Override
111622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    public void onLowMemory() {
11170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        super.onLowMemory();
11180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mTabControl.freeMemory();
11190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
11200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
11217bfa63b55644fbf2da1fe6a24b3be0267529202cMike Reed    private boolean resumeWebViewTimers() {
112222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        Tab tab = mTabControl.getCurrentTab();
112322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        boolean inLoad = tab.inLoad();
112422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if ((!mActivityInPause && !inLoad) || (mActivityInPause && inLoad)) {
11250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            CookieSyncManager.getInstance().startSync();
112622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            WebView w = tab.getWebView();
11270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (w != null) {
11280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                w.resumeTimers();
11290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
11300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return true;
11310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
11320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return false;
11330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
11340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
11350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
11367bfa63b55644fbf2da1fe6a24b3be0267529202cMike Reed    private boolean pauseWebViewTimers() {
113722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        Tab tab = mTabControl.getCurrentTab();
113822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        boolean inLoad = tab.inLoad();
113922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mActivityInPause && !inLoad) {
11400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            CookieSyncManager.getInstance().stopSync();
11410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            WebView w = mTabControl.getCurrentWebView();
11420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (w != null) {
11430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                w.pauseTimers();
11440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
11450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return true;
11460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
11470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return false;
11480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
11490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
11500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
11511f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins    // FIXME: Do we want to call this when loading google for the first time?
11520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /*
11530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * This function is called when we are launching for the first time. We
11540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * are waiting for the login credentials before loading Google home
11550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * pages. This way the user will be logged in straight away.
11560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
11570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void waitForCredentials() {
11580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Show a toast
11590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mCredsDlg = new ProgressDialog(this);
11600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mCredsDlg.setIndeterminate(true);
11610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mCredsDlg.setMessage(getText(R.string.retrieving_creds_dlg_msg));
11620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // If the user cancels the operation, then cancel the Google
11630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Credentials request.
11640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mCredsDlg.setCancelMessage(mHandler.obtainMessage(CANCEL_CREDS_REQUEST));
11650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mCredsDlg.show();
11660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
11670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // We set a timeout for the retrieval of credentials in onResume()
11680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // as that is when we have freed up some CPU time to get
11690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // the login credentials.
11700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
11710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
11720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /*
11730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * If we have received the credentials or we have timed out and we are
11740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * showing the credentials dialog, then it is time to move on.
11750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
11760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void resumeAfterCredentials() {
11770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mCredsDlg == null) {
11780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
11790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
11800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
11810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Clear the toast
11820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mCredsDlg.isShowing()) {
11830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mCredsDlg.dismiss();
11840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
11850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mCredsDlg = null;
11860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
11870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Clear any pending timeout
11880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mHandler.removeMessages(CANCEL_CREDS_REQUEST);
11890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
11900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Load the page
11910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebView w = mTabControl.getCurrentWebView();
11920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (w != null) {
11930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            w.loadUrl(mSettings.getHomePage());
11940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
11950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
11960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Update the settings, need to do this last as it can take a moment
11970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // to persist the settings. In the mean time we could be loading
11980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // content.
11990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mSettings.setLoginInitialized(this);
12000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
12010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
12020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Open the icon database and retain all the icons for visited sites.
12030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void retainIconsOnStartup() {
12040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final WebIconDatabase db = WebIconDatabase.getInstance();
12050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        db.open(getDir("icons", 0).getPath());
12060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        try {
12070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Cursor c = Browser.getAllBookmarks(mResolver);
12080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (!c.moveToFirst()) {
12090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                c.deactivate();
12100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                return;
12110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
12120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            int urlIndex = c.getColumnIndex(Browser.BookmarkColumns.URL);
12130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            do {
12140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                String url = c.getString(urlIndex);
12150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                db.retainIconForPageUrl(url);
12160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } while (c.moveToNext());
12170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            c.deactivate();
12180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } catch (IllegalStateException e) {
12190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Log.e(LOGTAG, "retainIconsOnStartup", e);
12200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
12210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
12220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
12230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Helper method for getting the top window.
12240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    WebView getTopWindow() {
12250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return mTabControl.getCurrentTopWebView();
12260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
12270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
122822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    TabControl getTabControl() {
122922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return mTabControl;
123022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
123122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
12320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    @Override
12330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public boolean onCreateOptionsMenu(Menu menu) {
12340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        super.onCreateOptionsMenu(menu);
12350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
12360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        MenuInflater inflater = getMenuInflater();
12370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        inflater.inflate(R.menu.browser, menu);
12380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mMenu = menu;
12390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        updateInLoadMenuItems();
12400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return true;
12410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
12420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
12430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
12440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * As the menu can be open when loading state changes
12450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * we must manually update the state of the stop/reload menu
12460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * item
12470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
12480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void updateInLoadMenuItems() {
12490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mMenu == null) {
12500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
12510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
12520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        MenuItem src = mInLoad ?
12530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mMenu.findItem(R.id.stop_menu_id):
12540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    mMenu.findItem(R.id.reload_menu_id);
12550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        MenuItem dest = mMenu.findItem(R.id.stop_reload_menu_id);
12560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        dest.setIcon(src.getIcon());
12570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        dest.setTitle(src.getTitle());
12580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
12590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
12600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    @Override
12610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public boolean onContextItemSelected(MenuItem item) {
12620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // chording is not an issue with context menus, but we use the same
12630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // options selector, so set mCanChord to true so we can access them.
12640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mCanChord = true;
12650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        int id = item.getItemId();
126696afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins        boolean result = true;
12670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        switch (id) {
1268c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins            // For the context menu from the title bar
1269c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins            case R.id.title_bar_copy_page_url:
127096afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                Tab currentTab = mTabControl.getCurrentTab();
127196afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                if (null == currentTab) {
127296afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                    result = false;
127396afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                    break;
1274c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins                }
127596afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                WebView mainView = currentTab.getWebView();
127696afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                if (null == mainView) {
127796afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                    result = false;
127896afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                    break;
1279c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins                }
128096afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                copy(mainView.getUrl());
1281c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins                break;
12820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // -- Browser context menu
12830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.open_context_menu_id:
12840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.open_newtab_context_menu_id:
12850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.bookmark_context_menu_id:
12860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.save_link_context_menu_id:
12870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.share_link_context_menu_id:
12880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.copy_link_context_menu_id:
1289c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins                final WebView webView = getTopWindow();
1290c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins                if (null == webView) {
129196afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                    result = false;
129296afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                    break;
1293c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins                }
1294c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins                final HashMap hrefMap = new HashMap();
1295c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins                hrefMap.put("webview", webView);
1296c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins                final Message msg = mHandler.obtainMessage(
1297c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins                        FOCUS_NODE_HREF, id, 0, hrefMap);
12980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                webView.requestFocusNodeHref(msg);
12990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
13000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
13010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            default:
13020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // For other context menus
130396afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                result = onOptionsItemSelected(item);
13040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
13050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mCanChord = false;
130696afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins        return result;
13070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
13080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
13090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private Bundle createGoogleSearchSourceBundle(String source) {
13100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        Bundle bundle = new Bundle();
13110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        bundle.putString(SearchManager.SOURCE, source);
13120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return bundle;
13130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
13140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
13150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
13164e5f58704099c37186d4825c3d55ea5b0527867fThe Android Open Source Project     * Overriding this to insert a local information bundle
13170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
13180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    @Override
13190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public boolean onSearchRequested() {
132068579393973f745fc65a2781061af9bb8f2d7020Leon Scroggins        if (mOptionsMenuOpen) closeOptionsMenu();
13215bbe98025a2c606a35c91b826760020890daadb1Leon Scroggins        String url = (getTopWindow() == null) ? null : getTopWindow().getUrl();
132283f473462fcd7869031a423c02b957c6e938a2f6Grace Kloba        startSearch(mSettings.getHomePage().equals(url) ? null : url, true,
13234e5f58704099c37186d4825c3d55ea5b0527867fThe Android Open Source Project                createGoogleSearchSourceBundle(GOOGLE_SEARCH_SOURCE_SEARCHKEY), false);
13240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return true;
13250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
13260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
13270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    @Override
13280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public void startSearch(String initialQuery, boolean selectInitialQuery,
13290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Bundle appSearchData, boolean globalSearch) {
13300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (appSearchData == null) {
13310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            appSearchData = createGoogleSearchSourceBundle(GOOGLE_SEARCH_SOURCE_TYPE);
13320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
13330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        super.startSearch(initialQuery, selectInitialQuery, appSearchData, globalSearch);
13340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
13350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
13361f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins    /**
13371f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins     * Switch tabs.  Called by the TitleBarSet when sliding the title bar
13381f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins     * results in changing tabs.
1339160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins     * @param index Index of the tab to change to, as defined by
1340160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins     *              mTabControl.getTabIndex(Tab t).
1341160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins     * @return boolean True if we successfully switched to a different tab.  If
1342160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins     *                 the indexth tab is null, or if that tab is the same as
1343160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins     *                 the current one, return false.
13441f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins     */
1345160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins    /* package */ boolean switchToTab(int index) {
134622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        Tab tab = mTabControl.getTab(index);
134722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        Tab currentTab = mTabControl.getCurrentTab();
13481f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins        if (tab == null || tab == currentTab) {
1349160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins            return false;
13501f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins        }
13511f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins        if (currentTab != null) {
13521f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins            // currentTab may be null if it was just removed.  In that case,
13531f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins            // we do not need to remove it
13541f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins            removeTabFromContentView(currentTab);
13551f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins        }
13561f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins        mTabControl.setCurrentTab(tab);
13571f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins        attachTabToContentView(tab);
1358eb6eef4c45df2d65c3e70660493a147a2be405e3Grace Kloba        resetTitleIconAndProgress();
1359eb6eef4c45df2d65c3e70660493a147a2be405e3Grace Kloba        updateLockIconToLatest();
1360160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins        return true;
13611f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins    }
13621f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins
136322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /* package */ Tab openTabToHomePage() {
13640a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins        return openTabAndShow(mSettings.getHomePage(), false, null);
13650a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins    }
13660a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins
13671f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins    /* package */ void closeCurrentWindow() {
136822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        final Tab current = mTabControl.getCurrentTab();
1369160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins        if (mTabControl.getTabCount() == 1) {
1370304442375719effd41dbd53ae62de7a8d0cec7d9Leon Scroggins            // This is the last tab.  Open a new one, with the home
1371304442375719effd41dbd53ae62de7a8d0cec7d9Leon Scroggins            // page and close the current one.
137222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            openTabToHomePage();
1373160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins            closeTab(current);
1374160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins            return;
1375160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins        }
137622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        final Tab parent = current.getParentTab();
13771f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins        int indexToShow = -1;
13781f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins        if (parent != null) {
13791f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins            indexToShow = mTabControl.getTabIndex(parent);
13801f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins        } else {
1381160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins            final int currentIndex = mTabControl.getCurrentIndex();
1382160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins            // Try to move to the tab to the right
1383160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins            indexToShow = currentIndex + 1;
1384160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins            if (indexToShow > mTabControl.getTabCount() - 1) {
1385160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins                // Try to move to the tab to the left
1386160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins                indexToShow = currentIndex - 1;
13871f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins            }
13881f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins        }
1389160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins        if (switchToTab(indexToShow)) {
1390160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins            // Close window
1391160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins            closeTab(current);
1392160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins        }
13931f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins    }
13941f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins
13950a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins    private ActiveTabsPage mActiveTabsPage;
13960a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins
13970a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins    /**
13980a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins     * Remove the active tabs page.
13990a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins     * @param needToAttach If true, the active tabs page did not attach a tab
14000a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins     *                     to the content view, so we need to do that here.
14010a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins     */
14020a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins    /* package */ void removeActiveTabPage(boolean needToAttach) {
14030a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins        mContentView.removeView(mActiveTabsPage);
14040a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins        mActiveTabsPage = null;
14050a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins        mMenuState = R.id.MAIN_MENU;
14060a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins        if (needToAttach) {
14070a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins            attachTabToContentView(mTabControl.getCurrentTab());
14080a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins        }
14090a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins        getTopWindow().requestFocus();
14100a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins    }
14110a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins
14120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    @Override
14130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public boolean onOptionsItemSelected(MenuItem item) {
14140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (!mCanChord) {
14150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // The user has already fired a shortcut with this hold down of the
14160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // menu key.
14170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return false;
14180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
14191f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins        if (null == getTopWindow()) {
14200d7ae0ed82e21d472cde8cf92b5657d8ee8ca0d8Leon Scroggins            return false;
14210d7ae0ed82e21d472cde8cf92b5657d8ee8ca0d8Leon Scroggins        }
14226ee9c498b8cf648f1507281ed5a1834ba3390907Grace Kloba        if (mMenuIsDown) {
14236ee9c498b8cf648f1507281ed5a1834ba3390907Grace Kloba            // The shortcut action consumes the MENU. Even if it is still down,
14246ee9c498b8cf648f1507281ed5a1834ba3390907Grace Kloba            // it won't trigger the next shortcut action. In the case of the
14256ee9c498b8cf648f1507281ed5a1834ba3390907Grace Kloba            // shortcut action triggering a new activity, like Bookmarks, we
14266ee9c498b8cf648f1507281ed5a1834ba3390907Grace Kloba            // won't get onKeyUp for MENU. So it is important to reset it here.
14276ee9c498b8cf648f1507281ed5a1834ba3390907Grace Kloba            mMenuIsDown = false;
14286ee9c498b8cf648f1507281ed5a1834ba3390907Grace Kloba        }
14290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        switch (item.getItemId()) {
14300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // -- Main menu
1431a81a764063d2f849fba0cbc3039f86e67c2960ddLeon Scroggins            case R.id.new_tab_menu_id:
14320a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins                openTabToHomePage();
1433a81a764063d2f849fba0cbc3039f86e67c2960ddLeon Scroggins                break;
1434a81a764063d2f849fba0cbc3039f86e67c2960ddLeon Scroggins
143564b80f3efd95d7b5192731e995ccde79c4c6c11fLeon Scroggins            case R.id.goto_menu_id:
1436b3a5bedeede968b53363a6c517f92bc2484bb42dLeon Scroggins                onSearchRequested();
1437b3a5bedeede968b53363a6c517f92bc2484bb42dLeon Scroggins                break;
1438b3a5bedeede968b53363a6c517f92bc2484bb42dLeon Scroggins
1439b3a5bedeede968b53363a6c517f92bc2484bb42dLeon Scroggins            case R.id.bookmarks_menu_id:
1440304442375719effd41dbd53ae62de7a8d0cec7d9Leon Scroggins                bookmarksOrHistoryPicker(false);
14410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
14420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
14430a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins            case R.id.active_tabs_menu_id:
14440a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins                mActiveTabsPage = new ActiveTabsPage(this, mTabControl);
14450a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins                removeTabFromContentView(mTabControl.getCurrentTab());
144643de61666cfc98a3acc41c7161a1a8b0bdb2b72bLeon Scroggins                hideFakeTitleBar();
14470a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins                mContentView.addView(mActiveTabsPage, COVER_SCREEN_PARAMS);
14480a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins                mActiveTabsPage.requestFocus();
14490a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins                mMenuState = EMPTY_MENU;
14500a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins                break;
14510a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins
14521f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins            case R.id.add_bookmark_menu_id:
14531f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                Intent i = new Intent(BrowserActivity.this,
14541f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                        AddBookmarkPage.class);
14551f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                WebView w = getTopWindow();
14561f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                i.putExtra("url", w.getUrl());
14571f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                i.putExtra("title", w.getTitle());
145883cdb2c40f2dbcbdf522a2af0ec8224c7195c6c1Grace Kloba                i.putExtra("touch_icon_url", w.getTouchIconUrl());
1459dcc2b6f08dd5677bc6ba761a9ba6f1c655113051Ben Murdoch                i.putExtra("thumbnail", createScreenshot(w));
14601f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                startActivity(i);
14610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
14620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
14630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.stop_reload_menu_id:
14640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (mInLoad) {
14650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    stopLoading();
14660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                } else {
14670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    getTopWindow().reload();
14680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
14690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
14700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
14710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.back_menu_id:
14720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                getTopWindow().goBack();
14730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
14740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
14750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.forward_menu_id:
14760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                getTopWindow().goForward();
14770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
14780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
14790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.close_menu_id:
14800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // Close the subwindow if it exists.
14810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (mTabControl.getCurrentSubWindow() != null) {
14820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    dismissSubWindow(mTabControl.getCurrentTab());
14830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    break;
14840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
14851f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                closeCurrentWindow();
14860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
14870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
14880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.homepage_menu_id:
148922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                Tab current = mTabControl.getCurrentTab();
14900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (current != null) {
14910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    dismissSubWindow(current);
14920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    current.getWebView().loadUrl(mSettings.getHomePage());
14930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
14940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
14950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
14960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.preferences_menu_id:
14970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                Intent intent = new Intent(this,
14980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        BrowserPreferencesPage.class);
1499d530494de9c182af4aff97ddd46343b32594da51Leon Scroggins                intent.putExtra(BrowserPreferencesPage.CURRENT_PAGE,
1500d530494de9c182af4aff97ddd46343b32594da51Leon Scroggins                        getTopWindow().getUrl());
15010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                startActivityForResult(intent, PREFERENCES_PAGE);
15020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
15030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
15040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.find_menu_id:
15050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (null == mFindDialog) {
15060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    mFindDialog = new FindDialog(this);
15070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
15080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mFindDialog.setWebView(getTopWindow());
15090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mFindDialog.show();
15100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mMenuState = EMPTY_MENU;
15110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
15120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
15130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.select_text_id:
15140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                getTopWindow().emulateShiftHeld();
15150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
15160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.page_info_menu_id:
15170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                showPageInfo(mTabControl.getCurrentTab(), false);
15180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
15190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
15200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.classic_history_menu_id:
1521304442375719effd41dbd53ae62de7a8d0cec7d9Leon Scroggins                bookmarksOrHistoryPicker(true);
15220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
15230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
152496afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins            case R.id.title_bar_share_page_url:
15250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.share_page_menu_id:
152696afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                Tab currentTab = mTabControl.getCurrentTab();
152796afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                if (null == currentTab) {
152896afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                    mCanChord = false;
152996afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                    return false;
153096afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                }
153196afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                currentTab.populatePickerData();
153296afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                sharePage(this, currentTab.getTitle(),
153396afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                        currentTab.getUrl(), currentTab.getFavicon(),
153496afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                        createScreenshot(currentTab.getWebView()));
15350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
15360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
15370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.dump_nav_menu_id:
15380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                getTopWindow().debugDump();
15390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
15400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
15417a8b88b0e0f20544df5ee34b798398603261b733Andrei Popescu            case R.id.dump_counters_menu_id:
15427a8b88b0e0f20544df5ee34b798398603261b733Andrei Popescu                getTopWindow().dumpV8Counters();
15437a8b88b0e0f20544df5ee34b798398603261b733Andrei Popescu                break;
15447a8b88b0e0f20544df5ee34b798398603261b733Andrei Popescu
15450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.zoom_in_menu_id:
15460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                getTopWindow().zoomIn();
15470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
15480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
15490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.zoom_out_menu_id:
15500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                getTopWindow().zoomOut();
15510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
15520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
15530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.view_downloads_menu_id:
15540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                viewDownloads(null);
15550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
15560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
15570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.window_one_menu_id:
15580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.window_two_menu_id:
15590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.window_three_menu_id:
15600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.window_four_menu_id:
15610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.window_five_menu_id:
15620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.window_six_menu_id:
15630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.window_seven_menu_id:
15640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.window_eight_menu_id:
15650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                {
15660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    int menuid = item.getItemId();
15670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    for (int id = 0; id < WINDOW_SHORTCUT_ID_ARRAY.length; id++) {
15680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        if (WINDOW_SHORTCUT_ID_ARRAY[id] == menuid) {
156922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            Tab desiredTab = mTabControl.getTab(id);
15700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            if (desiredTab != null &&
15710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    desiredTab != mTabControl.getCurrentTab()) {
15721f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                                switchToTab(id);
15730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            }
15740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            break;
15750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }
15760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
15770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
15780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
15790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
15800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            default:
15810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (!super.onOptionsItemSelected(item)) {
15820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    return false;
15830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
15840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // Otherwise fall through.
15850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
15860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mCanChord = false;
15870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return true;
15880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
15890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
15900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public void closeFind() {
15910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mMenuState = R.id.MAIN_MENU;
15920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
15930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
159422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    @Override
159522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    public boolean onPrepareOptionsMenu(Menu menu) {
15960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // This happens when the user begins to hold down the menu key, so
15970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // allow them to chord to get a shortcut.
15980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mCanChord = true;
15990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Note: setVisible will decide whether an item is visible; while
16000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // setEnabled() will decide whether an item is enabled, which also means
16010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // whether the matching shortcut key will function.
16020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        super.onPrepareOptionsMenu(menu);
16030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        switch (mMenuState) {
16040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case EMPTY_MENU:
16050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (mCurrentMenuState != mMenuState) {
16060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    menu.setGroupVisible(R.id.MAIN_MENU, false);
16070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    menu.setGroupEnabled(R.id.MAIN_MENU, false);
16080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    menu.setGroupEnabled(R.id.MAIN_SHORTCUT_MENU, false);
16090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
16100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
16110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            default:
16120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (mCurrentMenuState != mMenuState) {
16130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    menu.setGroupVisible(R.id.MAIN_MENU, true);
16140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    menu.setGroupEnabled(R.id.MAIN_MENU, true);
16150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    menu.setGroupEnabled(R.id.MAIN_SHORTCUT_MENU, true);
16160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
16170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                final WebView w = getTopWindow();
16180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                boolean canGoBack = false;
16190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                boolean canGoForward = false;
16200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                boolean isHome = false;
16210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (w != null) {
16220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    canGoBack = w.canGoBack();
16230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    canGoForward = w.canGoForward();
16240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    isHome = mSettings.getHomePage().equals(w.getUrl());
16250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
16260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                final MenuItem back = menu.findItem(R.id.back_menu_id);
16270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                back.setEnabled(canGoBack);
16280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
16290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                final MenuItem home = menu.findItem(R.id.homepage_menu_id);
16300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                home.setEnabled(!isHome);
16310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
16320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.forward_menu_id)
16330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        .setEnabled(canGoForward);
16340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
1635a81a764063d2f849fba0cbc3039f86e67c2960ddLeon Scroggins                menu.findItem(R.id.new_tab_menu_id).setEnabled(
163622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        mTabControl.canCreateNewTab());
1637a81a764063d2f849fba0cbc3039f86e67c2960ddLeon Scroggins
16380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // decide whether to show the share link option
16390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                PackageManager pm = getPackageManager();
16400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                Intent send = new Intent(Intent.ACTION_SEND);
16410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                send.setType("text/plain");
16420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                ResolveInfo ri = pm.resolveActivity(send, PackageManager.MATCH_DEFAULT_ONLY);
16430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.share_page_menu_id).setVisible(ri != null);
16440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
16450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                boolean isNavDump = mSettings.isNavDump();
16460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                final MenuItem nav = menu.findItem(R.id.dump_nav_menu_id);
16470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                nav.setVisible(isNavDump);
16480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                nav.setEnabled(isNavDump);
16497a8b88b0e0f20544df5ee34b798398603261b733Andrei Popescu
16507a8b88b0e0f20544df5ee34b798398603261b733Andrei Popescu                boolean showDebugSettings = mSettings.showDebugSettings();
16517a8b88b0e0f20544df5ee34b798398603261b733Andrei Popescu                final MenuItem counter = menu.findItem(R.id.dump_counters_menu_id);
16527a8b88b0e0f20544df5ee34b798398603261b733Andrei Popescu                counter.setVisible(showDebugSettings);
16537a8b88b0e0f20544df5ee34b798398603261b733Andrei Popescu                counter.setEnabled(showDebugSettings);
16547a8b88b0e0f20544df5ee34b798398603261b733Andrei Popescu
16550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
16560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
16570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mCurrentMenuState = mMenuState;
16580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return true;
16590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
16600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
16610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    @Override
16620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public void onCreateContextMenu(ContextMenu menu, View v,
16630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ContextMenuInfo menuInfo) {
16640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebView webview = (WebView) v;
16650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebView.HitTestResult result = webview.getHitTestResult();
16660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (result == null) {
16670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
16680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
16690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
16700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        int type = result.getType();
16710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (type == WebView.HitTestResult.UNKNOWN_TYPE) {
16720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Log.w(LOGTAG,
16730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    "We should not show context menu when nothing is touched");
16740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
16750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
16760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (type == WebView.HitTestResult.EDIT_TEXT_TYPE) {
16770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // let TextView handles context menu
16780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
16790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
16800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
16810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Note, http://b/issue?id=1106666 is requesting that
16820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // an inflated menu can be used again. This is not available
16830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // yet, so inflate each time (yuk!)
16840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        MenuInflater inflater = getMenuInflater();
16850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        inflater.inflate(R.menu.browsercontext, menu);
16860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
16870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Show the correct menu group
16880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String extra = result.getExtra();
16890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        menu.setGroupVisible(R.id.PHONE_MENU,
16900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                type == WebView.HitTestResult.PHONE_TYPE);
16910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        menu.setGroupVisible(R.id.EMAIL_MENU,
16920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                type == WebView.HitTestResult.EMAIL_TYPE);
16930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        menu.setGroupVisible(R.id.GEO_MENU,
16940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                type == WebView.HitTestResult.GEO_TYPE);
16950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        menu.setGroupVisible(R.id.IMAGE_MENU,
16960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                type == WebView.HitTestResult.IMAGE_TYPE
16970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                || type == WebView.HitTestResult.SRC_IMAGE_ANCHOR_TYPE);
16980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        menu.setGroupVisible(R.id.ANCHOR_MENU,
16990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                type == WebView.HitTestResult.SRC_ANCHOR_TYPE
17000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                || type == WebView.HitTestResult.SRC_IMAGE_ANCHOR_TYPE);
17010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
17020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Setup custom handling depending on the type
17030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        switch (type) {
17040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case WebView.HitTestResult.PHONE_TYPE:
17050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.setHeaderTitle(Uri.decode(extra));
17060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.dial_context_menu_id).setIntent(
17070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new Intent(Intent.ACTION_VIEW, Uri
17080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                .parse(WebView.SCHEME_TEL + extra)));
17090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                Intent addIntent = new Intent(Intent.ACTION_INSERT_OR_EDIT);
17100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                addIntent.putExtra(Insert.PHONE, Uri.decode(extra));
17115e335a381a0cd66e94117b202c1f34f5cb29c9b8Cary Clark                addIntent.setType(ContactsContract.Contacts.CONTENT_ITEM_TYPE);
17120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.add_contact_context_menu_id).setIntent(
17130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        addIntent);
17140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.copy_phone_context_menu_id).setOnMenuItemClickListener(
17150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new Copy(extra));
17160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
17170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
17180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case WebView.HitTestResult.EMAIL_TYPE:
17190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.setHeaderTitle(extra);
17200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.email_context_menu_id).setIntent(
17210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new Intent(Intent.ACTION_VIEW, Uri
17220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                .parse(WebView.SCHEME_MAILTO + extra)));
17230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.copy_mail_context_menu_id).setOnMenuItemClickListener(
17240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new Copy(extra));
17250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
17260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
17270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case WebView.HitTestResult.GEO_TYPE:
17280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.setHeaderTitle(extra);
17290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.map_context_menu_id).setIntent(
17300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new Intent(Intent.ACTION_VIEW, Uri
17310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                .parse(WebView.SCHEME_GEO
17320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        + URLEncoder.encode(extra))));
17330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.copy_geo_context_menu_id).setOnMenuItemClickListener(
17340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new Copy(extra));
17350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
17360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
17370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case WebView.HitTestResult.SRC_ANCHOR_TYPE:
17380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case WebView.HitTestResult.SRC_IMAGE_ANCHOR_TYPE:
17390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                TextView titleView = (TextView) LayoutInflater.from(this)
17400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        .inflate(android.R.layout.browser_link_context_header,
17410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        null);
17420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                titleView.setText(extra);
17430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.setHeaderView(titleView);
17440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // decide whether to show the open link in new tab option
17450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.open_newtab_context_menu_id).setVisible(
174622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        mTabControl.canCreateNewTab());
1747de353621650d17a412b6ffe2cbf0366db5f11c40Ben Murdoch                menu.findItem(R.id.bookmark_context_menu_id).setVisible(
1748de353621650d17a412b6ffe2cbf0366db5f11c40Ben Murdoch                        Bookmarks.urlHasAcceptableScheme(extra));
17490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                PackageManager pm = getPackageManager();
17500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                Intent send = new Intent(Intent.ACTION_SEND);
17510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                send.setType("text/plain");
17520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                ResolveInfo ri = pm.resolveActivity(send, PackageManager.MATCH_DEFAULT_ONLY);
17530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.share_link_context_menu_id).setVisible(ri != null);
17540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (type == WebView.HitTestResult.SRC_ANCHOR_TYPE) {
17550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    break;
17560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
17570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // otherwise fall through to handle image part
17580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case WebView.HitTestResult.IMAGE_TYPE:
17590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (type == WebView.HitTestResult.IMAGE_TYPE) {
17600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    menu.setHeaderTitle(extra);
17610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
17620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.view_image_context_menu_id).setIntent(
17630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new Intent(Intent.ACTION_VIEW, Uri.parse(extra)));
17640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.download_context_menu_id).
17650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        setOnMenuItemClickListener(new Download(extra));
17664f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                menu.findItem(R.id.set_wallpaper_context_menu_id).
17674f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                        setOnMenuItemClickListener(new SetAsWallpaper(extra));
17680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
17690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
17700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            default:
17710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                Log.w(LOGTAG, "We should not get here.");
17720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
17730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
1774b2b19f501ee05448ca81bddaaca70e9b2f51cb54Leon Scroggins        hideFakeTitleBar();
17750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
17760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
17770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Attach the given tab to the content view.
1778c928c30a51eee84b40cb7045842c288c1cfafff0Grace Kloba    // this should only be called for the current tab.
177922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private void attachTabToContentView(Tab t) {
17802bc69918d97a767a02132090e58718077381ba1aSteve Block        // Attach the container that contains the main WebView and any other UI
17812bc69918d97a767a02132090e58718077381ba1aSteve Block        // associated with the tab.
1782d0119535d0c490e087be114ae8fd1639bb1945dcPatrick Scott        t.attachTabToContentView(mContentView);
1783bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch
1784bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch        if (mShouldShowErrorConsole) {
178522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            ErrorConsoleView errorConsole = t.getErrorConsole(true);
1786bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch            if (errorConsole.numberOfErrors() == 0) {
1787bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch                errorConsole.showConsole(ErrorConsoleView.SHOW_NONE);
1788bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch            } else {
1789bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch                errorConsole.showConsole(ErrorConsoleView.SHOW_MINIMIZED);
1790bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch            }
1791bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch
1792bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch            mErrorConsoleContainer.addView(errorConsole,
179315b8ec6b226f4d57307716e1f495e10a91f8cbf4Romain Guy                    new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
1794bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch                                                  ViewGroup.LayoutParams.WRAP_CONTENT));
1795bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch        }
1796bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch
179739ab28eba0c8c837ac80851ec0dd2af336aa3f85Leon Scroggins        WebView view = t.getWebView();
179855a5bc2a8f3c9a0721eeaa5a45241e00d5da95efLeon Scroggins        view.setEmbeddedTitleBar(mTitleBar);
179958d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        if (t.isInVoiceSearchMode()) {
180058d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins            showVoiceTitleBar(t.getVoiceDisplayTitle());
180158d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        } else {
180258d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins            revertVoiceTitleBar();
180358d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        }
18040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Request focus on the top window.
18050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        t.getTopWindow().requestFocus();
18060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
18070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
18080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Attach a sub window to the main WebView of the given tab.
180922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void attachSubWindow(Tab t) {
1810d0119535d0c490e087be114ae8fd1639bb1945dcPatrick Scott        t.attachSubWindow(mContentView);
1811d0119535d0c490e087be114ae8fd1639bb1945dcPatrick Scott        getTopWindow().requestFocus();
18120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
18130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
18140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Remove the given tab from the content view.
181522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private void removeTabFromContentView(Tab t) {
18162bc69918d97a767a02132090e58718077381ba1aSteve Block        // Remove the container that contains the main WebView.
1817d0119535d0c490e087be114ae8fd1639bb1945dcPatrick Scott        t.removeTabFromContentView(mContentView);
1818bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch
181922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        ErrorConsoleView errorConsole = t.getErrorConsole(false);
182022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (errorConsole != null) {
182122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mErrorConsoleContainer.removeView(errorConsole);
1822bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch        }
1823bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch
182439ab28eba0c8c837ac80851ec0dd2af336aa3f85Leon Scroggins        WebView view = t.getWebView();
1825bb85b9016201d45ea939d7cb7edd0ba6616a111cLeon Scroggins        if (view != null) {
1826bb85b9016201d45ea939d7cb7edd0ba6616a111cLeon Scroggins            view.setEmbeddedTitleBar(null);
1827bb85b9016201d45ea939d7cb7edd0ba6616a111cLeon Scroggins        }
18280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
18290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
18300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Remove the sub window if it exists. Also called by TabControl when the
18310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // user clicks the 'X' to dismiss a sub window.
183222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /* package */ void dismissSubWindow(Tab t) {
1833d0119535d0c490e087be114ae8fd1639bb1945dcPatrick Scott        t.removeSubWindow(mContentView);
183422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // dismiss the subwindow. This will destroy the WebView.
183522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        t.dismissSubWindow();
1836d0119535d0c490e087be114ae8fd1639bb1945dcPatrick Scott        getTopWindow().requestFocus();
18370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
18380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
18391f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins    // A wrapper function of {@link #openTabAndShow(UrlData, boolean, String)}
184025ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima    // that accepts url as string.
184122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private Tab openTabAndShow(String url, boolean closeOnExit, String appId) {
18421f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins        return openTabAndShow(new UrlData(url), closeOnExit, appId);
18430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
18440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
18450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // This method does a ton of stuff. It will attempt to create a new tab
18460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // if we haven't reached MAX_TABS. Otherwise it uses the current tab. If
18471f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins    // url isn't null, it will load the given url.
184822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /* package */Tab openTabAndShow(UrlData urlData, boolean closeOnExit,
184922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            String appId) {
185022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        final Tab currentTab = mTabControl.getCurrentTab();
185122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mTabControl.canCreateNewTab()) {
185222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            final Tab tab = mTabControl.createNewTab(closeOnExit, appId,
185322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    urlData.mUrl);
18541f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins            WebView webview = tab.getWebView();
18550a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins            // If the last tab was removed from the active tabs page, currentTab
18560a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins            // will be null.
18570a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins            if (currentTab != null) {
18580a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins                removeTabFromContentView(currentTab);
18590a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins            }
18608bbd69f50abd537bfe7eb314b3a3e20241ac22bdPatrick Scott            // We must set the new tab as the current tab to reflect the old
18618bbd69f50abd537bfe7eb314b3a3e20241ac22bdPatrick Scott            // animation behavior.
18628bbd69f50abd537bfe7eb314b3a3e20241ac22bdPatrick Scott            mTabControl.setCurrentTab(tab);
1863eb6eef4c45df2d65c3e70660493a147a2be405e3Grace Kloba            attachTabToContentView(tab);
1864160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins            if (!urlData.isEmpty()) {
186558d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins                urlData.loadIn(tab);
18660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
18671f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins            return tab;
186864b80f3efd95d7b5192731e995ccde79c4c6c11fLeon Scroggins        } else {
18691f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins            // Get rid of the subwindow if it exists
18701f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins            dismissSubWindow(currentTab);
18711f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins            if (!urlData.isEmpty()) {
18721f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                // Load the given url.
187358d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins                urlData.loadIn(currentTab);
18740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
187558d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins            return currentTab;
18760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
18770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
18780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
187922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private Tab openTab(String url) {
18800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mSettings.openInBackground()) {
188122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            Tab t = mTabControl.createNewTab();
18820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (t != null) {
18831f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                WebView view = t.getWebView();
18841f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                view.loadUrl(url);
18850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
1886c9181841c7ed6b9f7dfc953eab8dc7ba1047022cGrace Kloba            return t;
18870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
18881f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins            return openTabAndShow(url, false, null);
18890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
18900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
18910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
18920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private class Copy implements OnMenuItemClickListener {
18930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        private CharSequence mText;
18940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
18950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public boolean onMenuItemClick(MenuItem item) {
18960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            copy(mText);
18970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return true;
18980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
18990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
19000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public Copy(CharSequence toCopy) {
19010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mText = toCopy;
19020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
19030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
19040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
19050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private class Download implements OnMenuItemClickListener {
19060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        private String mText;
19070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
19080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public boolean onMenuItemClick(MenuItem item) {
19090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            onDownloadStartNoStream(mText, null, null, null, -1);
19100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return true;
19110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
19120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
19130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public Download(String toDownload) {
19140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mText = toDownload;
19150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
19160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
19170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
19184f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch    private class SetAsWallpaper extends Thread implements
19194f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch            OnMenuItemClickListener, DialogInterface.OnCancelListener {
19204f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch        private URL mUrl;
19214f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch        private ProgressDialog mWallpaperProgress;
19224f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch        private boolean mCanceled = false;
19234f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch
19244f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch        public SetAsWallpaper(String url) {
19254f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch            try {
19264f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                mUrl = new URL(url);
19274f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch            } catch (MalformedURLException e) {
19284f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                mUrl = null;
19294f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch            }
19304f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch        }
19314f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch
19324f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch        public void onCancel(DialogInterface dialog) {
19334f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch            mCanceled = true;
19344f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch        }
19354f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch
19364f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch        public boolean onMenuItemClick(MenuItem item) {
19374f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch            if (mUrl != null) {
19384f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                // The user may have tried to set a image with a large file size as their
19394f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                // background so it may take a few moments to perform the operation. Display
19404f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                // a progress spinner while it is working.
19414f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                mWallpaperProgress = new ProgressDialog(BrowserActivity.this);
19424f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                mWallpaperProgress.setIndeterminate(true);
19434f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                mWallpaperProgress.setMessage(getText(R.string.progress_dialog_setting_wallpaper));
19444f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                mWallpaperProgress.setCancelable(true);
19454f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                mWallpaperProgress.setOnCancelListener(this);
19464f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                mWallpaperProgress.show();
19474f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                start();
19484f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch            }
19494f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch            return true;
19504f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch        }
19514f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch
19524f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch        public void run() {
19534f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch            Drawable oldWallpaper = BrowserActivity.this.getWallpaper();
19544f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch            try {
19554f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                // TODO: This will cause the resource to be downloaded again, when we
19564f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                // should in most cases be able to grab it from the cache. To fix this
19574f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                // we should query WebCore to see if we can access a cached version and
19584f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                // instead open an input stream on that. This pattern could also be used
19594f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                // in the download manager where the same problem exists.
19604f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                InputStream inputstream = mUrl.openStream();
19614f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                if (inputstream != null) {
19624f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                    setWallpaper(inputstream);
19634f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                }
19644f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch            } catch (IOException e) {
19654f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                Log.e(LOGTAG, "Unable to set new wallpaper");
19664f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                // Act as though the user canceled the operation so we try to
19674f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                // restore the old wallpaper.
19684f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                mCanceled = true;
19694f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch            }
19704f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch
19714f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch            if (mCanceled) {
19724f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                // Restore the old wallpaper if the user cancelled whilst we were setting
19734f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                // the new wallpaper.
19744f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                int width = oldWallpaper.getIntrinsicWidth();
19754f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                int height = oldWallpaper.getIntrinsicHeight();
19764f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                Bitmap bm = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);
19774f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                Canvas canvas = new Canvas(bm);
19784f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                oldWallpaper.setBounds(0, 0, width, height);
19794f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                oldWallpaper.draw(canvas);
19804f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                try {
19814f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                    setWallpaper(bm);
19824f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                } catch (IOException e) {
19834f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                    Log.e(LOGTAG, "Unable to restore old wallpaper.");
19844f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                }
19854f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                mCanceled = false;
19864f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch            }
19874f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch
19884f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch            if (mWallpaperProgress.isShowing()) {
19894f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                mWallpaperProgress.dismiss();
19904f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch            }
19914f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch        }
19924f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch    }
19934f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch
19940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void copy(CharSequence text) {
19950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        try {
19960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            IClipboard clip = IClipboard.Stub.asInterface(ServiceManager.getService("clipboard"));
19970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (clip != null) {
19980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                clip.setClipboardText(text);
19990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
20000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } catch (android.os.RemoteException e) {
20010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Log.e(LOGTAG, "Copy failed", e);
20020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
20030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
20040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
20050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
20060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Resets the browser title-view to whatever it must be
20070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * (for example, if we had a loading error)
20080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * When we have a new page, we call resetTitle, when we
20090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * have to reset the titlebar to whatever it used to be
20100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * (for example, if the user chose to stop loading), we
20110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * call resetTitleAndRevertLockIcon.
20120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
20130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /* package */ void resetTitleAndRevertLockIcon() {
201422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mTabControl.getCurrentTab().revertLockIcon();
201522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        updateLockIconToLatest();
20160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        resetTitleIconAndProgress();
20170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
20180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
20190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
20200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Reset the title, favicon, and progress.
20210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
20220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void resetTitleIconAndProgress() {
20230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebView current = mTabControl.getCurrentWebView();
20240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (current == null) {
20250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
20260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
20270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        resetTitleAndIcon(current);
20280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        int progress = current.getProgress();
202922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        current.getWebChromeClient().onProgressChanged(current, progress);
20300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
20310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
20320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Reset the title and the icon based on the given item.
20330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void resetTitleAndIcon(WebView view) {
20340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebHistoryItem item = view.copyBackForwardList().getCurrentItem();
20350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (item != null) {
203668579393973f745fc65a2781061af9bb8f2d7020Leon Scroggins            setUrlTitle(item.getUrl(), item.getTitle());
20370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            setFavicon(item.getFavicon());
20380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
203968579393973f745fc65a2781061af9bb8f2d7020Leon Scroggins            setUrlTitle(null, null);
20400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            setFavicon(null);
20410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
20420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
20430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
20440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
20450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Sets a title composed of the URL and the title string.
20460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param url The URL of the site being loaded.
20470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param title The title of the site being loaded.
20480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
204922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void setUrlTitle(String url, String title) {
20500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mUrl = url;
20510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mTitle = title;
20520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
205358d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        // If we are in voice search mode, the title has already been set.
205458d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        if (mTabControl.getCurrentTab().isInVoiceSearchMode()) return;
205558d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        mTitleBar.setDisplayTitle(url);
205658d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        mFakeTitleBar.setDisplayTitle(url);
20570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
20580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
20590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
20600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param url The URL to build a title version of the URL from.
20610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @return The title version of the URL or null if fails.
20620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * The title version of the URL can be either the URL hostname,
20630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * or the hostname with an "https://" prefix (for secure URLs),
20640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * or an empty string if, for example, the URL in question is a
20650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * file:// URL with no hostname.
20660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
206732e14a6deccfa75490b3032bb4ddd5ae90f89de8Leon Scroggins    /* package */ static String buildTitleUrl(String url) {
20680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String titleUrl = null;
20690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
20700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (url != null) {
20710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            try {
20720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // parse the url string
20730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                URL urlObj = new URL(url);
20740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (urlObj != null) {
20750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    titleUrl = "";
20760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
20770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    String protocol = urlObj.getProtocol();
20780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    String host = urlObj.getHost();
20790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
20800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    if (host != null && 0 < host.length()) {
20810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        titleUrl = host;
20820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        if (protocol != null) {
20830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            // if a secure site, add an "https://" prefix!
20840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            if (protocol.equalsIgnoreCase("https")) {
20850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                titleUrl = protocol + "://" + host;
20860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            }
20870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }
20880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
20890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
20900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } catch (MalformedURLException e) {}
20910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
20920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
20930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return titleUrl;
20940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
20950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
20960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Set the favicon in the title bar.
209722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void setFavicon(Bitmap icon) {
209868579393973f745fc65a2781061af9bb8f2d7020Leon Scroggins        mTitleBar.setFavicon(icon);
2099fe87bd3a3897e4bad65bb3d284659ae2f4e57570Leon Scroggins        mFakeTitleBar.setFavicon(icon);
21000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
21010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
21020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
21030a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins     * Close the tab, remove its associated title bar, and adjust mTabControl's
21040a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins     * current tab to a valid value.
21051f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins     */
210622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /* package */ void closeTab(Tab t) {
21070a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins        int currentIndex = mTabControl.getCurrentIndex();
21080a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins        int removeIndex = mTabControl.getTabIndex(t);
21091f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins        mTabControl.removeTab(t);
21100a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins        if (currentIndex >= removeIndex && currentIndex != 0) {
21110a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins            currentIndex--;
21120a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins        }
21130a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins        mTabControl.setCurrentTab(mTabControl.getTab(currentIndex));
2114a5bf1deca120315a2643ea5b010f94d853461b15Andrei Popescu        resetTitleIconAndProgress();
21150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
21160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
21170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void goBackOnePageOrQuit() {
211822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        Tab current = mTabControl.getCurrentTab();
21190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (current == null) {
21200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            /*
21210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project             * Instead of finishing the activity, simply push this to the back
21220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project             * of the stack and let ActivityManager to choose the foreground
21230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project             * activity. As BrowserActivity is singleTask, it will be always the
21240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project             * root of the task. So we can use either true or false for
21250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project             * moveTaskToBack().
21260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project             */
21270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            moveTaskToBack(true);
212800d85e74921459b34e70eb93368245b4c0a9bf5fGrace Kloba            return;
21290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
21300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebView w = current.getWebView();
21310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (w.canGoBack()) {
21320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            w.goBack();
21330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
21340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Check to see if we are closing a window that was created by
21350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // another window. If so, we switch back to that window.
213622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            Tab parent = current.getParentTab();
21370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (parent != null) {
21381f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                switchToTab(mTabControl.getTabIndex(parent));
21391f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                // Now we close the other tab
21401f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                closeTab(current);
21410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } else {
21420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (current.closeOnExit()) {
214322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    // force the tab's inLoad() to be false as we are going to
214422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    // either finish the activity or remove the tab. This will
214522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    // ensure pauseWebViewTimers() taking action.
214622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    mTabControl.getCurrentTab().clearInLoad();
21470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    if (mTabControl.getTabCount() == 1) {
21480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        finish();
21490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        return;
21500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
21517bfa63b55644fbf2da1fe6a24b3be0267529202cMike Reed                    // call pauseWebViewTimers() now, we won't be able to call
21527bfa63b55644fbf2da1fe6a24b3be0267529202cMike Reed                    // it in onPause() as the WebView won't be valid.
2153ec1b5ad8d8283b1fbbc5d7fa1cd50ef95b9e594dGrace Kloba                    // Temporarily change mActivityInPause to be true as
2154ec1b5ad8d8283b1fbbc5d7fa1cd50ef95b9e594dGrace Kloba                    // pauseWebViewTimers() will do nothing if mActivityInPause
2155ec1b5ad8d8283b1fbbc5d7fa1cd50ef95b9e594dGrace Kloba                    // is false.
2156918e1d78b2db6ef21c71a07868572d9cda498476Grace Kloba                    boolean savedState = mActivityInPause;
2157918e1d78b2db6ef21c71a07868572d9cda498476Grace Kloba                    if (savedState) {
2158ec1b5ad8d8283b1fbbc5d7fa1cd50ef95b9e594dGrace Kloba                        Log.e(LOGTAG, "BrowserActivity is already paused "
2159ec1b5ad8d8283b1fbbc5d7fa1cd50ef95b9e594dGrace Kloba                                + "while handing goBackOnePageOrQuit.");
2160918e1d78b2db6ef21c71a07868572d9cda498476Grace Kloba                    }
2161918e1d78b2db6ef21c71a07868572d9cda498476Grace Kloba                    mActivityInPause = true;
21627bfa63b55644fbf2da1fe6a24b3be0267529202cMike Reed                    pauseWebViewTimers();
2163918e1d78b2db6ef21c71a07868572d9cda498476Grace Kloba                    mActivityInPause = savedState;
21640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    removeTabFromContentView(current);
21650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    mTabControl.removeTab(current);
21660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
21670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                /*
21680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                 * Instead of finishing the activity, simply push this to the back
21690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                 * of the stack and let ActivityManager to choose the foreground
21700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                 * activity. As BrowserActivity is singleTask, it will be always the
21710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                 * root of the task. So we can use either true or false for
21720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                 * moveTaskToBack().
21730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                 */
21740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                moveTaskToBack(true);
21750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
21760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
21770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
21780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
217922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    boolean isMenuDown() {
218022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return mMenuIsDown;
218122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
218222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
21835942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba    @Override
21845942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba    public boolean onKeyDown(int keyCode, KeyEvent event) {
2185f65b50ddd2f7ed1205002d74082fff1ac2336d5cLeon Scroggins        // Even if MENU is already held down, we need to call to super to open
2186f65b50ddd2f7ed1205002d74082fff1ac2336d5cLeon Scroggins        // the IME on long press.
2187f65b50ddd2f7ed1205002d74082fff1ac2336d5cLeon Scroggins        if (KeyEvent.KEYCODE_MENU == keyCode) {
2188f65b50ddd2f7ed1205002d74082fff1ac2336d5cLeon Scroggins            mMenuIsDown = true;
2189f65b50ddd2f7ed1205002d74082fff1ac2336d5cLeon Scroggins            return super.onKeyDown(keyCode, event);
2190f65b50ddd2f7ed1205002d74082fff1ac2336d5cLeon Scroggins        }
21915942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba        // The default key mode is DEFAULT_KEYS_SEARCH_LOCAL. As the MENU is
21925942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba        // still down, we don't want to trigger the search. Pretend to consume
21935942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba        // the key and do nothing.
21945942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba        if (mMenuIsDown) return true;
21955942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba
21965942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba        switch(keyCode) {
21975942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba            case KeyEvent.KEYCODE_SPACE:
2198da0fe556a00773ce2af25eb6dcc5442bd08c7addGrace Kloba                // WebView/WebTextView handle the keys in the KeyDown. As
2199da0fe556a00773ce2af25eb6dcc5442bd08c7addGrace Kloba                // the Activity's shortcut keys are only handled when WebView
2200da0fe556a00773ce2af25eb6dcc5442bd08c7addGrace Kloba                // doesn't, have to do it in onKeyDown instead of onKeyUp.
2201da0fe556a00773ce2af25eb6dcc5442bd08c7addGrace Kloba                if (event.isShiftPressed()) {
2202da0fe556a00773ce2af25eb6dcc5442bd08c7addGrace Kloba                    getTopWindow().pageUp(false);
2203da0fe556a00773ce2af25eb6dcc5442bd08c7addGrace Kloba                } else {
2204da0fe556a00773ce2af25eb6dcc5442bd08c7addGrace Kloba                    getTopWindow().pageDown(false);
2205da0fe556a00773ce2af25eb6dcc5442bd08c7addGrace Kloba                }
22065942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                return true;
22075942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba            case KeyEvent.KEYCODE_BACK:
22085942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                if (event.getRepeatCount() == 0) {
22095942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                    event.startTracking();
22105942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                    return true;
22115942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                } else if (mCustomView == null && mActiveTabsPage == null
22125942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                        && event.isLongPress()) {
22135942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                    bookmarksOrHistoryPicker(true);
22145942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                    return true;
22150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
22165942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                break;
22170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
22185942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba        return super.onKeyDown(keyCode, event);
22190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
22200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
22215942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba    @Override
22225942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba    public boolean onKeyUp(int keyCode, KeyEvent event) {
22235942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba        switch(keyCode) {
22245942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba            case KeyEvent.KEYCODE_MENU:
22255942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                mMenuIsDown = false;
22265942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                break;
22275942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba            case KeyEvent.KEYCODE_BACK:
22285942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                if (event.isTracking() && !event.isCanceled()) {
22295942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                    if (mCustomView != null) {
22305942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                        // if a custom view is showing, hide it
223122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        mTabControl.getCurrentWebView().getWebChromeClient()
223222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                .onHideCustomView();
22335942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                    } else if (mActiveTabsPage != null) {
22345942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                        // if tab page is showing, hide it
22355942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                        removeActiveTabPage(true);
22360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    } else {
22375942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                        WebView subwindow = mTabControl.getCurrentSubWindow();
22385942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                        if (subwindow != null) {
22395942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                            if (subwindow.canGoBack()) {
22405942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                                subwindow.goBack();
22415942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                            } else {
22425942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                                dismissSubWindow(mTabControl.getCurrentTab());
22435942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                            }
22445942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                        } else {
22455942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                            goBackOnePageOrQuit();
22465942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                        }
22470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
22485942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                    return true;
22495942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                }
22505942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                break;
22510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
22525942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba        return super.onKeyUp(keyCode, event);
22530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
22540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
225568579393973f745fc65a2781061af9bb8f2d7020Leon Scroggins    /* package */ void stopLoading() {
2256b7cc8b439dc595dc48e1c2183b35d23ad72dfbe5Ben Murdoch        mDidStopLoad = true;
22570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        resetTitleAndRevertLockIcon();
22580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebView w = getTopWindow();
22590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        w.stopLoading();
226022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // FIXME: before refactor, it is using mWebViewClient. So I keep the
226122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // same logic here. But for subwindow case, should we call into the main
226222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // WebView's onPageFinished as we never call its onPageStarted and if
226322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // the page finishes itself, we don't call onPageFinished.
226422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mTabControl.getCurrentWebView().getWebViewClient().onPageFinished(w,
226522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                w.getUrl());
22660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
22670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        cancelStopToast();
22680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mStopToast = Toast
22690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .makeText(this, R.string.stopping, Toast.LENGTH_SHORT);
22700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mStopToast.show();
22710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
22720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
227322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    boolean didUserStopLoading() {
227422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return mDidStopLoad;
227522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
227622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
22770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void cancelStopToast() {
22780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mStopToast != null) {
22790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mStopToast.cancel();
22800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mStopToast = null;
22810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
22820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
22830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
228422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // called by a UI or non-UI thread to post the message
228522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    public void postMessage(int what, int arg1, int arg2, Object obj,
228622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            long delayMillis) {
228722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mHandler.sendMessageDelayed(mHandler.obtainMessage(what, arg1, arg2,
228822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                obj), delayMillis);
228922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
229022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
229122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // called by a UI or non-UI thread to remove the message
229222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void removeMessages(int what, Object object) {
229322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mHandler.removeMessages(what, object);
22940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
22950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
22960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // public message ids
22970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public final static int LOAD_URL                = 1001;
22980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public final static int STOP_LOAD               = 1002;
22990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
23000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Message Ids
23010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private static final int FOCUS_NODE_HREF         = 102;
23020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private static final int CANCEL_CREDS_REQUEST    = 103;
230392c18a52ca7a79c114028b5ba22c3dfe443bd1a4Grace Kloba    private static final int RELEASE_WAKELOCK        = 107;
23040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
230522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    static final int UPDATE_BOOKMARK_THUMBNAIL       = 108;
23062694e23a55d5ca526fc29534a80a200e2c58698bBen Murdoch
23070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Private handler for handling javascript and saving passwords
23080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private Handler mHandler = new Handler() {
23090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
23100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public void handleMessage(Message msg) {
23110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            switch (msg.what) {
23120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                case FOCUS_NODE_HREF:
23132694e23a55d5ca526fc29534a80a200e2c58698bBen Murdoch                {
23140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    String url = (String) msg.getData().get("url");
231590d088caeee718f89755ee9c25249ba6da15ab97Ben Murdoch                    String title = (String) msg.getData().get("title");
23160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    if (url == null || url.length() == 0) {
23170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        break;
23180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
23190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    HashMap focusNodeMap = (HashMap) msg.obj;
23200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    WebView view = (WebView) focusNodeMap.get("webview");
23210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // Only apply the action if the top window did not change.
23220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    if (getTopWindow() != view) {
23230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        break;
23240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
23250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    switch (msg.arg1) {
23260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        case R.id.open_context_menu_id:
23270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        case R.id.view_image_context_menu_id:
23280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            loadURL(getTopWindow(), url);
23290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            break;
23300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        case R.id.open_newtab_context_menu_id:
233122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            final Tab parent = mTabControl.getCurrentTab();
233222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            final Tab newTab = openTab(url);
2333c9181841c7ed6b9f7dfc953eab8dc7ba1047022cGrace Kloba                            if (newTab != parent) {
2334c9181841c7ed6b9f7dfc953eab8dc7ba1047022cGrace Kloba                                parent.addChildTab(newTab);
2335c9181841c7ed6b9f7dfc953eab8dc7ba1047022cGrace Kloba                            }
23360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            break;
23370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        case R.id.bookmark_context_menu_id:
23380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            Intent intent = new Intent(BrowserActivity.this,
23390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    AddBookmarkPage.class);
23400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            intent.putExtra("url", url);
234190d088caeee718f89755ee9c25249ba6da15ab97Ben Murdoch                            intent.putExtra("title", title);
23420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            startActivity(intent);
23430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            break;
23440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        case R.id.share_link_context_menu_id:
234596afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                            // See if this site has been visited before
234696afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                            StringBuilder sb = new StringBuilder(
234796afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                                    Browser.BookmarkColumns.URL + " = ");
234896afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                            DatabaseUtils.appendEscapedSQLString(sb, url);
234996afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                            Cursor c = mResolver.query(Browser.BOOKMARKS_URI,
235096afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                                    Browser.HISTORY_PROJECTION,
235196afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                                    sb.toString(),
235296afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                                    null,
235396afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                                    null);
235496afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                            if (c.moveToFirst()) {
235596afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                                // The site has been visited before, so grab the
235696afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                                // info from the database.
235796afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                                Bitmap favicon = null;
235896afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                                Bitmap thumbnail = null;
235996afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                                String linkTitle = c.getString(Browser.
236096afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                                        HISTORY_PROJECTION_TITLE_INDEX);
236196afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                                byte[] data = c.getBlob(Browser.
236296afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                                        HISTORY_PROJECTION_FAVICON_INDEX);
236396afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                                if (data != null) {
236496afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                                    favicon = BitmapFactory.decodeByteArray(
236596afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                                            data, 0, data.length);
236696afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                                }
236796afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                                data = c.getBlob(Browser.
236896afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                                        HISTORY_PROJECTION_THUMBNAIL_INDEX);
236996afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                                if (data != null) {
237096afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                                    thumbnail = BitmapFactory.decodeByteArray(
237196afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                                            data, 0, data.length);
237296afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                                }
237396afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                                sharePage(BrowserActivity.this,
237496afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                                        linkTitle, url, favicon, thumbnail);
237596afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                            } else {
237696afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                                Browser.sendString(BrowserActivity.this, url,
237796afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                                        getString(
237896afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                                        R.string.choosertitle_sharevia));
237996afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                            }
23800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            break;
23810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        case R.id.copy_link_context_menu_id:
23820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            copy(url);
23830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            break;
23840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        case R.id.save_link_context_menu_id:
23850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        case R.id.download_context_menu_id:
23860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            onDownloadStartNoStream(url, null, null, null, -1);
23870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            break;
23880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
23890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    break;
23902694e23a55d5ca526fc29534a80a200e2c58698bBen Murdoch                }
23910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
23920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                case LOAD_URL:
23930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    loadURL(getTopWindow(), (String) msg.obj);
23940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    break;
23950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
23960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                case STOP_LOAD:
23970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    stopLoading();
23980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    break;
23990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
24000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                case CANCEL_CREDS_REQUEST:
24010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    resumeAfterCredentials();
24020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    break;
24030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
24040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                case RELEASE_WAKELOCK:
24050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    if (mWakeLock.isHeld()) {
24060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        mWakeLock.release();
24075d0e02e646e46b14289168f75c2a8f6ed43cac54Grace Kloba                        // if we reach here, Browser should be still in the
24085d0e02e646e46b14289168f75c2a8f6ed43cac54Grace Kloba                        // background loading after WAKELOCK_TIMEOUT (5-min).
24095d0e02e646e46b14289168f75c2a8f6ed43cac54Grace Kloba                        // To avoid burning the battery, stop loading.
24105d0e02e646e46b14289168f75c2a8f6ed43cac54Grace Kloba                        mTabControl.stopAllLoading();
24110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
24120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    break;
24132694e23a55d5ca526fc29534a80a200e2c58698bBen Murdoch
24142694e23a55d5ca526fc29534a80a200e2c58698bBen Murdoch                case UPDATE_BOOKMARK_THUMBNAIL:
24152694e23a55d5ca526fc29534a80a200e2c58698bBen Murdoch                    WebView view = (WebView) msg.obj;
24162694e23a55d5ca526fc29534a80a200e2c58698bBen Murdoch                    if (view != null) {
24172694e23a55d5ca526fc29534a80a200e2c58698bBen Murdoch                        updateScreenshot(view);
24182694e23a55d5ca526fc29534a80a200e2c58698bBen Murdoch                    }
24192694e23a55d5ca526fc29534a80a200e2c58698bBen Murdoch                    break;
24200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
24210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
24220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    };
24230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
242496afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins    /**
242596afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins     * Share a page, providing the title, url, favicon, and a screenshot.  Uses
242696afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins     * an {@link Intent} to launch the Activity chooser.
242796afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins     * @param c Context used to launch a new Activity.
242896afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins     * @param title Title of the page.  Stored in the Intent with
242996afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins     *          {@link Browser#EXTRA_SHARE_TITLE}
243096afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins     * @param url URL of the page.  Stored in the Intent with
243196afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins     *          {@link Intent#EXTRA_TEXT}
243296afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins     * @param favicon Bitmap of the favicon for the page.  Stored in the Intent
243396afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins     *          with {@link Browser#EXTRA_SHARE_FAVICON}
243496afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins     * @param screenshot Bitmap of a screenshot of the page.  Stored in the
243596afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins     *          Intent with {@link Browser#EXTRA_SHARE_SCREENSHOT}
243696afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins     */
243796afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins    public static final void sharePage(Context c, String title, String url,
243896afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins            Bitmap favicon, Bitmap screenshot) {
243996afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins        Intent send = new Intent(Intent.ACTION_SEND);
244096afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins        send.setType("text/plain");
244196afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins        send.putExtra(Intent.EXTRA_TEXT, url);
244296afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins        send.putExtra(Browser.EXTRA_SHARE_TITLE, title);
244396afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins        send.putExtra(Browser.EXTRA_SHARE_FAVICON, favicon);
244496afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins        send.putExtra(Browser.EXTRA_SHARE_SCREENSHOT, screenshot);
244596afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins        try {
244696afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins            c.startActivity(Intent.createChooser(send, c.getString(
244796afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                    R.string.choosertitle_sharevia)));
244896afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins        } catch(android.content.ActivityNotFoundException ex) {
244996afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins            // if no app handles it, do nothing
245096afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins        }
245196afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins    }
245296afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins
245389c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins    private void updateScreenshot(WebView view) {
245489c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins        // If this is a bookmarked site, add a screenshot to the database.
245589c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins        // FIXME: When should we update?  Every time?
245689c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins        // FIXME: Would like to make sure there is actually something to
245789c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins        // draw, but the API for that (WebViewCore.pictureReady()) is not
245889c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins        // currently accessible here.
2459aac7aa6fcfcb519755987ec126be066323f589c8Ben Murdoch
24603918d4443ff38ef1870e02aa51a8b29f8352bb1aPatrick Scott        ContentResolver cr = getContentResolver();
24613918d4443ff38ef1870e02aa51a8b29f8352bb1aPatrick Scott        final Cursor c = BrowserBookmarksAdapter.queryBookmarksForUrl(
2462aac7aa6fcfcb519755987ec126be066323f589c8Ben Murdoch                cr, view.getOriginalUrl(), view.getUrl(), true);
24633918d4443ff38ef1870e02aa51a8b29f8352bb1aPatrick Scott        if (c != null) {
246489c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins            boolean succeed = c.moveToFirst();
246589c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins            ContentValues values = null;
246689c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins            while (succeed) {
246789c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins                if (values == null) {
246889c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins                    final ByteArrayOutputStream os
246989c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins                            = new ByteArrayOutputStream();
2470dcc2b6f08dd5677bc6ba761a9ba6f1c655113051Ben Murdoch                    Bitmap bm = createScreenshot(view);
24714580057e772b60433272af5cd691825748892693Leon Scroggins                    if (bm == null) {
24724580057e772b60433272af5cd691825748892693Leon Scroggins                        c.close();
24734580057e772b60433272af5cd691825748892693Leon Scroggins                        return;
24744580057e772b60433272af5cd691825748892693Leon Scroggins                    }
247589c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins                    bm.compress(Bitmap.CompressFormat.PNG, 100, os);
247689c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins                    values = new ContentValues();
247789c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins                    values.put(Browser.BookmarkColumns.THUMBNAIL,
247889c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins                            os.toByteArray());
247989c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins                }
248089c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins                cr.update(ContentUris.withAppendedId(Browser.BOOKMARKS_URI,
248189c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins                        c.getInt(0)), values, null, null);
248289c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins                succeed = c.moveToNext();
248389c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins            }
248489c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins            c.close();
248589c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins        }
248689c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins    }
248789c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins
248806ec5f2d8735d1ba17b779deb0f8da032e0a62eaLeon Scroggins    /**
2489f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins     * Values for the size of the thumbnail created when taking a screenshot.
2490f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins     * Lazily initialized.  Instead of using these directly, use
2491f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins     * getDesiredThumbnailWidth() or getDesiredThumbnailHeight().
249206ec5f2d8735d1ba17b779deb0f8da032e0a62eaLeon Scroggins     */
2493f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins    private static int THUMBNAIL_WIDTH = 0;
2494f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins    private static int THUMBNAIL_HEIGHT = 0;
2495f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins
2496f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins    /**
2497f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins     * Return the desired width for thumbnail screenshots, which are stored in
2498f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins     * the database, and used on the bookmarks screen.
2499f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins     * @param context Context for finding out the density of the screen.
2500f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins     * @return int desired width for thumbnail screenshot.
2501f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins     */
2502f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins    /* package */ static int getDesiredThumbnailWidth(Context context) {
2503f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins        if (THUMBNAIL_WIDTH == 0) {
2504f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins            float density = context.getResources().getDisplayMetrics().density;
2505f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins            THUMBNAIL_WIDTH = (int) (90 * density);
2506f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins            THUMBNAIL_HEIGHT = (int) (80 * density);
2507f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins        }
2508f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins        return THUMBNAIL_WIDTH;
2509f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins    }
2510f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins
2511f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins    /**
2512f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins     * Return the desired height for thumbnail screenshots, which are stored in
2513f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins     * the database, and used on the bookmarks screen.
2514f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins     * @param context Context for finding out the density of the screen.
2515f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins     * @return int desired height for thumbnail screenshot.
2516f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins     */
2517f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins    /* package */ static int getDesiredThumbnailHeight(Context context) {
2518f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins        // To ensure that they are both initialized.
2519f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins        getDesiredThumbnailWidth(context);
2520f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins        return THUMBNAIL_HEIGHT;
2521f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins    }
252206ec5f2d8735d1ba17b779deb0f8da032e0a62eaLeon Scroggins
2523dcc2b6f08dd5677bc6ba761a9ba6f1c655113051Ben Murdoch    private Bitmap createScreenshot(WebView view) {
2524dcc2b6f08dd5677bc6ba761a9ba6f1c655113051Ben Murdoch        Picture thumbnail = view.capturePicture();
25254580057e772b60433272af5cd691825748892693Leon Scroggins        if (thumbnail == null) {
25264580057e772b60433272af5cd691825748892693Leon Scroggins            return null;
25274580057e772b60433272af5cd691825748892693Leon Scroggins        }
2528f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins        Bitmap bm = Bitmap.createBitmap(getDesiredThumbnailWidth(this),
2529f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins                getDesiredThumbnailHeight(this), Bitmap.Config.ARGB_4444);
2530dcc2b6f08dd5677bc6ba761a9ba6f1c655113051Ben Murdoch        Canvas canvas = new Canvas(bm);
2531dcc2b6f08dd5677bc6ba761a9ba6f1c655113051Ben Murdoch        // May need to tweak these values to determine what is the
2532dcc2b6f08dd5677bc6ba761a9ba6f1c655113051Ben Murdoch        // best scale factor
25332694e23a55d5ca526fc29534a80a200e2c58698bBen Murdoch        int thumbnailWidth = thumbnail.getWidth();
2534ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch        int thumbnailHeight = thumbnail.getHeight();
2535ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch        float scaleFactorX = 1.0f;
2536ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch        float scaleFactorY = 1.0f;
25372694e23a55d5ca526fc29534a80a200e2c58698bBen Murdoch        if (thumbnailWidth > 0) {
2538ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch            scaleFactorX = (float) getDesiredThumbnailWidth(this) /
25392694e23a55d5ca526fc29534a80a200e2c58698bBen Murdoch                    (float)thumbnailWidth;
2540ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch        } else {
2541ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch            return null;
254206ec5f2d8735d1ba17b779deb0f8da032e0a62eaLeon Scroggins        }
2543ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch
2544ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch        if (view.getWidth() > view.getHeight() &&
2545ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch                thumbnailHeight < view.getHeight() && thumbnailHeight > 0) {
2546ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch            // If the device is in landscape and the page is shorter
2547ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch            // than the height of the view, stretch the thumbnail to fill the
2548ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch            // space.
2549ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch            scaleFactorY = (float) getDesiredThumbnailHeight(this) /
2550ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch                    (float)thumbnailHeight;
2551ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch        } else {
2552ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch            // In the portrait case, this looks nice.
2553ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch            scaleFactorY = scaleFactorX;
2554ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch        }
2555ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch
2556ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch        canvas.scale(scaleFactorX, scaleFactorY);
2557ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch
2558dcc2b6f08dd5677bc6ba761a9ba6f1c655113051Ben Murdoch        thumbnail.draw(canvas);
2559dcc2b6f08dd5677bc6ba761a9ba6f1c655113051Ben Murdoch        return bm;
2560dcc2b6f08dd5677bc6ba761a9ba6f1c655113051Ben Murdoch    }
2561dcc2b6f08dd5677bc6ba761a9ba6f1c655113051Ben Murdoch
25620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // -------------------------------------------------------------------------
256322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // Helper function for WebViewClient.
25640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    //-------------------------------------------------------------------------
25650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
25660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Use in overrideUrlLoading
25670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /* package */ final static String SCHEME_WTAI = "wtai://wp/";
25680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /* package */ final static String SCHEME_WTAI_MC = "wtai://wp/mc;";
25690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /* package */ final static String SCHEME_WTAI_SD = "wtai://wp/sd;";
25700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /* package */ final static String SCHEME_WTAI_AP = "wtai://wp/ap;";
25710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
257222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void onPageStarted(WebView view, String url, Bitmap favicon) {
257322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // when BrowserActivity just starts, onPageStarted may be called before
257422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // onResume as it is triggered from onCreate. Call resumeWebViewTimers
257522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // to start the timer. As we won't switch tabs while an activity is in
257622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // pause state, we can ensure calling resume and pause in pair.
257722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mActivityInPause) resumeWebViewTimers();
257822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
257922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        resetLockIcon(url);
258022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        setUrlTitle(url, null);
258122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        setFavicon(favicon);
25828cf8f682e90f004d4b8028d2f5b74f72c0cf4e19Leon Scroggins        // Keep this initial progress in sync with initialProgressValue (* 100)
25838cf8f682e90f004d4b8028d2f5b74f72c0cf4e19Leon Scroggins        // in ProgressTracker.cpp
25848cf8f682e90f004d4b8028d2f5b74f72c0cf4e19Leon Scroggins        // Show some progress so that the user knows the page is beginning to
25858cf8f682e90f004d4b8028d2f5b74f72c0cf4e19Leon Scroggins        // load
25868cf8f682e90f004d4b8028d2f5b74f72c0cf4e19Leon Scroggins        onProgressChanged(view, 10);
258722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mDidStopLoad = false;
258822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (!mIsNetworkUp) createAndShowNetworkDialog();
25890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
259022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mSettings.isTracing()) {
259122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            String host;
259222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            try {
259322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                WebAddress uri = new WebAddress(url);
259422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                host = uri.mHost;
259522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            } catch (android.net.ParseException ex) {
259622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                host = "browser";
259722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
259822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            host = host.replace('.', '_');
259922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            host += ".trace";
260022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mInTrace = true;
260122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            Debug.startMethodTracing(host, 20 * 1024 * 1024);
260215525d48024d325c8a52766d8ca727191251a8d4Patrick Scott        }
260315525d48024d325c8a52766d8ca727191251a8d4Patrick Scott
260422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Performance probe
260522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (false) {
260622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mStart = SystemClock.uptimeMillis();
260722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mProcessStart = Process.getElapsedCpuTime();
260822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            long[] sysCpu = new long[7];
260922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (Process.readProcFile("/proc/stat", SYSTEM_CPU_FORMAT, null,
261022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    sysCpu, null)) {
261122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                mUserStart = sysCpu[0] + sysCpu[1];
261222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                mSystemStart = sysCpu[2];
261322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                mIdleStart = sysCpu[3];
261422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                mIrqStart = sysCpu[4] + sysCpu[5] + sysCpu[6];
261522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
261622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mUiStart = SystemClock.currentThreadTimeMillis();
26170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
26180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
26190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
262022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void onPageFinished(WebView view, String url) {
262122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Reset the title and icon in case we stopped a provisional load.
262222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        resetTitleAndIcon(view);
262322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Update the lock icon image only once we are done loading
262422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        updateLockIconToLatest();
262522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // pause the WebView timer and release the wake lock if it is finished
262622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // while BrowserActivity is in pause state.
262722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mActivityInPause && pauseWebViewTimers()) {
262822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (mWakeLock.isHeld()) {
262922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                mHandler.removeMessages(RELEASE_WAKELOCK);
263022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                mWakeLock.release();
263122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
263222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
263322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
263422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Performance probe
263522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (false) {
263622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            long[] sysCpu = new long[7];
263722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (Process.readProcFile("/proc/stat", SYSTEM_CPU_FORMAT, null,
263822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    sysCpu, null)) {
263922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                String uiInfo = "UI thread used "
264022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        + (SystemClock.currentThreadTimeMillis() - mUiStart)
264122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        + " ms";
264222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                if (LOGD_ENABLED) {
264322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    Log.d(LOGTAG, uiInfo);
264422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                }
264522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                //The string that gets written to the log
264622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                String performanceString = "It took total "
264722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        + (SystemClock.uptimeMillis() - mStart)
264822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        + " ms clock time to load the page."
264922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        + "\nbrowser process used "
265022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        + (Process.getElapsedCpuTime() - mProcessStart)
265122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        + " ms, user processes used "
265222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        + (sysCpu[0] + sysCpu[1] - mUserStart) * 10
265322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        + " ms, kernel used "
265422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        + (sysCpu[2] - mSystemStart) * 10
265522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        + " ms, idle took " + (sysCpu[3] - mIdleStart) * 10
265622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        + " ms and irq took "
265722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        + (sysCpu[4] + sysCpu[5] + sysCpu[6] - mIrqStart)
265822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        * 10 + " ms, " + uiInfo;
265922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                if (LOGD_ENABLED) {
266022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    Log.d(LOGTAG, performanceString + "\nWebpage: " + url);
26610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
266222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                if (url != null) {
266322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    // strip the url to maintain consistency
266422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    String newUrl = new String(url);
266522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    if (newUrl.startsWith("http://www.")) {
266622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        newUrl = newUrl.substring(11);
266722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    } else if (newUrl.startsWith("http://")) {
266822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        newUrl = newUrl.substring(7);
266922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    } else if (newUrl.startsWith("https://www.")) {
267022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        newUrl = newUrl.substring(12);
267122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    } else if (newUrl.startsWith("https://")) {
267222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        newUrl = newUrl.substring(8);
26730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
267431a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort                    if (LOGD_ENABLED) {
267522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        Log.d(LOGTAG, newUrl + " loaded");
26760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
26770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
26780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
267922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         }
26800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
268122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mInTrace) {
268222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mInTrace = false;
268322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            Debug.stopMethodTracing();
26840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
268522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
26860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
268722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    boolean shouldOverrideUrlLoading(WebView view, String url) {
268822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (url.startsWith(SCHEME_WTAI)) {
268922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // wtai://wp/mc;number
269022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // number=string(phone-number)
269122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (url.startsWith(SCHEME_WTAI_MC)) {
269222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                Intent intent = new Intent(Intent.ACTION_VIEW,
269322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        Uri.parse(WebView.SCHEME_TEL +
269422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        url.substring(SCHEME_WTAI_MC.length())));
269522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                startActivity(intent);
269622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                return true;
26970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
269822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // wtai://wp/sd;dtmf
269922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // dtmf=string(dialstring)
270022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (url.startsWith(SCHEME_WTAI_SD)) {
270122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                // TODO: only send when there is active voice connection
27029918943559193e3e047a1c18442e2cdb0fe22b15Dianne Hackborn                return false;
27039918943559193e3e047a1c18442e2cdb0fe22b15Dianne Hackborn            }
270422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // wtai://wp/ap;number;name
270522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // number=string(phone-number)
270622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // name=string
270722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (url.startsWith(SCHEME_WTAI_AP)) {
270822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                // TODO
27090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                return false;
27100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
27110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
27120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
271322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // The "about:" schemes are internal to the browser; don't want these to
271422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // be dispatched to other apps.
271522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (url.startsWith("about:")) {
271622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            return false;
27170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
27180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
271922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        Intent intent;
272022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // perform generic parsing of the URI to turn it into an Intent.
272122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        try {
272222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            intent = Intent.parseUri(url, Intent.URI_INTENT_SCHEME);
272322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        } catch (URISyntaxException ex) {
272422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            Log.w("Browser", "Bad URI " + url + ": " + ex.getMessage());
272522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            return false;
27260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
27270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
272822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // check whether the intent can be resolved. If not, we will see
272922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // whether we can download it from the Market.
273022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (getPackageManager().resolveActivity(intent, 0) == null) {
273122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            String packagename = intent.getPackage();
273222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (packagename != null) {
273322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                intent = new Intent(Intent.ACTION_VIEW, Uri
273422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        .parse("market://search?q=pname:" + packagename));
273522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                intent.addCategory(Intent.CATEGORY_BROWSABLE);
273622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                startActivity(intent);
273722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                return true;
27380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } else {
27390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                return false;
27400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
27410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
27420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
274322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // sanitize the Intent, ensuring web pages can not bypass browser
274422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // security (only access to BROWSABLE activities).
274522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        intent.addCategory(Intent.CATEGORY_BROWSABLE);
274622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        intent.setComponent(null);
274722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        try {
274822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (startActivityIfNeeded(intent, -1)) {
27490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                return true;
27500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
275122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        } catch (ActivityNotFoundException ex) {
275222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // ignore the error. If no application can handle the URL,
275322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // eg about:blank, assume the browser can handle it.
275422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
27550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
275622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mMenuIsDown) {
275722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            openTab(url);
275822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            closeOptionsMenu();
27590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return true;
27600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
276122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return false;
276222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
27630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
276422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // -------------------------------------------------------------------------
276522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // Helper function for WebChromeClient
276622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // -------------------------------------------------------------------------
27670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
276822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void onProgressChanged(WebView view, int newProgress) {
276922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mTitleBar.setProgress(newProgress);
277022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mFakeTitleBar.setProgress(newProgress);
277122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
277222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (newProgress == 100) {
277322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // onProgressChanged() may continue to be called after the main
277422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // frame has finished loading, as any remaining sub frames continue
277522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // to load. We'll only get called once though with newProgress as
277622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // 100 when everything is loaded. (onPageFinished is called once
277722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // when the main frame completes loading regardless of the state of
277822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // any sub frames so calls to onProgressChanges may continue after
277922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // onPageFinished has executed)
278022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (mInLoad) {
278122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                mInLoad = false;
2782a27ff19e24cb1c9fef5624dbc4554548349b5b31Leon Scroggins                updateInLoadMenuItems();
278322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                // If the options menu is open, leave the title bar
278422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                if (!mOptionsMenuOpen || !mIconView) {
278522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    hideFakeTitleBar();
27860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
27870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
278822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        } else if (!mInLoad) {
278922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // onPageFinished may have already been called but a subframe is
279022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // still loading and updating the progress. Reset mInLoad and update
279122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // the menu items.
279222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mInLoad = true;
279322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            updateInLoadMenuItems();
279422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (!mOptionsMenuOpen || mIconView) {
279522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                // This page has begun to load, so show the title bar
279622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                showFakeTitleBar();
27973918d4443ff38ef1870e02aa51a8b29f8352bb1aPatrick Scott            }
27980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
279922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
2800092dd5d22d7f2ee0efcc68bd6e5a3afd1ea98953Ben Murdoch
280122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void onShowCustomView(View view, WebChromeClient.CustomViewCallback callback) {
28028ff57db0a8dc8eb659fbcdcd4a856208609e6070Derek Sollenberger        // if a view already exists then immediately terminate the new one
28038ff57db0a8dc8eb659fbcdcd4a856208609e6070Derek Sollenberger        if (mCustomView != null) {
28048ff57db0a8dc8eb659fbcdcd4a856208609e6070Derek Sollenberger            callback.onCustomViewHidden();
280522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            return;
28068ff57db0a8dc8eb659fbcdcd4a856208609e6070Derek Sollenberger        }
28072bc69918d97a767a02132090e58718077381ba1aSteve Block
280822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Add the custom view to its container.
280922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mCustomViewContainer.addView(view, COVER_SCREEN_GRAVITY_CENTER);
281022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mCustomView = view;
281122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mCustomViewCallback = callback;
281222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Save the menu state and set it to empty while the custom
281322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // view is showing.
281422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mOldMenuState = mMenuState;
281522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mMenuState = EMPTY_MENU;
281622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Hide the content view.
281722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mContentView.setVisibility(View.GONE);
281822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Finally show the custom view container.
2819163ab74e2f85b53a1a374c49677073fb64d35f28Andrei Popescu        setStatusBarVisibility(false);
282022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mCustomViewContainer.setVisibility(View.VISIBLE);
282122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mCustomViewContainer.bringToFront();
282222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
282322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
282422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void onHideCustomView() {
282522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mCustomView == null)
282622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            return;
28272bc69918d97a767a02132090e58718077381ba1aSteve Block
282822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Hide the custom view.
282922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mCustomView.setVisibility(View.GONE);
283022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Remove the custom view from its container.
283122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mCustomViewContainer.removeView(mCustomView);
283222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mCustomView = null;
283322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Reset the old menu state.
283422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mMenuState = mOldMenuState;
283522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mOldMenuState = EMPTY_MENU;
283622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mCustomViewContainer.setVisibility(View.GONE);
283722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mCustomViewCallback.onCustomViewHidden();
283822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Show the content view.
2839163ab74e2f85b53a1a374c49677073fb64d35f28Andrei Popescu        setStatusBarVisibility(true);
284022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mContentView.setVisibility(View.VISIBLE);
284122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
2842540035dfd1347c78eeec10ec0847e18fcc50ef36Andrei Popescu
284322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    Bitmap getDefaultVideoPoster() {
284422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mDefaultVideoPoster == null) {
284522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mDefaultVideoPoster = BitmapFactory.decodeResource(
284622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    getResources(), R.drawable.default_video_poster);
2847540035dfd1347c78eeec10ec0847e18fcc50ef36Andrei Popescu        }
284822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return mDefaultVideoPoster;
284922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
2850540035dfd1347c78eeec10ec0847e18fcc50ef36Andrei Popescu
285122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    View getVideoLoadingProgressView() {
285222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mVideoProgressView == null) {
285322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            LayoutInflater inflater = LayoutInflater.from(BrowserActivity.this);
285422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mVideoProgressView = inflater.inflate(
285522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    R.layout.video_loading_progress, null);
2856540035dfd1347c78eeec10ec0847e18fcc50ef36Andrei Popescu        }
285722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return mVideoProgressView;
285822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
28590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
28608d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins    /*
28618d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins     * The Object used to inform the WebView of the file to upload.
28628d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins     */
28638d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins    private ValueCallback<Uri> mUploadMessage;
28648d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins
286522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void openFileChooser(ValueCallback<Uri> uploadMsg) {
286622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mUploadMessage != null) return;
286722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mUploadMessage = uploadMsg;
286822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        Intent i = new Intent(Intent.ACTION_GET_CONTENT);
286922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        i.addCategory(Intent.CATEGORY_OPENABLE);
287022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        i.setType("*/*");
287122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        BrowserActivity.this.startActivityForResult(Intent.createChooser(i,
287222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                getString(R.string.choose_upload)), FILE_SELECTED);
287322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
287422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
287522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // -------------------------------------------------------------------------
287622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // Implement functions for DownloadListener
287722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // -------------------------------------------------------------------------
287822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
28790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
28800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Notify the host application a download should be done, or that
28810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * the data should be streamed if a streaming viewer is available.
28820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param url The full url to the content that should be downloaded
28830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param contentDisposition Content-disposition http header, if
28840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *                           present.
28850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param mimetype The mimetype of the content reported by the server
28860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param contentLength The file size reported by the server
28870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
28880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public void onDownloadStart(String url, String userAgent,
28890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            String contentDisposition, String mimetype, long contentLength) {
28900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // if we're dealing wih A/V content that's not explicitly marked
28910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        //     for download, check if it's streamable.
28920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (contentDisposition == null
2893e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                || !contentDisposition.regionMatches(
2894e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                        true, 0, "attachment", 0, 10)) {
28950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // query the package manager to see if there's a registered handler
28960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            //     that matches.
28970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Intent intent = new Intent(Intent.ACTION_VIEW);
28980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            intent.setDataAndType(Uri.parse(url), mimetype);
2899e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott            ResolveInfo info = getPackageManager().resolveActivity(intent,
2900e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                    PackageManager.MATCH_DEFAULT_ONLY);
2901e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott            if (info != null) {
2902e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                ComponentName myName = getComponentName();
2903e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                // If we resolved to ourselves, we don't want to attempt to
2904e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                // load the url only to try and download it again.
2905e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                if (!myName.getPackageName().equals(
2906e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                        info.activityInfo.packageName)
2907e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                        || !myName.getClassName().equals(
2908e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                                info.activityInfo.name)) {
2909e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                    // someone (other than us) knows how to handle this mime
2910e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                    // type with this scheme, don't download.
2911e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                    try {
2912e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                        startActivity(intent);
2913e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                        return;
2914e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                    } catch (ActivityNotFoundException ex) {
2915e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                        if (LOGD_ENABLED) {
2916e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                            Log.d(LOGTAG, "activity not found for " + mimetype
2917e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                                    + " over " + Uri.parse(url).getScheme(),
2918e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                                    ex);
2919e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                        }
2920e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                        // Best behavior is to fall back to a download in this
2921e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                        // case
29220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
29230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
29240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
29250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
29260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        onDownloadStartNoStream(url, userAgent, contentDisposition, mimetype, contentLength);
29270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
29280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
29290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
29300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Notify the host application a download should be done, even if there
29310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * is a streaming viewer available for thise type.
29320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param url The full url to the content that should be downloaded
29330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param contentDisposition Content-disposition http header, if
29340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *                           present.
29350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param mimetype The mimetype of the content reported by the server
29360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param contentLength The file size reported by the server
29370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
29380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /*package */ void onDownloadStartNoStream(String url, String userAgent,
29390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            String contentDisposition, String mimetype, long contentLength) {
29400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
29410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String filename = URLUtil.guessFileName(url,
29420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                contentDisposition, mimetype);
29430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
29440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Check to see if we have an SDCard
29450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String status = Environment.getExternalStorageState();
29460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (!status.equals(Environment.MEDIA_MOUNTED)) {
29470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            int title;
29480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            String msg;
29490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
29500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Check to see if the SDCard is busy, same as the music app
29510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (status.equals(Environment.MEDIA_SHARED)) {
29520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                msg = getString(R.string.download_sdcard_busy_dlg_msg);
29530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                title = R.string.download_sdcard_busy_dlg_title;
29540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } else {
29550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                msg = getString(R.string.download_no_sdcard_dlg_msg, filename);
29560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                title = R.string.download_no_sdcard_dlg_title;
29570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
29580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
29590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            new AlertDialog.Builder(this)
29600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setTitle(title)
29610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setIcon(android.R.drawable.ic_dialog_alert)
29620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setMessage(msg)
29630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setPositiveButton(R.string.ok, null)
29640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .show();
29650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
29660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
29670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
29680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // java.net.URI is a lot stricter than KURL so we have to undo
29690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // KURL's percent-encoding and redo the encoding using java.net.URI.
29700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        URI uri = null;
29710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        try {
29720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Undo the percent-encoding that KURL may have done.
29730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            String newUrl = new String(URLUtil.decode(url.getBytes()));
29740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Parse the url into pieces
29750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            WebAddress w = new WebAddress(newUrl);
29760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            String frag = null;
29770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            String query = null;
29780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            String path = w.mPath;
29790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Break the path into path, query, and fragment
29800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (path.length() > 0) {
29810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // Strip the fragment
29820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                int idx = path.lastIndexOf('#');
29830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (idx != -1) {
29840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    frag = path.substring(idx + 1);
29850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    path = path.substring(0, idx);
29860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
29870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                idx = path.lastIndexOf('?');
29880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (idx != -1) {
29890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    query = path.substring(idx + 1);
29900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    path = path.substring(0, idx);
29910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
29920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
29930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            uri = new URI(w.mScheme, w.mAuthInfo, w.mHost, w.mPort, path,
29940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    query, frag);
29950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } catch (Exception e) {
29960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Log.e(LOGTAG, "Could not parse url for download: " + url, e);
29970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
29980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
29990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
30000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // XXX: Have to use the old url since the cookies were stored using the
30010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // old percent-encoded url.
30020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String cookies = CookieManager.getInstance().getCookie(url);
30030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
30040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        ContentValues values = new ContentValues();
30051e5bad97ca8fb9b12501f4f747941d02f03e1362Jean-Baptiste Queru        values.put(Downloads.Impl.COLUMN_URI, uri.toString());
30061e5bad97ca8fb9b12501f4f747941d02f03e1362Jean-Baptiste Queru        values.put(Downloads.Impl.COLUMN_COOKIE_DATA, cookies);
30071e5bad97ca8fb9b12501f4f747941d02f03e1362Jean-Baptiste Queru        values.put(Downloads.Impl.COLUMN_USER_AGENT, userAgent);
30081e5bad97ca8fb9b12501f4f747941d02f03e1362Jean-Baptiste Queru        values.put(Downloads.Impl.COLUMN_NOTIFICATION_PACKAGE,
30090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                getPackageName());
30101e5bad97ca8fb9b12501f4f747941d02f03e1362Jean-Baptiste Queru        values.put(Downloads.Impl.COLUMN_NOTIFICATION_CLASS,
30110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                BrowserDownloadPage.class.getCanonicalName());
30121e5bad97ca8fb9b12501f4f747941d02f03e1362Jean-Baptiste Queru        values.put(Downloads.Impl.COLUMN_VISIBILITY,
30131e5bad97ca8fb9b12501f4f747941d02f03e1362Jean-Baptiste Queru                Downloads.Impl.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
30141e5bad97ca8fb9b12501f4f747941d02f03e1362Jean-Baptiste Queru        values.put(Downloads.Impl.COLUMN_MIME_TYPE, mimetype);
30151e5bad97ca8fb9b12501f4f747941d02f03e1362Jean-Baptiste Queru        values.put(Downloads.Impl.COLUMN_FILE_NAME_HINT, filename);
30161e5bad97ca8fb9b12501f4f747941d02f03e1362Jean-Baptiste Queru        values.put(Downloads.Impl.COLUMN_DESCRIPTION, uri.getHost());
30170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (contentLength > 0) {
30181e5bad97ca8fb9b12501f4f747941d02f03e1362Jean-Baptiste Queru            values.put(Downloads.Impl.COLUMN_TOTAL_BYTES, contentLength);
30190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
30200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mimetype == null) {
30210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // We must have long pressed on a link or image to download it. We
30220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // are not sure of the mimetype in this case, so do a head request
30230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            new FetchUrlMimeType(this).execute(values);
30240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
30250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            final Uri contentUri =
30261e5bad97ca8fb9b12501f4f747941d02f03e1362Jean-Baptiste Queru                    getContentResolver().insert(Downloads.Impl.CONTENT_URI, values);
30270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
30280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
30290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
30300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
303122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // -------------------------------------------------------------------------
303222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
30330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
30340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Resets the lock icon. This method is called when we start a new load and
30350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * know the url to be loaded.
30360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
30370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void resetLockIcon(String url) {
30380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Save the lock-icon state (we revert to it if the load gets cancelled)
303922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mTabControl.getCurrentTab().resetLockIcon(url);
30400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        updateLockIconImage(LOCK_ICON_UNSECURE);
30410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
30420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
30430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
30443bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     * Update the lock icon to correspond to our latest state.
30453bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     */
304622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private void updateLockIconToLatest() {
304722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        updateLockIconImage(mTabControl.getCurrentTab().getLockIconType());
30483bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    }
30493bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins
30503bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    /**
30510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Updates the lock-icon image in the title-bar.
30520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
30530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void updateLockIconImage(int lockIconType) {
30540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        Drawable d = null;
30550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (lockIconType == LOCK_ICON_SECURE) {
30560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            d = mSecLockIcon;
30570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else if (lockIconType == LOCK_ICON_MIXED) {
30580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            d = mMixLockIcon;
30590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
306068579393973f745fc65a2781061af9bb8f2d7020Leon Scroggins        mTitleBar.setLock(d);
3061fe87bd3a3897e4bad65bb3d284659ae2f4e57570Leon Scroggins        mFakeTitleBar.setLock(d);
30620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
30630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
30640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
30650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Displays a page-info dialog.
30660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param tab The tab to show info about
30670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param fromShowSSLCertificateOnError The flag that indicates whether
30680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * this dialog was opened from the SSL-certificate-on-error dialog or
30690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * not. This is important, since we need to know whether to return to
30700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * the parent dialog or simply dismiss.
30710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
307222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private void showPageInfo(final Tab tab,
30730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                              final boolean fromShowSSLCertificateOnError) {
30740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final LayoutInflater factory = LayoutInflater
30750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .from(this);
30760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
30770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final View pageInfoView = factory.inflate(R.layout.page_info, null);
30780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
30790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final WebView view = tab.getWebView();
30800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
30810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String url = null;
30820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String title = null;
30830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
30840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (view == null) {
30850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            url = tab.getUrl();
30860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            title = tab.getTitle();
30870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else if (view == mTabControl.getCurrentWebView()) {
30880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project             // Use the cached title and url if this is the current WebView
30890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            url = mUrl;
30900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            title = mTitle;
30910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
30920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            url = view.getUrl();
30930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            title = view.getTitle();
30940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
30950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
30960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (url == null) {
30970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            url = "";
30980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
30990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (title == null) {
31000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            title = "";
31010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
31020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
31030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        ((TextView) pageInfoView.findViewById(R.id.address)).setText(url);
31040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        ((TextView) pageInfoView.findViewById(R.id.title)).setText(title);
31050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
31060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mPageInfoView = tab;
3107c7b92f811dfa3572578ddc6714c98a03936d9ce5Leon Scroggins        mPageInfoFromShowSSLCertificateOnError = fromShowSSLCertificateOnError;
31080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
31090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        AlertDialog.Builder alertDialogBuilder =
31100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            new AlertDialog.Builder(this)
31110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            .setTitle(R.string.page_info).setIcon(android.R.drawable.ic_dialog_info)
31120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            .setView(pageInfoView)
31130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            .setPositiveButton(
31140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                R.string.ok,
31150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                new DialogInterface.OnClickListener() {
31160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    public void onClick(DialogInterface dialog,
31170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        int whichButton) {
31180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        mPageInfoDialog = null;
31190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        mPageInfoView = null;
31200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
31210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        // if we came here from the SSL error dialog
31220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        if (fromShowSSLCertificateOnError) {
31230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            // go back to the SSL error dialog
31240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            showSSLCertificateOnError(
31250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorView,
31260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorHandler,
31270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorError);
31280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }
31290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
31300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                })
31310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            .setOnCancelListener(
31320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                new DialogInterface.OnCancelListener() {
31330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    public void onCancel(DialogInterface dialog) {
31340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        mPageInfoDialog = null;
31350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        mPageInfoView = null;
31360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
31370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        // if we came here from the SSL error dialog
31380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        if (fromShowSSLCertificateOnError) {
31390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            // go back to the SSL error dialog
31400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            showSSLCertificateOnError(
31410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorView,
31420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorHandler,
31430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorError);
31440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }
31450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
31460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                });
31470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
31480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // if we have a main top-level page SSL certificate set or a certificate
31490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // error
31500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (fromShowSSLCertificateOnError ||
31510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                (view != null && view.getCertificate() != null)) {
31520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // add a 'View Certificate' button
31530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            alertDialogBuilder.setNeutralButton(
31540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                R.string.view_certificate,
31550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                new DialogInterface.OnClickListener() {
31560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    public void onClick(DialogInterface dialog,
31570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        int whichButton) {
31580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        mPageInfoDialog = null;
31590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        mPageInfoView = null;
31600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
31610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        // if we came here from the SSL error dialog
31620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        if (fromShowSSLCertificateOnError) {
31630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            // go back to the SSL error dialog
31640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            showSSLCertificateOnError(
31650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorView,
31660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorHandler,
31670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorError);
31680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        } else {
31690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            // otherwise, display the top-most certificate from
31700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            // the chain
31710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            if (view.getCertificate() != null) {
31720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                showSSLCertificate(tab);
31730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            }
31740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }
31750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
31760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                });
31770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
31780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
31790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mPageInfoDialog = alertDialogBuilder.show();
31800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
31810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
31820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project       /**
31830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Displays the main top-level page SSL certificate dialog
31840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * (accessible from the Page-Info dialog).
31850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param tab The tab to show certificate for.
31860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
318722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private void showSSLCertificate(final Tab tab) {
31880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final View certificateView =
31890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                inflateCertificateView(tab.getWebView().getCertificate());
31900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (certificateView == null) {
31910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
31920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
31930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
31940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        LayoutInflater factory = LayoutInflater.from(this);
31950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
31960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final LinearLayout placeholder =
31970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                (LinearLayout)certificateView.findViewById(R.id.placeholder);
31980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
31990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        LinearLayout ll = (LinearLayout) factory.inflate(
32000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            R.layout.ssl_success, placeholder);
32010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        ((TextView)ll.findViewById(R.id.success))
32020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            .setText(R.string.ssl_certificate_is_valid);
32030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
32040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mSSLCertificateView = tab;
32050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mSSLCertificateDialog =
32060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            new AlertDialog.Builder(this)
32070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setTitle(R.string.ssl_certificate).setIcon(
32080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    R.drawable.ic_dialog_browser_certificate_secure)
32090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setView(certificateView)
32100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setPositiveButton(R.string.ok,
32110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new DialogInterface.OnClickListener() {
32120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            public void onClick(DialogInterface dialog,
32130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    int whichButton) {
32140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateDialog = null;
32150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateView = null;
32160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
32170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                showPageInfo(tab, false);
32180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            }
32190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        })
32200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setOnCancelListener(
32210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new DialogInterface.OnCancelListener() {
32220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            public void onCancel(DialogInterface dialog) {
32230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateDialog = null;
32240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateView = null;
32250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
32260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                showPageInfo(tab, false);
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     * Displays the SSL error certificate dialog.
32340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param view The target web-view.
32350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param handler The SSL error handler responsible for cancelling the
32360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * connection that resulted in an SSL error or proceeding per user request.
32370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param error The SSL error object.
32380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
323922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void showSSLCertificateOnError(
32400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final WebView view, final SslErrorHandler handler, final SslError error) {
32410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
32420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final View certificateView =
32430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            inflateCertificateView(error.getCertificate());
32440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (certificateView == null) {
32450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
32460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
32470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
32480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        LayoutInflater factory = LayoutInflater.from(this);
32490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
32500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final LinearLayout placeholder =
32510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                (LinearLayout)certificateView.findViewById(R.id.placeholder);
32520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
32530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (error.hasError(SslError.SSL_UNTRUSTED)) {
32540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            LinearLayout ll = (LinearLayout)factory
32550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .inflate(R.layout.ssl_warning, placeholder);
32560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((TextView)ll.findViewById(R.id.warning))
32570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setText(R.string.ssl_untrusted);
32580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
32590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
32600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (error.hasError(SslError.SSL_IDMISMATCH)) {
32610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            LinearLayout ll = (LinearLayout)factory
32620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .inflate(R.layout.ssl_warning, placeholder);
32630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((TextView)ll.findViewById(R.id.warning))
32640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setText(R.string.ssl_mismatch);
32650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
32660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
32670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (error.hasError(SslError.SSL_EXPIRED)) {
32680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            LinearLayout ll = (LinearLayout)factory
32690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .inflate(R.layout.ssl_warning, placeholder);
32700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((TextView)ll.findViewById(R.id.warning))
32710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setText(R.string.ssl_expired);
32720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
32730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
32740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (error.hasError(SslError.SSL_NOTYETVALID)) {
32750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            LinearLayout ll = (LinearLayout)factory
32760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .inflate(R.layout.ssl_warning, placeholder);
32770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((TextView)ll.findViewById(R.id.warning))
32780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setText(R.string.ssl_not_yet_valid);
32790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
32800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
32810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mSSLCertificateOnErrorHandler = handler;
32820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mSSLCertificateOnErrorView = view;
32830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mSSLCertificateOnErrorError = error;
32840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mSSLCertificateOnErrorDialog =
32850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            new AlertDialog.Builder(this)
32860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setTitle(R.string.ssl_certificate).setIcon(
32870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    R.drawable.ic_dialog_browser_certificate_partially_secure)
32880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setView(certificateView)
32890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setPositiveButton(R.string.ok,
32900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new DialogInterface.OnClickListener() {
32910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            public void onClick(DialogInterface dialog,
32920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    int whichButton) {
32930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorDialog = null;
32940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorView = null;
32950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorHandler = null;
32960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorError = null;
32970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
329822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                view.getWebViewClient().onReceivedSslError(
329922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                                view, handler, error);
33000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            }
33010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        })
33020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                 .setNeutralButton(R.string.page_info_view,
33030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new DialogInterface.OnClickListener() {
33040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            public void onClick(DialogInterface dialog,
33050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    int whichButton) {
33060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorDialog = null;
33070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
33080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                // do not clear the dialog state: we will
33090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                // need to show the dialog again once the
33100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                // user is done exploring the page-info details
33110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
33120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                showPageInfo(mTabControl.getTabFromView(view),
33130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        true);
33140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            }
33150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        })
33160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setOnCancelListener(
33170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new DialogInterface.OnCancelListener() {
33180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            public void onCancel(DialogInterface dialog) {
33190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorDialog = null;
33200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorView = null;
33210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorHandler = null;
33220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorError = null;
33230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
332422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                view.getWebViewClient().onReceivedSslError(
332522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                                view, handler, error);
33260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            }
33270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        })
33280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .show();
33290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
33300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
33310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
33320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Inflates the SSL certificate view (helper method).
33330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param certificate The SSL certificate.
33340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @return The resultant certificate view with issued-to, issued-by,
33350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * issued-on, expires-on, and possibly other fields set.
33360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * If the input certificate is null, returns null.
33370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
33380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private View inflateCertificateView(SslCertificate certificate) {
33390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (certificate == null) {
33400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return null;
33410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
33420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
33430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        LayoutInflater factory = LayoutInflater.from(this);
33440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
33450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        View certificateView = factory.inflate(
33460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            R.layout.ssl_certificate, null);
33470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
33480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // issued to:
33490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        SslCertificate.DName issuedTo = certificate.getIssuedTo();
33500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (issuedTo != null) {
33510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((TextView) certificateView.findViewById(R.id.to_common))
33520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setText(issuedTo.getCName());
33530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((TextView) certificateView.findViewById(R.id.to_org))
33540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setText(issuedTo.getOName());
33550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((TextView) certificateView.findViewById(R.id.to_org_unit))
33560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setText(issuedTo.getUName());
33570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
33580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
33590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // issued by:
33600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        SslCertificate.DName issuedBy = certificate.getIssuedBy();
33610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (issuedBy != null) {
33620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((TextView) certificateView.findViewById(R.id.by_common))
33630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setText(issuedBy.getCName());
33640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((TextView) certificateView.findViewById(R.id.by_org))
33650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setText(issuedBy.getOName());
33660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((TextView) certificateView.findViewById(R.id.by_org_unit))
33670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setText(issuedBy.getUName());
33680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
33690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
33700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // issued on:
33710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String issuedOn = reformatCertificateDate(
33720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            certificate.getValidNotBefore());
33730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        ((TextView) certificateView.findViewById(R.id.issued_on))
33740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            .setText(issuedOn);
33750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
33760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // expires on:
33770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String expiresOn = reformatCertificateDate(
33780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            certificate.getValidNotAfter());
33790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        ((TextView) certificateView.findViewById(R.id.expires_on))
33800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            .setText(expiresOn);
33810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
33820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return certificateView;
33830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
33840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
33850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
33860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Re-formats the certificate date (Date.toString()) string to
33870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * a properly localized date string.
33880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @return Properly localized version of the certificate date string and
33890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * the original certificate date string if fails to localize.
33900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * If the original string is null, returns an empty string "".
33910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
33920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private String reformatCertificateDate(String certificateDate) {
33930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project      String reformattedDate = null;
33940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
33950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project      if (certificateDate != null) {
33960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project          Date date = null;
33970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project          try {
33980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project              date = java.text.DateFormat.getInstance().parse(certificateDate);
33990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project          } catch (ParseException e) {
34000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project              date = null;
34010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project          }
34020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
34030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project          if (date != null) {
34040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project              reformattedDate =
34050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                  DateFormat.getDateFormat(this).format(date);
34060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project          }
34070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project      }
34080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
34090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project      return reformattedDate != null ? reformattedDate :
34100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project          (certificateDate != null ? certificateDate : "");
34110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
34120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
34130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
34140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Displays an http-authentication dialog.
34150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
341622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void showHttpAuthentication(final HttpAuthHandler handler,
34170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            final String host, final String realm, final String title,
34180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            final String name, final String password, int focusId) {
34190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        LayoutInflater factory = LayoutInflater.from(this);
34200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final View v = factory
34210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .inflate(R.layout.http_authentication, null);
34220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (name != null) {
34230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((EditText) v.findViewById(R.id.username_edit)).setText(name);
34240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
34250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (password != null) {
34260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((EditText) v.findViewById(R.id.password_edit)).setText(password);
34270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
34280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
34290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String titleText = title;
34300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (titleText == null) {
34310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            titleText = getText(R.string.sign_in_to).toString().replace(
34320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    "%s1", host).replace("%s2", realm);
34330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
34340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
34350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mHttpAuthHandler = handler;
34360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        AlertDialog dialog = new AlertDialog.Builder(this)
34370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setTitle(titleText)
34380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setIcon(android.R.drawable.ic_dialog_alert)
34390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setView(v)
34400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setPositiveButton(R.string.action,
34410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new DialogInterface.OnClickListener() {
34420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                             public void onClick(DialogInterface dialog,
34430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                     int whichButton) {
34440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                String nm = ((EditText) v
34450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        .findViewById(R.id.username_edit))
34460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        .getText().toString();
34470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                String pw = ((EditText) v
34480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        .findViewById(R.id.password_edit))
34490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        .getText().toString();
34500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                BrowserActivity.this.setHttpAuthUsernamePassword
34510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        (host, realm, nm, pw);
34520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                handler.proceed(nm, pw);
34530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mHttpAuthenticationDialog = null;
34540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mHttpAuthHandler = null;
34550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            }})
34560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setNegativeButton(R.string.cancel,
34570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new DialogInterface.OnClickListener() {
34580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            public void onClick(DialogInterface dialog,
34590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    int whichButton) {
34600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                handler.cancel();
34610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                BrowserActivity.this.resetTitleAndRevertLockIcon();
34620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mHttpAuthenticationDialog = null;
34630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mHttpAuthHandler = null;
34640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            }})
34650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setOnCancelListener(new DialogInterface.OnCancelListener() {
34660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        public void onCancel(DialogInterface dialog) {
34670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            handler.cancel();
34680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            BrowserActivity.this.resetTitleAndRevertLockIcon();
34690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            mHttpAuthenticationDialog = null;
34700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            mHttpAuthHandler = null;
34710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }})
34720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .create();
34730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Make the IME appear when the dialog is displayed if applicable.
34740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        dialog.getWindow().setSoftInputMode(
34750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);
34760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        dialog.show();
34770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (focusId != 0) {
34780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            dialog.findViewById(focusId).requestFocus();
34790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
34800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            v.findViewById(R.id.username_edit).requestFocus();
34810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
34820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mHttpAuthenticationDialog = dialog;
34830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
34840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
34850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public int getProgress() {
34860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebView w = mTabControl.getCurrentWebView();
34870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (w != null) {
34880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return w.getProgress();
34890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
34900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return 100;
34910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
34920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
34930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
34940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
34950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Set HTTP authentication password.
34960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *
34970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param host The host for the password
34980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param realm The realm for the password
34990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param username The username for the password. If it is null, it means
35000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *            password can't be saved.
35010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param password The password
35020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
35030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public void setHttpAuthUsernamePassword(String host, String realm,
35040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                            String username,
35050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                            String password) {
35060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebView w = mTabControl.getCurrentWebView();
35070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (w != null) {
35080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            w.setHttpAuthUsernamePassword(host, realm, username, password);
35090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
35100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
35110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
35120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
35130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * connectivity manager says net has come or gone... inform the user
35140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param up true if net has come up, false if net has gone down
35150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
35160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public void onNetworkToggle(boolean up) {
35170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (up == mIsNetworkUp) {
35180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
35190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else if (up) {
35200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mIsNetworkUp = true;
35210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (mAlertDialog != null) {
35220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mAlertDialog.cancel();
35230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mAlertDialog = null;
35240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
35250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
35260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mIsNetworkUp = false;
3527eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott            if (mInLoad) {
3528eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott                createAndShowNetworkDialog();
3529eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott           }
35300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
35310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebView w = mTabControl.getCurrentWebView();
35320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (w != null) {
35330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            w.setNetworkAvailable(up);
35340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
35350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
35360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
353722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    boolean isNetworkUp() {
353822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return mIsNetworkUp;
353922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
354022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
3541eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott    // This method shows the network dialog alerting the user that the net is
3542eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott    // down. It will only show the dialog if mAlertDialog is null.
3543eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott    private void createAndShowNetworkDialog() {
3544eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott        if (mAlertDialog == null) {
3545eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott            mAlertDialog = new AlertDialog.Builder(this)
3546eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott                    .setTitle(R.string.loadSuspendedTitle)
3547eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott                    .setMessage(R.string.loadSuspended)
3548eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott                    .setPositiveButton(R.string.ok, null)
3549eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott                    .show();
3550eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott        }
3551eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott    }
3552eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott
35530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    @Override
35540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    protected void onActivityResult(int requestCode, int resultCode,
35550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    Intent intent) {
3556bb394f3e134b6e5898ef7ae861b75e95e618688fGrace Kloba        if (getTopWindow() == null) return;
3557bb394f3e134b6e5898ef7ae861b75e95e618688fGrace Kloba
35580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        switch (requestCode) {
35590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case COMBO_PAGE:
35600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (resultCode == RESULT_OK && intent != null) {
35610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    String data = intent.getAction();
35620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    Bundle extras = intent.getExtras();
35630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    if (extras != null && extras.getBoolean("new_window", false)) {
356425d3547e0df084f963e38c6a93c99b02bd619de3Leon Scroggins                        openTab(data);
35650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    } else {
356622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        final Tab currentTab =
35670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mTabControl.getCurrentTab();
35681f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                        dismissSubWindow(currentTab);
35691f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                        if (data != null && data.length() != 0) {
35701f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                            getTopWindow().loadUrl(data);
35710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }
35720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
35730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
3574fde9746ac3055848e110c35f19ec5893c621f766Leon Scroggins                // Deliberately fall through to PREFERENCES_PAGE, since the
3575fde9746ac3055848e110c35f19ec5893c621f766Leon Scroggins                // same extra may be attached to the COMBO_PAGE
3576fde9746ac3055848e110c35f19ec5893c621f766Leon Scroggins            case PREFERENCES_PAGE:
3577fde9746ac3055848e110c35f19ec5893c621f766Leon Scroggins                if (resultCode == RESULT_OK && intent != null) {
3578fde9746ac3055848e110c35f19ec5893c621f766Leon Scroggins                    String action = intent.getStringExtra(Intent.EXTRA_TEXT);
3579fde9746ac3055848e110c35f19ec5893c621f766Leon Scroggins                    if (BrowserSettings.PREF_CLEAR_HISTORY.equals(action)) {
3580fde9746ac3055848e110c35f19ec5893c621f766Leon Scroggins                        mTabControl.removeParentChildRelationShips();
3581fde9746ac3055848e110c35f19ec5893c621f766Leon Scroggins                    }
3582fde9746ac3055848e110c35f19ec5893c621f766Leon Scroggins                }
35830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
35848d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins            // Choose a file from the file picker.
35858d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins            case FILE_SELECTED:
35868d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins                if (null == mUploadMessage) break;
35878d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins                Uri result = intent == null || resultCode != RESULT_OK ? null
35888d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins                        : intent.getData();
35898d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins                mUploadMessage.onReceiveValue(result);
35908d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins                mUploadMessage = null;
35918d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins                break;
35920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            default:
35930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
35940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
3595304442375719effd41dbd53ae62de7a8d0cec7d9Leon Scroggins        getTopWindow().requestFocus();
35960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
35970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
35980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /*
35990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * This method is called as a result of the user selecting the options
3600f08809b2cf7e502fef5965691a7fb6d7cf0322afLeon Scroggins     * menu to see the download window. It shows the download window on top of
3601f08809b2cf7e502fef5965691a7fb6d7cf0322afLeon Scroggins     * the current window.
36020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
3603f08809b2cf7e502fef5965691a7fb6d7cf0322afLeon Scroggins    private void viewDownloads(Uri downloadRecord) {
36040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        Intent intent = new Intent(this,
36050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                BrowserDownloadPage.class);
36060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        intent.setData(downloadRecord);
360722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        startActivityForResult(intent, BrowserActivity.DOWNLOAD_PAGE);
36080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
36090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
36100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
3611160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins    /**
3612160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins     * Open the Go page.
3613160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins     * @param startWithHistory If true, open starting on the history tab.
3614160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins     *                         Otherwise, start with the bookmarks tab.
3615160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins     */
3616304442375719effd41dbd53ae62de7a8d0cec7d9Leon Scroggins    /* package */ void bookmarksOrHistoryPicker(boolean startWithHistory) {
36170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebView current = mTabControl.getCurrentWebView();
36180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (current == null) {
36190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
36200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
36210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        Intent intent = new Intent(this,
36220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                CombinedBookmarkHistoryActivity.class);
36230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String title = current.getTitle();
36240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String url = current.getUrl();
3625dcc2b6f08dd5677bc6ba761a9ba6f1c655113051Ben Murdoch        Bitmap thumbnail = createScreenshot(current);
3626dcc2b6f08dd5677bc6ba761a9ba6f1c655113051Ben Murdoch
36270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Just in case the user opens bookmarks before a page finishes loading
36280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // so the current history item, and therefore the page, is null.
36290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (null == url) {
36300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            url = mLastEnteredUrl;
36310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // This can happen.
36320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (null == url) {
36330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                url = mSettings.getHomePage();
36340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
36350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
36360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // In case the web page has not yet received its associated title.
36370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (title == null) {
36380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            title = url;
36390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
36400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        intent.putExtra("title", title);
36410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        intent.putExtra("url", url);
3642dcc2b6f08dd5677bc6ba761a9ba6f1c655113051Ben Murdoch        intent.putExtra("thumbnail", thumbnail);
3643304442375719effd41dbd53ae62de7a8d0cec7d9Leon Scroggins        // Disable opening in a new window if we have maxed out the windows
364422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        intent.putExtra("disable_new_window", !mTabControl.canCreateNewTab());
36453918d4443ff38ef1870e02aa51a8b29f8352bb1aPatrick Scott        intent.putExtra("touch_icon_url", current.getTouchIconUrl());
36460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (startWithHistory) {
36470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            intent.putExtra(CombinedBookmarkHistoryActivity.STARTING_TAB,
36480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    CombinedBookmarkHistoryActivity.HISTORY_TAB);
36490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
36500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        startActivityForResult(intent, COMBO_PAGE);
36510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
36520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
36530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Called when loading from context menu or LOAD_URL message
36540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void loadURL(WebView view, String url) {
36550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // In case the user enters nothing.
36560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (url != null && url.length() != 0 && view != null) {
36570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            url = smartUrlFilter(url);
365822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (!view.getWebViewClient().shouldOverrideUrlLoading(view, url)) {
36590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                view.loadUrl(url);
36600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
36610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
36620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
36630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
36640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private String smartUrlFilter(Uri inUri) {
36650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (inUri != null) {
36660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return smartUrlFilter(inUri.toString());
36670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
36680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return null;
36690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
36700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
3671b34f87a2e13af13d697130482af01b537ab7c5fdFeng Qian    protected static final Pattern ACCEPTED_URI_SCHEMA = Pattern.compile(
36720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            "(?i)" + // switch on case insensitive matching
36730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            "(" +    // begin group for schema
36740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            "(?:http|https|file):\\/\\/" +
367525ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima            "|(?:inline|data|about|content|javascript):" +
36760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ")" +
36770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            "(.*)" );
36780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
36790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
36800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Attempts to determine whether user input is a URL or search
36810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * terms.  Anything with a space is passed to search.
36820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *
36830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Converts to lowercase any mistakenly uppercased schema (i.e.,
36840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * "Http://" converts to "http://"
36850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *
36860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @return Original or modified URL
36870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *
36880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
36890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    String smartUrlFilter(String url) {
36900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
36910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String inUrl = url.trim();
36920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        boolean hasSpace = inUrl.indexOf(' ') != -1;
36930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
36940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        Matcher matcher = ACCEPTED_URI_SCHEMA.matcher(inUrl);
36950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (matcher.matches()) {
36960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // force scheme to lowercase
36970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            String scheme = matcher.group(1);
36980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            String lcScheme = scheme.toLowerCase();
36990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (!lcScheme.equals(scheme)) {
3700123ecfb21e7ca670e3d04efe58780b3bac54a9a1Mitsuru Oshima                inUrl = lcScheme + matcher.group(2);
3701123ecfb21e7ca670e3d04efe58780b3bac54a9a1Mitsuru Oshima            }
3702123ecfb21e7ca670e3d04efe58780b3bac54a9a1Mitsuru Oshima            if (hasSpace) {
3703123ecfb21e7ca670e3d04efe58780b3bac54a9a1Mitsuru Oshima                inUrl = inUrl.replace(" ", "%20");
37040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
37050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return inUrl;
37060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
37070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (hasSpace) {
3708565505b1a2c1d3099496af5910760087602e994aSatish Sampath            // FIXME: Is this the correct place to add to searches?
3709565505b1a2c1d3099496af5910760087602e994aSatish Sampath            // what if someone else calls this function?
3710565505b1a2c1d3099496af5910760087602e994aSatish Sampath            int shortcut = parseUrlShortcut(inUrl);
3711565505b1a2c1d3099496af5910760087602e994aSatish Sampath            if (shortcut != SHORTCUT_INVALID) {
3712565505b1a2c1d3099496af5910760087602e994aSatish Sampath                Browser.addSearchUrl(mResolver, inUrl);
3713565505b1a2c1d3099496af5910760087602e994aSatish Sampath                String query = inUrl.substring(2);
3714565505b1a2c1d3099496af5910760087602e994aSatish Sampath                switch (shortcut) {
3715565505b1a2c1d3099496af5910760087602e994aSatish Sampath                case SHORTCUT_GOOGLE_SEARCH:
371647fdfdb989ffb79590a39c40792be995de32e521Grace Kloba                    return URLUtil.composeSearchUrl(query, QuickSearch_G, QUERY_PLACE_HOLDER);
3717565505b1a2c1d3099496af5910760087602e994aSatish Sampath                case SHORTCUT_WIKIPEDIA_SEARCH:
3718565505b1a2c1d3099496af5910760087602e994aSatish Sampath                    return URLUtil.composeSearchUrl(query, QuickSearch_W, QUERY_PLACE_HOLDER);
3719565505b1a2c1d3099496af5910760087602e994aSatish Sampath                case SHORTCUT_DICTIONARY_SEARCH:
3720565505b1a2c1d3099496af5910760087602e994aSatish Sampath                    return URLUtil.composeSearchUrl(query, QuickSearch_D, QUERY_PLACE_HOLDER);
3721565505b1a2c1d3099496af5910760087602e994aSatish Sampath                case SHORTCUT_GOOGLE_MOBILE_LOCAL_SEARCH:
37220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // FIXME: we need location in this case
3723565505b1a2c1d3099496af5910760087602e994aSatish Sampath                    return URLUtil.composeSearchUrl(query, QuickSearch_L, QUERY_PLACE_HOLDER);
37240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
37250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
37260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
37275ee906c089567bca705e18561357510d7b55cb5aDan Egnor            if (Patterns.WEB_URL.matcher(inUrl).matches()) {
37280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                return URLUtil.guessUrl(inUrl);
37290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
37300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
37310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
37320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        Browser.addSearchUrl(mResolver, inUrl);
373347fdfdb989ffb79590a39c40792be995de32e521Grace Kloba        return URLUtil.composeSearchUrl(inUrl, QuickSearch_G, QUERY_PLACE_HOLDER);
37340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
37350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
3736bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch    /* package */ void setShouldShowErrorConsole(boolean flag) {
3737bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch        if (flag == mShouldShowErrorConsole) {
3738bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch            // Nothing to do.
3739bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch            return;
3740bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch        }
3741bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch
3742bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch        mShouldShowErrorConsole = flag;
3743bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch
374422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        ErrorConsoleView errorConsole = mTabControl.getCurrentTab()
374522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                .getErrorConsole(true);
3746bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch
3747bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch        if (flag) {
3748bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch            // Setting the show state of the console will cause it's the layout to be inflated.
3749bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch            if (errorConsole.numberOfErrors() > 0) {
3750bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch                errorConsole.showConsole(ErrorConsoleView.SHOW_MINIMIZED);
3751bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch            } else {
3752bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch                errorConsole.showConsole(ErrorConsoleView.SHOW_NONE);
3753bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch            }
3754bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch
3755bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch            // Now we can add it to the main view.
3756bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch            mErrorConsoleContainer.addView(errorConsole,
375715b8ec6b226f4d57307716e1f495e10a91f8cbf4Romain Guy                    new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
3758bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch                                                  ViewGroup.LayoutParams.WRAP_CONTENT));
3759bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch        } else {
3760bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch            mErrorConsoleContainer.removeView(errorConsole);
3761bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch        }
3762bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch
3763bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch    }
3764bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch
376522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    boolean shouldShowErrorConsole() {
376622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return mShouldShowErrorConsole;
376722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
376822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
3769163ab74e2f85b53a1a374c49677073fb64d35f28Andrei Popescu    private void setStatusBarVisibility(boolean visible) {
3770163ab74e2f85b53a1a374c49677073fb64d35f28Andrei Popescu        int flag = visible ? 0 : WindowManager.LayoutParams.FLAG_FULLSCREEN;
3771163ab74e2f85b53a1a374c49677073fb64d35f28Andrei Popescu        getWindow().setFlags(flag, WindowManager.LayoutParams.FLAG_FULLSCREEN);
3772163ab74e2f85b53a1a374c49677073fb64d35f28Andrei Popescu    }
3773163ab74e2f85b53a1a374c49677073fb64d35f28Andrei Popescu
377456199cc25e7ee0455ec2a8099098b66b8554f677Andrei Popescu
377556199cc25e7ee0455ec2a8099098b66b8554f677Andrei Popescu    private void sendNetworkType(String type, String subtype) {
377656199cc25e7ee0455ec2a8099098b66b8554f677Andrei Popescu        WebView w = mTabControl.getCurrentWebView();
377756199cc25e7ee0455ec2a8099098b66b8554f677Andrei Popescu        if (w != null) {
377856199cc25e7ee0455ec2a8099098b66b8554f677Andrei Popescu            w.setNetworkType(type, subtype);
377956199cc25e7ee0455ec2a8099098b66b8554f677Andrei Popescu        }
378056199cc25e7ee0455ec2a8099098b66b8554f677Andrei Popescu    }
378156199cc25e7ee0455ec2a8099098b66b8554f677Andrei Popescu
3782eb6eef4c45df2d65c3e70660493a147a2be405e3Grace Kloba    final static int LOCK_ICON_UNSECURE = 0;
3783eb6eef4c45df2d65c3e70660493a147a2be405e3Grace Kloba    final static int LOCK_ICON_SECURE   = 1;
3784eb6eef4c45df2d65c3e70660493a147a2be405e3Grace Kloba    final static int LOCK_ICON_MIXED    = 2;
37850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
37860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private BrowserSettings mSettings;
37870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private TabControl      mTabControl;
37880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private ContentResolver mResolver;
37890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private FrameLayout     mContentView;
3790adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu    private View            mCustomView;
3791adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu    private FrameLayout     mCustomViewContainer;
3792c9b5556351b59caec77b4eec1ad30652fec6a4d9Andrei Popescu    private WebChromeClient.CustomViewCallback mCustomViewCallback;
37930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
37940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // FIXME, temp address onPrepareMenu performance problem. When we move everything out of
37950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // view, we should rewrite this.
37960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private int mCurrentMenuState = 0;
37970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private int mMenuState = R.id.MAIN_MENU;
3798adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu    private int mOldMenuState = EMPTY_MENU;
37990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private static final int EMPTY_MENU = -1;
38000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private Menu mMenu;
38010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
38020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private FindDialog mFindDialog;
38030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Used to prevent chording to result in firing two shortcuts immediately
38040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // one after another.  Fixes bug 1211714.
38050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    boolean mCanChord;
38060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
38070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private boolean mInLoad;
38080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private boolean mIsNetworkUp;
3809b7cc8b439dc595dc48e1c2183b35d23ad72dfbe5Ben Murdoch    private boolean mDidStopLoad;
38100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
38110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private boolean mActivityInPause = true;
38120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
38130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private boolean mMenuIsDown;
38140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
38150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private static boolean mInTrace;
38160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
38170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Performance probe
38180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private static final int[] SYSTEM_CPU_FORMAT = new int[] {
38190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Process.PROC_SPACE_TERM | Process.PROC_COMBINE,
38200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Process.PROC_SPACE_TERM | Process.PROC_OUT_LONG, // 1: user time
38210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Process.PROC_SPACE_TERM | Process.PROC_OUT_LONG, // 2: nice time
38220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Process.PROC_SPACE_TERM | Process.PROC_OUT_LONG, // 3: sys time
38230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Process.PROC_SPACE_TERM | Process.PROC_OUT_LONG, // 4: idle time
38240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Process.PROC_SPACE_TERM | Process.PROC_OUT_LONG, // 5: iowait time
38250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Process.PROC_SPACE_TERM | Process.PROC_OUT_LONG, // 6: irq time
38260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Process.PROC_SPACE_TERM | Process.PROC_OUT_LONG  // 7: softirq time
38270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    };
38280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
38290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private long mStart;
38300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private long mProcessStart;
38310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private long mUserStart;
38320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private long mSystemStart;
38330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private long mIdleStart;
38340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private long mIrqStart;
38350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
38360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private long mUiStart;
38370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
38380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private Drawable    mMixLockIcon;
38390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private Drawable    mSecLockIcon;
38400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
38410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /* hold a ref so we can auto-cancel if necessary */
38420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private AlertDialog mAlertDialog;
38430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
38440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Wait for credentials before loading google.com
38450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private ProgressDialog mCredsDlg;
38460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
38470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // The up-to-date URL and title (these can be different from those stored
38480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // in WebView, since it takes some time for the information in WebView to
38490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // get updated)
38500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private String mUrl;
38510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private String mTitle;
38520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
38530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // As PageInfo has different style for landscape / portrait, we have
38540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // to re-open it when configuration changed
38550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private AlertDialog mPageInfoDialog;
385622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private Tab mPageInfoView;
38570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // If the Page-Info dialog is launched from the SSL-certificate-on-error
38580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // dialog, we should not just dismiss it, but should get back to the
38590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // SSL-certificate-on-error dialog. This flag is used to store this state
3860c7b92f811dfa3572578ddc6714c98a03936d9ce5Leon Scroggins    private boolean mPageInfoFromShowSSLCertificateOnError;
38610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
38620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // as SSLCertificateOnError has different style for landscape / portrait,
38630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // we have to re-open it when configuration changed
38640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private AlertDialog mSSLCertificateOnErrorDialog;
38650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private WebView mSSLCertificateOnErrorView;
38660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private SslErrorHandler mSSLCertificateOnErrorHandler;
38670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private SslError mSSLCertificateOnErrorError;
38680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
38690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // as SSLCertificate has different style for landscape / portrait, we
38700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // have to re-open it when configuration changed
38710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private AlertDialog mSSLCertificateDialog;
387222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private Tab mSSLCertificateView;
38730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
38740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // as HttpAuthentication has different style for landscape / portrait, we
38750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // have to re-open it when configuration changed
38760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private AlertDialog mHttpAuthenticationDialog;
38770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private HttpAuthHandler mHttpAuthHandler;
38780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
38790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /*package*/ static final FrameLayout.LayoutParams COVER_SCREEN_PARAMS =
38800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                            new FrameLayout.LayoutParams(
388115b8ec6b226f4d57307716e1f495e10a91f8cbf4Romain Guy                                            ViewGroup.LayoutParams.MATCH_PARENT,
388215b8ec6b226f4d57307716e1f495e10a91f8cbf4Romain Guy                                            ViewGroup.LayoutParams.MATCH_PARENT);
3883adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu    /*package*/ static final FrameLayout.LayoutParams COVER_SCREEN_GRAVITY_CENTER =
3884adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu                                            new FrameLayout.LayoutParams(
388515b8ec6b226f4d57307716e1f495e10a91f8cbf4Romain Guy                                            ViewGroup.LayoutParams.MATCH_PARENT,
388615b8ec6b226f4d57307716e1f495e10a91f8cbf4Romain Guy                                            ViewGroup.LayoutParams.MATCH_PARENT,
3887adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu                                            Gravity.CENTER);
388847fdfdb989ffb79590a39c40792be995de32e521Grace Kloba    // Google search
388947fdfdb989ffb79590a39c40792be995de32e521Grace Kloba    final static String QuickSearch_G = "http://www.google.com/m?q=%s";
38900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Wikipedia search
38910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    final static String QuickSearch_W = "http://en.wikipedia.org/w/index.php?search=%s&go=Go";
38920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Dictionary search
38930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    final static String QuickSearch_D = "http://dictionary.reference.com/search?q=%s";
38940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Google Mobile Local search
38950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    final static String QuickSearch_L = "http://www.google.com/m/search?site=local&q=%s&near=mountain+view";
38960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
38970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    final static String QUERY_PLACE_HOLDER = "%s";
38980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
38990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // "source" parameter for Google search through search key
39000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    final static String GOOGLE_SEARCH_SOURCE_SEARCHKEY = "browser-key";
39010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // "source" parameter for Google search through goto menu
39020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    final static String GOOGLE_SEARCH_SOURCE_GOTO = "browser-goto";
39030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // "source" parameter for Google search through simplily type
39040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    final static String GOOGLE_SEARCH_SOURCE_TYPE = "browser-type";
39050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // "source" parameter for Google search suggested by the browser
39060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    final static String GOOGLE_SEARCH_SOURCE_SUGGEST = "browser-suggest";
39070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // "source" parameter for Google search from unknown source
39080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    final static String GOOGLE_SEARCH_SOURCE_UNKNOWN = "unknown";
39090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
39100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private final static String LOGTAG = "browser";
39110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
39120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private String mLastEnteredUrl;
39130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
39140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private PowerManager.WakeLock mWakeLock;
39150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private final static int WAKELOCK_TIMEOUT = 5 * 60 * 1000; // 5 minutes
39160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
39170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private Toast mStopToast;
39180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
391968579393973f745fc65a2781061af9bb8f2d7020Leon Scroggins    private TitleBar mTitleBar;
392081db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins
3921bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch    private LinearLayout mErrorConsoleContainer = null;
3922bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch    private boolean mShouldShowErrorConsole = false;
3923bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch
39240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // As the ids are dynamically created, we can't guarantee that they will
39250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // be in sequence, so this static array maps ids to a window number.
39260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    final static private int[] WINDOW_SHORTCUT_ID_ARRAY =
39270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    { R.id.window_one_menu_id, R.id.window_two_menu_id, R.id.window_three_menu_id,
39280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project      R.id.window_four_menu_id, R.id.window_five_menu_id, R.id.window_six_menu_id,
39290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project      R.id.window_seven_menu_id, R.id.window_eight_menu_id };
39300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
39310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // monitor platform changes
39320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private IntentFilter mNetworkStateChangedFilter;
39330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private BroadcastReceiver mNetworkStateIntentReceiver;
39340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
3935b4da0ad0351996f639b50f9f29b123a9b5c24fd0Grace Kloba    private BroadcastReceiver mPackageInstallationReceiver;
3936b4da0ad0351996f639b50f9f29b123a9b5c24fd0Grace Kloba
39370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // activity requestCode
393878a98e459323f938e97789a6131beddbebb459ceNicolas Roard    final static int COMBO_PAGE                 = 1;
393978a98e459323f938e97789a6131beddbebb459ceNicolas Roard    final static int DOWNLOAD_PAGE              = 2;
394078a98e459323f938e97789a6131beddbebb459ceNicolas Roard    final static int PREFERENCES_PAGE           = 3;
39418d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins    final static int FILE_SELECTED              = 4;
39420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
3943540035dfd1347c78eeec10ec0847e18fcc50ef36Andrei Popescu    // the default <video> poster
3944540035dfd1347c78eeec10ec0847e18fcc50ef36Andrei Popescu    private Bitmap mDefaultVideoPoster;
3945540035dfd1347c78eeec10ec0847e18fcc50ef36Andrei Popescu    // the video progress view
3946540035dfd1347c78eeec10ec0847e18fcc50ef36Andrei Popescu    private View mVideoProgressView;
3947540035dfd1347c78eeec10ec0847e18fcc50ef36Andrei Popescu
394825ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima    /**
394925ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima     * A UrlData class to abstract how the content will be set to WebView.
395025ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima     * This base class uses loadUrl to show the content.
395125ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima     */
395225ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima    private static class UrlData {
3953068e48b469f5abca53ee3da38f933cf2c25c93b8Grace Kloba        final String mUrl;
3954068e48b469f5abca53ee3da38f933cf2c25c93b8Grace Kloba        final Map<String, String> mHeaders;
395558d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        final Intent mVoiceIntent;
395660e095c190496d42327f8ec2ef990c044d15a76fGrace Kloba
395725ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima        UrlData(String url) {
395825ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima            this.mUrl = url;
3959068e48b469f5abca53ee3da38f933cf2c25c93b8Grace Kloba            this.mHeaders = null;
396058d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins            this.mVoiceIntent = null;
396125ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima        }
396260e095c190496d42327f8ec2ef990c044d15a76fGrace Kloba
396358d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        UrlData(String url, Map<String, String> headers, Intent intent) {
3964068e48b469f5abca53ee3da38f933cf2c25c93b8Grace Kloba            this.mUrl = url;
3965068e48b469f5abca53ee3da38f933cf2c25c93b8Grace Kloba            this.mHeaders = headers;
3966a1cc3fdce19a336c251297c61cd83ac6cf767cd1Leon Scroggins            if (RecognizerResultsIntent.ACTION_VOICE_SEARCH_RESULTS
3967a1cc3fdce19a336c251297c61cd83ac6cf767cd1Leon Scroggins                    .equals(intent.getAction())) {
396858d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins                this.mVoiceIntent = intent;
396958d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins            } else {
397058d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins                this.mVoiceIntent = null;
397158d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins            }
397260e095c190496d42327f8ec2ef990c044d15a76fGrace Kloba        }
397360e095c190496d42327f8ec2ef990c044d15a76fGrace Kloba
397425ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima        boolean isEmpty() {
397558d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins            return mVoiceIntent == null && (mUrl == null || mUrl.length() == 0);
397625ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima        }
397725ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima
397858d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        public void loadIn(Tab t) {
397958d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins            if (mVoiceIntent != null) {
398058d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins                t.activateVoiceSearchMode(mVoiceIntent);
398158d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins            } else {
398258d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins                t.getWebView().loadUrl(mUrl, mHeaders);
398358d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins            }
398425ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima        }
398525ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima    };
398625ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima
39871f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins    /* package */ static final UrlData EMPTY_URL_DATA = new UrlData(null);
39880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project}
3989