BrowserActivity.java revision 2d508edbf54ea74cd4e89be8b622b1cbd587464a
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;
260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.content.ContentResolver;
27b6b7f9ef3b4ed220063f555d8b7c205210a61a04Leon Scrogginsimport android.content.ContentUris;
280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.content.ContentValues;
290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.content.Context;
300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.content.DialogInterface;
310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.content.Intent;
320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.content.IntentFilter;
33b4da0ad0351996f639b50f9f29b123a9b5c24fd0Grace Klobaimport android.content.pm.PackageInfo;
340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.content.pm.PackageManager;
350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.content.pm.ResolveInfo;
360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.content.res.Configuration;
370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.content.res.Resources;
380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.database.Cursor;
3996afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scrogginsimport android.database.DatabaseUtils;
400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.graphics.Bitmap;
41540035dfd1347c78eeec10ec0847e18fcc50ef36Andrei Popescuimport android.graphics.BitmapFactory;
420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.graphics.Canvas;
430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.graphics.Picture;
443bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scrogginsimport android.graphics.PixelFormat;
453bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scrogginsimport android.graphics.Rect;
460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.graphics.drawable.Drawable;
470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.net.ConnectivityManager;
4856199cc25e7ee0455ec2a8099098b66b8554f677Andrei Popescuimport android.net.NetworkInfo;
490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.net.Uri;
500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.net.WebAddress;
510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.net.http.SslCertificate;
520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.net.http.SslError;
530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.os.AsyncTask;
540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.os.Bundle;
550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.os.Debug;
560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.os.Environment;
570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.os.Handler;
580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.os.Message;
590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.os.PowerManager;
600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.os.Process;
610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.os.ServiceManager;
620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.os.SystemClock;
630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.provider.Browser;
645e335a381a0cd66e94117b202c1f34f5cb29c9b8Cary Clarkimport android.provider.ContactsContract;
655e335a381a0cd66e94117b202c1f34f5cb29c9b8Cary Clarkimport android.provider.ContactsContract.Intents.Insert;
660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.provider.Downloads;
670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.provider.MediaStore;
680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.text.IClipboard;
690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.text.TextUtils;
700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.text.format.DateFormat;
71b94bf27370329abb27e5e33b493d6edb5662b36eLeon Scrogginsimport android.util.AttributeSet;
720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.util.Log;
730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.view.ContextMenu;
740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.view.Gravity;
750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.view.KeyEvent;
760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.view.LayoutInflater;
770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.view.Menu;
780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.view.MenuInflater;
790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.view.MenuItem;
800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.view.View;
810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.view.ViewGroup;
820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.view.Window;
830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.view.WindowManager;
840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.view.ContextMenu.ContextMenuInfo;
850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.view.MenuItem.OnMenuItemClickListener;
860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.webkit.CookieManager;
870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.webkit.CookieSyncManager;
880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.webkit.DownloadListener;
890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.webkit.HttpAuthHandler;
90b4da0ad0351996f639b50f9f29b123a9b5c24fd0Grace Klobaimport android.webkit.PluginManager;
910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.webkit.SslErrorHandler;
920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.webkit.URLUtil;
93cb6cc864e53f7d916622daf3b2cec133b36d6a55Leon Clarkeimport android.webkit.ValueCallback;
940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.webkit.WebChromeClient;
950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.webkit.WebHistoryItem;
960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.webkit.WebIconDatabase;
970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.webkit.WebView;
980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.widget.EditText;
990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.widget.FrameLayout;
1000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.widget.LinearLayout;
1010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.widget.TextView;
1020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.widget.Toast;
103752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintanaimport android.accounts.Account;
104752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintanaimport android.accounts.AccountManager;
105752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintanaimport android.accounts.AccountManagerFuture;
106752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintanaimport android.accounts.AuthenticatorException;
107752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintanaimport android.accounts.OperationCanceledException;
108752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintanaimport android.accounts.AccountManagerCallback;
1090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
1105ee906c089567bca705e18561357510d7b55cb5aDan Egnorimport com.android.common.Patterns;
1115ee906c089567bca705e18561357510d7b55cb5aDan Egnor
112716d4f542daec3588f45cbc5cb3acc825233b8a1Doug Zongkerimport com.google.android.gsf.GoogleLoginServiceConstants;
1135ee906c089567bca705e18561357510d7b55cb5aDan Egnor
114b6b7f9ef3b4ed220063f555d8b7c205210a61a04Leon Scrogginsimport java.io.ByteArrayOutputStream;
1150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport java.io.File;
1164f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdochimport java.io.IOException;
1174f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdochimport java.io.InputStream;
1180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport java.net.MalformedURLException;
1190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport java.net.URI;
1209918943559193e3e047a1c18442e2cdb0fe22b15Dianne Hackbornimport java.net.URISyntaxException;
1210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport java.net.URL;
1220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport java.net.URLEncoder;
1230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport java.text.ParseException;
1240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport java.util.Date;
1250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport java.util.HashMap;
12600f54c589fd38431efd42ea2a551a49e64d595d5Grace Klobaimport java.util.Iterator;
127068e48b469f5abca53ee3da38f933cf2c25c93b8Grace Klobaimport java.util.Map;
1280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport java.util.regex.Matcher;
1290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport java.util.regex.Pattern;
1300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
1310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectpublic class BrowserActivity extends Activity
132752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana    implements View.OnCreateContextMenuListener, DownloadListener,
133752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana        AccountManagerCallback<Account[]> {
1340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
13531a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort    /* Define some aliases to make these debugging flags easier to refer to.
13631a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort     * This file imports android.provider.Browser, so we can't just refer to "Browser.DEBUG".
13731a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort     */
13831a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort    private final static boolean DEBUG = com.android.browser.Browser.DEBUG;
13931a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort    private final static boolean LOGV_ENABLED = com.android.browser.Browser.LOGV_ENABLED;
14031a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort    private final static boolean LOGD_ENABLED = com.android.browser.Browser.LOGD_ENABLED;
14131a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort
142565505b1a2c1d3099496af5910760087602e994aSatish Sampath    // These are single-character shortcuts for searching popular sources.
143565505b1a2c1d3099496af5910760087602e994aSatish Sampath    private static final int SHORTCUT_INVALID = 0;
144565505b1a2c1d3099496af5910760087602e994aSatish Sampath    private static final int SHORTCUT_GOOGLE_SEARCH = 1;
145565505b1a2c1d3099496af5910760087602e994aSatish Sampath    private static final int SHORTCUT_WIKIPEDIA_SEARCH = 2;
146565505b1a2c1d3099496af5910760087602e994aSatish Sampath    private static final int SHORTCUT_DICTIONARY_SEARCH = 3;
147565505b1a2c1d3099496af5910760087602e994aSatish Sampath    private static final int SHORTCUT_GOOGLE_MOBILE_LOCAL_SEARCH = 4;
148565505b1a2c1d3099496af5910760087602e994aSatish Sampath
149752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana    private Account[] mAccountsGoogle;
150752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana    private Account[] mAccountsPreferHosted;
1510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
152752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana    private void startReadOfGoogleAccounts() {
153752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana        mAccountsGoogle = null;
154752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana        mAccountsPreferHosted = null;
1550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
156752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana        AccountManager.get(this).getAccountsByTypeAndFeatures(
157752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana                GoogleLoginServiceConstants.ACCOUNT_TYPE,
158752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana                new String[]{GoogleLoginServiceConstants.FEATURE_LEGACY_HOSTED_OR_GOOGLE},
159752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana                this, null);
160752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana    }
161752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana
162752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana    /** This implements AccountManagerCallback<Account[]> */
163752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana    public void run(AccountManagerFuture<Account[]> accountManagerFuture) {
164752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana        try {
165752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana            if (mAccountsGoogle == null) {
166752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana                mAccountsGoogle = accountManagerFuture.getResult();
167752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana
168752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana                AccountManager.get(this).getAccountsByTypeAndFeatures(
169752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana                        GoogleLoginServiceConstants.ACCOUNT_TYPE,
170752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana                        new String[]{GoogleLoginServiceConstants.FEATURE_LEGACY_GOOGLE},
171752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana                        this, null);
172752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana            } else {
173752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana                mAccountsPreferHosted = accountManagerFuture.getResult();
174752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana                setupHomePage();
1750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
176752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana        } catch (OperationCanceledException e) {
177752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana            setupHomePage();
178752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana        } catch (IOException e) {
179752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana            setupHomePage();
180752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana        } catch (AuthenticatorException e) {
181752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana            setupHomePage();
182752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana        }
183752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana    }
184752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana
185752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana    private void setupHomePage() {
186752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana        // get the default home page
187752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana        String homepage = mSettings.getHomePage();
188752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana
189752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana        if (mAccountsPreferHosted != null && mAccountsGoogle != null) {
190752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana            // three cases:
191752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana            //
192752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana            //   hostedUser == googleUser
193752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana            //      The device has only a google account
194752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana            //
195752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana            //   hostedUser != googleUser
196752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana            //      The device has a hosted account and a google account
197752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana            //
198752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana            //   hostedUser != null, googleUser == null
199752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana            //      The device has only a hosted account (so far)
200752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana            String hostedUser = mAccountsPreferHosted.length == 0
201752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana                    ? null
202752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana                    : mAccountsPreferHosted[0].name;
203752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana            String googleUser = mAccountsGoogle.length == 0 ? null : mAccountsGoogle[0].name;
204752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana
205752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana            // developers might have no accounts at all
206752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana            if (hostedUser == null) return;
207752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana
208752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana            if (googleUser == null || !hostedUser.equals(googleUser)) {
209752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana                String domain = hostedUser.substring(hostedUser.lastIndexOf('@')+1);
210752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana                homepage = homepage.replace("?", "/a/" + domain + "?");
2110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
212752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana        }
2130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
214752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana        mSettings.setHomePage(BrowserActivity.this, homepage);
215752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana        resumeAfterCredentials();
2160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
2170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
218a977124eb29b195127fd161120ebbc58b255fb48Cary Clark    private static class ClearThumbnails extends AsyncTask<File, Void, Void> {
2190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        @Override
2200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public Void doInBackground(File... files) {
2210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (files != null) {
2220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                for (File f : files) {
223d6be1758b38d5b066ff10b6af906aa66c63670cdCary Clark                    if (!f.delete()) {
224d6be1758b38d5b066ff10b6af906aa66c63670cdCary Clark                      Log.e(LOGTAG, f.getPath() + " was not deleted");
225d6be1758b38d5b066ff10b6af906aa66c63670cdCary Clark                    }
2260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
2270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
2280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return null;
2290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
2300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
2310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
2323bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    /**
2333bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     * This layout holds everything you see below the status bar, including the
2343bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     * error console, the custom view container, and the webviews.
2353bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     */
2363bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    private FrameLayout mBrowserFrameLayout;
23781db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins
23822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    @Override
23922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    public void onCreate(Bundle icicle) {
24031a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort        if (LOGV_ENABLED) {
2410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Log.v(LOGTAG, this + " onStart");
2420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
2430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        super.onCreate(icicle);
2440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // test the browser in OpenGL
2450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // requestWindowFeature(Window.FEATURE_OPENGL);
2460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
247d334bf564b72416e77e707d25f8c55cfe1d85709Mike Reed        // enable this to test the browser in 32bit
248d334bf564b72416e77e707d25f8c55cfe1d85709Mike Reed        if (false) {
249d334bf564b72416e77e707d25f8c55cfe1d85709Mike Reed            getWindow().setFormat(PixelFormat.RGBX_8888);
250d334bf564b72416e77e707d25f8c55cfe1d85709Mike Reed            BitmapFactory.setDefaultConfig(Bitmap.Config.ARGB_8888);
251d334bf564b72416e77e707d25f8c55cfe1d85709Mike Reed        }
252d334bf564b72416e77e707d25f8c55cfe1d85709Mike Reed
2530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        setDefaultKeyMode(DEFAULT_KEYS_SEARCH_LOCAL);
2540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
2550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mResolver = getContentResolver();
2560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
2570923d69a8ca45222cabd82a80eaa88da9f132e9aGrace Kloba        // If this was a web search request, pass it on to the default web
2580923d69a8ca45222cabd82a80eaa88da9f132e9aGrace Kloba        // search provider and finish this activity.
2590923d69a8ca45222cabd82a80eaa88da9f132e9aGrace Kloba        if (handleWebSearchIntent(getIntent())) {
2600923d69a8ca45222cabd82a80eaa88da9f132e9aGrace Kloba            finish();
2610923d69a8ca45222cabd82a80eaa88da9f132e9aGrace Kloba            return;
2620923d69a8ca45222cabd82a80eaa88da9f132e9aGrace Kloba        }
2630923d69a8ca45222cabd82a80eaa88da9f132e9aGrace Kloba
2640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mSecLockIcon = Resources.getSystem().getDrawable(
2650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                android.R.drawable.ic_secure);
2660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mMixLockIcon = Resources.getSystem().getDrawable(
2670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                android.R.drawable.ic_partial_secure);
2680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
26981db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins        FrameLayout frameLayout = (FrameLayout) getWindow().getDecorView()
27081db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins                .findViewById(com.android.internal.R.id.content);
2713bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins        mBrowserFrameLayout = (FrameLayout) LayoutInflater.from(this)
2723bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                .inflate(R.layout.custom_screen, null);
2733bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins        mContentView = (FrameLayout) mBrowserFrameLayout.findViewById(
2743bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                R.id.main_content);
2753bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins        mErrorConsoleContainer = (LinearLayout) mBrowserFrameLayout
2763bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                .findViewById(R.id.error_console);
2773bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins        mCustomViewContainer = (FrameLayout) mBrowserFrameLayout
2783bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                .findViewById(R.id.fullscreen_custom_content);
2793bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins        frameLayout.addView(mBrowserFrameLayout, COVER_SCREEN_PARAMS);
28068579393973f745fc65a2781061af9bb8f2d7020Leon Scroggins        mTitleBar = new TitleBar(this);
281fe87bd3a3897e4bad65bb3d284659ae2f4e57570Leon Scroggins        mFakeTitleBar = new TitleBar(this);
2820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
2830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Create the tab control and our initial tab
2840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mTabControl = new TabControl(this);
2850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
2860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Open the icon database and retain all the bookmark urls for favicons
2870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        retainIconsOnStartup();
2880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
2890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Keep a settings instance handy.
2900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mSettings = BrowserSettings.getInstance();
2910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mSettings.setTabControl(mTabControl);
2920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mSettings.loadFromDb(this);
2930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
2940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
2950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "Browser");
2960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
297a34f686112fb4f9fbea00b8c2c47153d34e93e41Grace Kloba        /* enables registration for changes in network status from
298a34f686112fb4f9fbea00b8c2c47153d34e93e41Grace Kloba           http stack */
299a34f686112fb4f9fbea00b8c2c47153d34e93e41Grace Kloba        mNetworkStateChangedFilter = new IntentFilter();
300a34f686112fb4f9fbea00b8c2c47153d34e93e41Grace Kloba        mNetworkStateChangedFilter.addAction(
301a34f686112fb4f9fbea00b8c2c47153d34e93e41Grace Kloba                ConnectivityManager.CONNECTIVITY_ACTION);
302a34f686112fb4f9fbea00b8c2c47153d34e93e41Grace Kloba        mNetworkStateIntentReceiver = new BroadcastReceiver() {
303a34f686112fb4f9fbea00b8c2c47153d34e93e41Grace Kloba                @Override
304a34f686112fb4f9fbea00b8c2c47153d34e93e41Grace Kloba                public void onReceive(Context context, Intent intent) {
305a34f686112fb4f9fbea00b8c2c47153d34e93e41Grace Kloba                    if (intent.getAction().equals(
306a34f686112fb4f9fbea00b8c2c47153d34e93e41Grace Kloba                            ConnectivityManager.CONNECTIVITY_ACTION)) {
3077d899d6f5364a5b20716497a3be5e2f778a2bc0eRobert Greenwalt                        boolean noConnectivity = intent.getBooleanExtra(
3087d899d6f5364a5b20716497a3be5e2f778a2bc0eRobert Greenwalt                                ConnectivityManager.EXTRA_NO_CONNECTIVITY, false);
30956199cc25e7ee0455ec2a8099098b66b8554f677Andrei Popescu                        if (!noConnectivity) {
31056199cc25e7ee0455ec2a8099098b66b8554f677Andrei Popescu                            NetworkInfo info = intent.getParcelableExtra(
31156199cc25e7ee0455ec2a8099098b66b8554f677Andrei Popescu                                    ConnectivityManager.EXTRA_NETWORK_INFO);
31256199cc25e7ee0455ec2a8099098b66b8554f677Andrei Popescu                            String typeName = info.getTypeName();
31356199cc25e7ee0455ec2a8099098b66b8554f677Andrei Popescu                            String subtypeName = info.getSubtypeName();
31456199cc25e7ee0455ec2a8099098b66b8554f677Andrei Popescu                            sendNetworkType(typeName.toLowerCase(),
31556199cc25e7ee0455ec2a8099098b66b8554f677Andrei Popescu                                    (subtypeName != null ? subtypeName.toLowerCase() : ""));
31656199cc25e7ee0455ec2a8099098b66b8554f677Andrei Popescu                        }
3177d899d6f5364a5b20716497a3be5e2f778a2bc0eRobert Greenwalt                        onNetworkToggle(!noConnectivity);
318a34f686112fb4f9fbea00b8c2c47153d34e93e41Grace Kloba                    }
319a34f686112fb4f9fbea00b8c2c47153d34e93e41Grace Kloba                }
320a34f686112fb4f9fbea00b8c2c47153d34e93e41Grace Kloba            };
321a34f686112fb4f9fbea00b8c2c47153d34e93e41Grace Kloba
322615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba        IntentFilter filter = new IntentFilter(Intent.ACTION_PACKAGE_ADDED);
323615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba        filter.addAction(Intent.ACTION_PACKAGE_REMOVED);
324615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba        filter.addDataScheme("package");
325615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba        mPackageInstallationReceiver = new BroadcastReceiver() {
326615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba            @Override
327615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba            public void onReceive(Context context, Intent intent) {
328615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                final String action = intent.getAction();
329615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                final String packageName = intent.getData()
330615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                        .getSchemeSpecificPart();
331615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                final boolean replacing = intent.getBooleanExtra(
332615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                        Intent.EXTRA_REPLACING, false);
333615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                if (Intent.ACTION_PACKAGE_REMOVED.equals(action) && replacing) {
334615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                    // if it is replacing, refreshPlugins() when adding
335615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                    return;
336615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                }
337615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                PackageManager pm = BrowserActivity.this.getPackageManager();
338615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                PackageInfo pkgInfo = null;
339615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                try {
340615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                    pkgInfo = pm.getPackageInfo(packageName,
341615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                            PackageManager.GET_PERMISSIONS);
342615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                } catch (PackageManager.NameNotFoundException e) {
343615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                    return;
344615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                }
345615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                if (pkgInfo != null) {
346615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                    String permissions[] = pkgInfo.requestedPermissions;
347615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                    if (permissions == null) {
348615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                        return;
349615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                    }
350615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                    boolean permissionOk = false;
351615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                    for (String permit : permissions) {
352615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                        if (PluginManager.PLUGIN_PERMISSION.equals(permit)) {
353615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                            permissionOk = true;
354615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                            break;
355615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                        }
356615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                    }
357615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                    if (permissionOk) {
358615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                        PluginManager.getInstance(BrowserActivity.this)
359615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                                .refreshPlugins(
360615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                                        Intent.ACTION_PACKAGE_ADDED
361615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                                                .equals(action));
362615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                    }
363615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                }
364615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba            }
365615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba        };
366615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba        registerReceiver(mPackageInstallationReceiver, filter);
367615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba
3680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (!mTabControl.restoreState(icicle)) {
3690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // clear up the thumbnail directory if we can't restore the state as
3700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // none of the files in the directory are referenced any more.
3710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            new ClearThumbnails().execute(
3720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    mTabControl.getThumbnailDir().listFiles());
373aab3f09b5c2d39b19067e57635614080b2403a46Grace Kloba            // there is no quit on Android. But if we can't restore the state,
374aab3f09b5c2d39b19067e57635614080b2403a46Grace Kloba            // we can treat it as a new Browser, remove the old session cookies.
375aab3f09b5c2d39b19067e57635614080b2403a46Grace Kloba            CookieManager.getInstance().removeSessionCookie();
3760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            final Intent intent = getIntent();
3770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            final Bundle extra = intent.getExtras();
3780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Create an initial tab.
3790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // If the intent is ACTION_VIEW and data is not null, the Browser is
3800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // invoked to view the content by another application. In this case,
3810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // the tab will be close when exit.
38225ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima            UrlData urlData = getUrlDataFromIntent(intent);
38325ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima
38422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            final Tab t = mTabControl.createNewTab(
3850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    Intent.ACTION_VIEW.equals(intent.getAction()) &&
386f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    intent.getData() != null,
38725ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima                    intent.getStringExtra(Browser.EXTRA_APPLICATION_ID), urlData.mUrl);
3880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mTabControl.setCurrentTab(t);
3890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            attachTabToContentView(t);
3900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            WebView webView = t.getWebView();
3910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (extra != null) {
3920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                int scale = extra.getInt(Browser.INITIAL_ZOOM_LEVEL, 0);
3930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (scale > 0 && scale <= 1000) {
3940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    webView.setInitialScale(scale);
3950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
3960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
3970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // If we are not restoring from an icicle, then there is a high
3980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // likely hood this is the first run. So, check to see if the
3990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // homepage needs to be configured and copy any plugins from our
4000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // asset directory to the data partition.
4010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if ((extra == null || !extra.getBoolean("testing"))
4020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    && !mSettings.isLoginInitialized()) {
403752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana                startReadOfGoogleAccounts();
4040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
4050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
40625ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima            if (urlData.isEmpty()) {
407304442375719effd41dbd53ae62de7a8d0cec7d9Leon Scroggins                if (mSettings.isLoginInitialized()) {
408304442375719effd41dbd53ae62de7a8d0cec7d9Leon Scroggins                    webView.loadUrl(mSettings.getHomePage());
409304442375719effd41dbd53ae62de7a8d0cec7d9Leon Scroggins                } else {
410304442375719effd41dbd53ae62de7a8d0cec7d9Leon Scroggins                    waitForCredentials();
411304442375719effd41dbd53ae62de7a8d0cec7d9Leon Scroggins                }
4120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } else {
41325ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima                urlData.loadIn(webView);
4140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
4150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
4160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // TabControl.restoreState() will create a new tab even if
4171f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins            // restoring the state fails.
4180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            attachTabToContentView(mTabControl.getCurrentTab());
4190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
420615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba
421b3c02da4553b1a629b16377970fdabae28394c94Feng Qian        // Read JavaScript flags if it exists.
422b3c02da4553b1a629b16377970fdabae28394c94Feng Qian        String jsFlags = mSettings.getJsFlags();
423b3c02da4553b1a629b16377970fdabae28394c94Feng Qian        if (jsFlags.trim().length() != 0) {
424b3c02da4553b1a629b16377970fdabae28394c94Feng Qian            mTabControl.getCurrentWebView().setJsFlags(jsFlags);
425b3c02da4553b1a629b16377970fdabae28394c94Feng Qian        }
4260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
4270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
4280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    @Override
4290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    protected void onNewIntent(Intent intent) {
43022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        Tab current = mTabControl.getCurrentTab();
4310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // When a tab is closed on exit, the current tab index is set to -1.
4320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Reset before proceed as Browser requires the current tab to be set.
4330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (current == null) {
4340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Try to reset the tab in case the index was incorrect.
4350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            current = mTabControl.getTab(0);
4360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (current == null) {
4370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // No tabs at all so just ignore this intent.
4380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                return;
4390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
4400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mTabControl.setCurrentTab(current);
4410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            attachTabToContentView(current);
4420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            resetTitleAndIcon(current.getWebView());
4430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
4440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final String action = intent.getAction();
4450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final int flags = intent.getFlags();
4460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (Intent.ACTION_MAIN.equals(action) ||
4470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                (flags & Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY) != 0) {
4480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // just resume the browser
4490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
4500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
4510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (Intent.ACTION_VIEW.equals(action)
4520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                || Intent.ACTION_SEARCH.equals(action)
4530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                || MediaStore.INTENT_ACTION_MEDIA_SEARCH.equals(action)
4540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                || Intent.ACTION_WEB_SEARCH.equals(action)) {
455565505b1a2c1d3099496af5910760087602e994aSatish Sampath            // If this was a search request (e.g. search query directly typed into the address bar),
456565505b1a2c1d3099496af5910760087602e994aSatish Sampath            // pass it on to the default web search provider.
457565505b1a2c1d3099496af5910760087602e994aSatish Sampath            if (handleWebSearchIntent(intent)) {
458565505b1a2c1d3099496af5910760087602e994aSatish Sampath                return;
459565505b1a2c1d3099496af5910760087602e994aSatish Sampath            }
460565505b1a2c1d3099496af5910760087602e994aSatish Sampath
46125ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima            UrlData urlData = getUrlDataFromIntent(intent);
46225ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima            if (urlData.isEmpty()) {
46325ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima                urlData = new UrlData(mSettings.getHomePage());
4640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
46525ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima
466cc63403643786905262f505ab5266d8e80b9924cGrace Kloba            final String appId = intent
467cc63403643786905262f505ab5266d8e80b9924cGrace Kloba                    .getStringExtra(Browser.EXTRA_APPLICATION_ID);
468cc63403643786905262f505ab5266d8e80b9924cGrace Kloba            if (Intent.ACTION_VIEW.equals(action)
469cc63403643786905262f505ab5266d8e80b9924cGrace Kloba                    && !getPackageName().equals(appId)
470cc63403643786905262f505ab5266d8e80b9924cGrace Kloba                    && (flags & Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT) != 0) {
47122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                Tab appTab = mTabControl.getTabFromId(appId);
472f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                if (appTab != null) {
473f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    Log.i(LOGTAG, "Reusing tab for " + appId);
474f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    // Dismiss the subwindow if applicable.
475f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    dismissSubWindow(appTab);
476f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    // Since we might kill the WebView, remove it from the
477f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    // content view first.
478f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    removeTabFromContentView(appTab);
479f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    // Recreate the main WebView after destroying the old one.
480f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    // If the WebView has the same original url and is on that
481f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    // page, it can be reused.
482f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    boolean needsLoad =
48325ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima                            mTabControl.recreateWebView(appTab, urlData.mUrl);
484bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch
485f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    if (current != appTab) {
4861f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                        switchToTab(mTabControl.getTabIndex(appTab));
4871f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                        if (needsLoad) {
4881f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                            urlData.loadIn(appTab.getWebView());
4891f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                        }
490f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    } else {
4911f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                        // If the tab was the current tab, we have to attach
4921f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                        // it to the view system again.
4931f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                        attachTabToContentView(appTab);
4941f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                        if (needsLoad) {
4951f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                            urlData.loadIn(appTab.getWebView());
496f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                        }
497f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    }
498f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    return;
499cd11589fc3930906d4b9b7dd18aa52a9f1eb0c8aPatrick Scott                } else {
500cd11589fc3930906d4b9b7dd18aa52a9f1eb0c8aPatrick Scott                    // No matching application tab, try to find a regular tab
501cd11589fc3930906d4b9b7dd18aa52a9f1eb0c8aPatrick Scott                    // with a matching url.
502cd11589fc3930906d4b9b7dd18aa52a9f1eb0c8aPatrick Scott                    appTab = mTabControl.findUnusedTabWithUrl(urlData.mUrl);
50325515f8bd458a2471d13d876cfb0e18d8ff2a00fLeon Scroggins                    if (appTab != null) {
50425515f8bd458a2471d13d876cfb0e18d8ff2a00fLeon Scroggins                        if (current != appTab) {
50525515f8bd458a2471d13d876cfb0e18d8ff2a00fLeon Scroggins                            switchToTab(mTabControl.getTabIndex(appTab));
50625515f8bd458a2471d13d876cfb0e18d8ff2a00fLeon Scroggins                        }
50725515f8bd458a2471d13d876cfb0e18d8ff2a00fLeon Scroggins                        // Otherwise, we are already viewing the correct tab.
508cd11589fc3930906d4b9b7dd18aa52a9f1eb0c8aPatrick Scott                    } else {
509cd11589fc3930906d4b9b7dd18aa52a9f1eb0c8aPatrick Scott                        // if FLAG_ACTIVITY_BROUGHT_TO_FRONT flag is on, the url
510cd11589fc3930906d4b9b7dd18aa52a9f1eb0c8aPatrick Scott                        // will be opened in a new tab unless we have reached
511cd11589fc3930906d4b9b7dd18aa52a9f1eb0c8aPatrick Scott                        // MAX_TABS. Then the url will be opened in the current
512cd11589fc3930906d4b9b7dd18aa52a9f1eb0c8aPatrick Scott                        // tab. If a new tab is created, it will have "true" for
513cd11589fc3930906d4b9b7dd18aa52a9f1eb0c8aPatrick Scott                        // exit on close.
5141f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                        openTabAndShow(urlData, true, appId);
515cd11589fc3930906d4b9b7dd18aa52a9f1eb0c8aPatrick Scott                    }
516f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                }
5170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } else {
518638d3f45791a31d0b290e180b93bad49576eb6d3Grace Kloba                if (!urlData.isEmpty()
519638d3f45791a31d0b290e180b93bad49576eb6d3Grace Kloba                        && urlData.mUrl.startsWith("about:debug")) {
520638d3f45791a31d0b290e180b93bad49576eb6d3Grace Kloba                    if ("about:debug.dom".equals(urlData.mUrl)) {
521638d3f45791a31d0b290e180b93bad49576eb6d3Grace Kloba                        current.getWebView().dumpDomTree(false);
522638d3f45791a31d0b290e180b93bad49576eb6d3Grace Kloba                    } else if ("about:debug.dom.file".equals(urlData.mUrl)) {
523638d3f45791a31d0b290e180b93bad49576eb6d3Grace Kloba                        current.getWebView().dumpDomTree(true);
524638d3f45791a31d0b290e180b93bad49576eb6d3Grace Kloba                    } else if ("about:debug.render".equals(urlData.mUrl)) {
525638d3f45791a31d0b290e180b93bad49576eb6d3Grace Kloba                        current.getWebView().dumpRenderTree(false);
526638d3f45791a31d0b290e180b93bad49576eb6d3Grace Kloba                    } else if ("about:debug.render.file".equals(urlData.mUrl)) {
527638d3f45791a31d0b290e180b93bad49576eb6d3Grace Kloba                        current.getWebView().dumpRenderTree(true);
528638d3f45791a31d0b290e180b93bad49576eb6d3Grace Kloba                    } else if ("about:debug.display".equals(urlData.mUrl)) {
529638d3f45791a31d0b290e180b93bad49576eb6d3Grace Kloba                        current.getWebView().dumpDisplayTree();
5309b78e1d1e0bd819ae03df5594d4a56519e5d87c7Mike Reed                    } else if (urlData.mUrl.startsWith("about:debug.drag")) {
5319b78e1d1e0bd819ae03df5594d4a56519e5d87c7Mike Reed                        int index = urlData.mUrl.codePointAt(16) - '0';
5329b78e1d1e0bd819ae03df5594d4a56519e5d87c7Mike Reed                        if (index <= 0 || index > 9) {
5339b78e1d1e0bd819ae03df5594d4a56519e5d87c7Mike Reed                            current.getWebView().setDragTracker(null);
5349b78e1d1e0bd819ae03df5594d4a56519e5d87c7Mike Reed                        } else {
5359b78e1d1e0bd819ae03df5594d4a56519e5d87c7Mike Reed                            current.getWebView().setDragTracker(new MeshTracker(index));
5369b78e1d1e0bd819ae03df5594d4a56519e5d87c7Mike Reed                        }
537638d3f45791a31d0b290e180b93bad49576eb6d3Grace Kloba                    } else {
538638d3f45791a31d0b290e180b93bad49576eb6d3Grace Kloba                        mSettings.toggleDebugSettings();
539638d3f45791a31d0b290e180b93bad49576eb6d3Grace Kloba                    }
5400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    return;
5410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
5421f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                // Get rid of the subwindow if it exists
5431f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                dismissSubWindow(current);
5441f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                urlData.loadIn(current.getWebView());
5450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
5460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
5470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
5480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
549565505b1a2c1d3099496af5910760087602e994aSatish Sampath    private int parseUrlShortcut(String url) {
550565505b1a2c1d3099496af5910760087602e994aSatish Sampath        if (url == null) return SHORTCUT_INVALID;
551565505b1a2c1d3099496af5910760087602e994aSatish Sampath
552565505b1a2c1d3099496af5910760087602e994aSatish Sampath        // FIXME: quick search, need to be customized by setting
553565505b1a2c1d3099496af5910760087602e994aSatish Sampath        if (url.length() > 2 && url.charAt(1) == ' ') {
554565505b1a2c1d3099496af5910760087602e994aSatish Sampath            switch (url.charAt(0)) {
555565505b1a2c1d3099496af5910760087602e994aSatish Sampath            case 'g': return SHORTCUT_GOOGLE_SEARCH;
556565505b1a2c1d3099496af5910760087602e994aSatish Sampath            case 'w': return SHORTCUT_WIKIPEDIA_SEARCH;
557565505b1a2c1d3099496af5910760087602e994aSatish Sampath            case 'd': return SHORTCUT_DICTIONARY_SEARCH;
558565505b1a2c1d3099496af5910760087602e994aSatish Sampath            case 'l': return SHORTCUT_GOOGLE_MOBILE_LOCAL_SEARCH;
559565505b1a2c1d3099496af5910760087602e994aSatish Sampath            }
560565505b1a2c1d3099496af5910760087602e994aSatish Sampath        }
561565505b1a2c1d3099496af5910760087602e994aSatish Sampath        return SHORTCUT_INVALID;
562565505b1a2c1d3099496af5910760087602e994aSatish Sampath    }
563565505b1a2c1d3099496af5910760087602e994aSatish Sampath
564565505b1a2c1d3099496af5910760087602e994aSatish Sampath    /**
565565505b1a2c1d3099496af5910760087602e994aSatish Sampath     * Launches the default web search activity with the query parameters if the given intent's data
566565505b1a2c1d3099496af5910760087602e994aSatish Sampath     * are identified as plain search terms and not URLs/shortcuts.
567565505b1a2c1d3099496af5910760087602e994aSatish Sampath     * @return true if the intent was handled and web search activity was launched, false if not.
568565505b1a2c1d3099496af5910760087602e994aSatish Sampath     */
569565505b1a2c1d3099496af5910760087602e994aSatish Sampath    private boolean handleWebSearchIntent(Intent intent) {
570565505b1a2c1d3099496af5910760087602e994aSatish Sampath        if (intent == null) return false;
571565505b1a2c1d3099496af5910760087602e994aSatish Sampath
572565505b1a2c1d3099496af5910760087602e994aSatish Sampath        String url = null;
573565505b1a2c1d3099496af5910760087602e994aSatish Sampath        final String action = intent.getAction();
574565505b1a2c1d3099496af5910760087602e994aSatish Sampath        if (Intent.ACTION_VIEW.equals(action)) {
5751e70505659dd9bf0f7e03bce787ba880f9b7a8aaGrace Kloba            Uri data = intent.getData();
5761e70505659dd9bf0f7e03bce787ba880f9b7a8aaGrace Kloba            if (data != null) url = data.toString();
577565505b1a2c1d3099496af5910760087602e994aSatish Sampath        } else if (Intent.ACTION_SEARCH.equals(action)
578565505b1a2c1d3099496af5910760087602e994aSatish Sampath                || MediaStore.INTENT_ACTION_MEDIA_SEARCH.equals(action)
579565505b1a2c1d3099496af5910760087602e994aSatish Sampath                || Intent.ACTION_WEB_SEARCH.equals(action)) {
580565505b1a2c1d3099496af5910760087602e994aSatish Sampath            url = intent.getStringExtra(SearchManager.QUERY);
581565505b1a2c1d3099496af5910760087602e994aSatish Sampath        }
5820485170e03e079eb61b9dd52fc2c98da02fa7b2cBjorn Bringert        return handleWebSearchRequest(url, intent.getBundleExtra(SearchManager.APP_DATA),
5830485170e03e079eb61b9dd52fc2c98da02fa7b2cBjorn Bringert                intent.getStringExtra(SearchManager.EXTRA_DATA_KEY));
584565505b1a2c1d3099496af5910760087602e994aSatish Sampath    }
585565505b1a2c1d3099496af5910760087602e994aSatish Sampath
586565505b1a2c1d3099496af5910760087602e994aSatish Sampath    /**
587565505b1a2c1d3099496af5910760087602e994aSatish Sampath     * Launches the default web search activity with the query parameters if the given url string
588565505b1a2c1d3099496af5910760087602e994aSatish Sampath     * was identified as plain search terms and not URL/shortcut.
589565505b1a2c1d3099496af5910760087602e994aSatish Sampath     * @return true if the request was handled and web search activity was launched, false if not.
590565505b1a2c1d3099496af5910760087602e994aSatish Sampath     */
5910485170e03e079eb61b9dd52fc2c98da02fa7b2cBjorn Bringert    private boolean handleWebSearchRequest(String inUrl, Bundle appData, String extraData) {
592565505b1a2c1d3099496af5910760087602e994aSatish Sampath        if (inUrl == null) return false;
593565505b1a2c1d3099496af5910760087602e994aSatish Sampath
594565505b1a2c1d3099496af5910760087602e994aSatish Sampath        // In general, we shouldn't modify URL from Intent.
595565505b1a2c1d3099496af5910760087602e994aSatish Sampath        // But currently, we get the user-typed URL from search box as well.
596565505b1a2c1d3099496af5910760087602e994aSatish Sampath        String url = fixUrl(inUrl).trim();
597565505b1a2c1d3099496af5910760087602e994aSatish Sampath
598565505b1a2c1d3099496af5910760087602e994aSatish Sampath        // URLs and site specific search shortcuts are handled by the regular flow of control, so
599565505b1a2c1d3099496af5910760087602e994aSatish Sampath        // return early.
6005ee906c089567bca705e18561357510d7b55cb5aDan Egnor        if (Patterns.WEB_URL.matcher(url).matches()
601bc5b9f358a2b75bf3a104b9f5cd477ad2f6f740fSatish Sampath                || ACCEPTED_URI_SCHEMA.matcher(url).matches()
602565505b1a2c1d3099496af5910760087602e994aSatish Sampath                || parseUrlShortcut(url) != SHORTCUT_INVALID) {
603565505b1a2c1d3099496af5910760087602e994aSatish Sampath            return false;
604565505b1a2c1d3099496af5910760087602e994aSatish Sampath        }
605565505b1a2c1d3099496af5910760087602e994aSatish Sampath
606565505b1a2c1d3099496af5910760087602e994aSatish Sampath        Browser.updateVisitedHistory(mResolver, url, false);
607565505b1a2c1d3099496af5910760087602e994aSatish Sampath        Browser.addSearchUrl(mResolver, url);
608565505b1a2c1d3099496af5910760087602e994aSatish Sampath
609565505b1a2c1d3099496af5910760087602e994aSatish Sampath        Intent intent = new Intent(Intent.ACTION_WEB_SEARCH);
610565505b1a2c1d3099496af5910760087602e994aSatish Sampath        intent.addCategory(Intent.CATEGORY_DEFAULT);
611565505b1a2c1d3099496af5910760087602e994aSatish Sampath        intent.putExtra(SearchManager.QUERY, url);
61215e9f2dc92cf1621f95071b3c740f46079aa0f3bSatish Sampath        if (appData != null) {
61315e9f2dc92cf1621f95071b3c740f46079aa0f3bSatish Sampath            intent.putExtra(SearchManager.APP_DATA, appData);
61415e9f2dc92cf1621f95071b3c740f46079aa0f3bSatish Sampath        }
6150485170e03e079eb61b9dd52fc2c98da02fa7b2cBjorn Bringert        if (extraData != null) {
6160485170e03e079eb61b9dd52fc2c98da02fa7b2cBjorn Bringert            intent.putExtra(SearchManager.EXTRA_DATA_KEY, extraData);
6170485170e03e079eb61b9dd52fc2c98da02fa7b2cBjorn Bringert        }
618cc63403643786905262f505ab5266d8e80b9924cGrace Kloba        intent.putExtra(Browser.EXTRA_APPLICATION_ID, getPackageName());
619565505b1a2c1d3099496af5910760087602e994aSatish Sampath        startActivity(intent);
620565505b1a2c1d3099496af5910760087602e994aSatish Sampath
621565505b1a2c1d3099496af5910760087602e994aSatish Sampath        return true;
622565505b1a2c1d3099496af5910760087602e994aSatish Sampath    }
623565505b1a2c1d3099496af5910760087602e994aSatish Sampath
62425ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima    private UrlData getUrlDataFromIntent(Intent intent) {
6250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String url = null;
626068e48b469f5abca53ee3da38f933cf2c25c93b8Grace Kloba        Map<String, String> headers = null;
6270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (intent != null) {
6280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            final String action = intent.getAction();
6290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (Intent.ACTION_VIEW.equals(action)) {
6300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                url = smartUrlFilter(intent.getData());
6310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (url != null && url.startsWith("content:")) {
6320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    /* Append mimetype so webview knows how to display */
6330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    String mimeType = intent.resolveType(getContentResolver());
6340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    if (mimeType != null) {
6350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        url += "?" + mimeType;
6360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
6370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
638068e48b469f5abca53ee3da38f933cf2c25c93b8Grace Kloba                if (url != null && url.startsWith("http")) {
63900f54c589fd38431efd42ea2a551a49e64d595d5Grace Kloba                    final Bundle pairs = intent
64000f54c589fd38431efd42ea2a551a49e64d595d5Grace Kloba                            .getBundleExtra(Browser.EXTRA_HEADERS);
6412d508edbf54ea74cd4e89be8b622b1cbd587464aGrace Kloba                    if (pairs != null && !pairs.isEmpty()) {
64200f54c589fd38431efd42ea2a551a49e64d595d5Grace Kloba                        Iterator<String> iter = pairs.keySet().iterator();
643068e48b469f5abca53ee3da38f933cf2c25c93b8Grace Kloba                        headers = new HashMap<String, String>();
64400f54c589fd38431efd42ea2a551a49e64d595d5Grace Kloba                        while (iter.hasNext()) {
64500f54c589fd38431efd42ea2a551a49e64d595d5Grace Kloba                            String key = iter.next();
64600f54c589fd38431efd42ea2a551a49e64d595d5Grace Kloba                            headers.put(key, pairs.getString(key));
647068e48b469f5abca53ee3da38f933cf2c25c93b8Grace Kloba                        }
648068e48b469f5abca53ee3da38f933cf2c25c93b8Grace Kloba                    }
64925ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima                }
6500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } else if (Intent.ACTION_SEARCH.equals(action)
6510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    || MediaStore.INTENT_ACTION_MEDIA_SEARCH.equals(action)
6520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    || Intent.ACTION_WEB_SEARCH.equals(action)) {
6530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                url = intent.getStringExtra(SearchManager.QUERY);
6540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (url != null) {
6550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    mLastEnteredUrl = url;
656b446443e47c334bc3aaae98b67c8dca347da3032Leon Scroggins                    Browser.updateVisitedHistory(mResolver, url, false);
6570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // In general, we shouldn't modify URL from Intent.
6580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // But currently, we get the user-typed URL from search box as well.
6590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    url = fixUrl(url);
6600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    url = smartUrlFilter(url);
6610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    String searchSource = "&source=android-" + GOOGLE_SEARCH_SOURCE_SUGGEST + "&";
6620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    if (url.contains(searchSource)) {
6630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        String source = null;
6640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        final Bundle appData = intent.getBundleExtra(SearchManager.APP_DATA);
6650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        if (appData != null) {
6660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            source = appData.getString(SearchManager.SOURCE);
6670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }
6680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        if (TextUtils.isEmpty(source)) {
6690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            source = GOOGLE_SEARCH_SOURCE_UNKNOWN;
6700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }
6710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        url = url.replace(searchSource, "&source=android-"+source+"&");
6720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
6730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
6740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
6750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
676068e48b469f5abca53ee3da38f933cf2c25c93b8Grace Kloba        return new UrlData(url, headers);
6770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
6780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
6790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /* package */ static String fixUrl(String inUrl) {
680652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark        // FIXME: Converting the url to lower case
681652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark        // duplicates functionality in smartUrlFilter().
682652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark        // However, changing all current callers of fixUrl to
683652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark        // call smartUrlFilter in addition may have unwanted
684652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark        // consequences, and is deferred for now.
685652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark        int colon = inUrl.indexOf(':');
686652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark        boolean allLower = true;
687652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark        for (int index = 0; index < colon; index++) {
688652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark            char ch = inUrl.charAt(index);
689652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark            if (!Character.isLetter(ch)) {
690652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark                break;
691652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark            }
692652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark            allLower &= Character.isLowerCase(ch);
693652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark            if (index == colon - 1 && !allLower) {
694652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark                inUrl = inUrl.substring(0, colon).toLowerCase()
695652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark                        + inUrl.substring(colon);
696652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark            }
697652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark        }
6980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (inUrl.startsWith("http://") || inUrl.startsWith("https://"))
6990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return inUrl;
7000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (inUrl.startsWith("http:") ||
7010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                inUrl.startsWith("https:")) {
7020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (inUrl.startsWith("http:/") || inUrl.startsWith("https:/")) {
7030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                inUrl = inUrl.replaceFirst("/", "//");
7040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } else inUrl = inUrl.replaceFirst(":", "://");
7050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
7060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return inUrl;
7070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
7080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
70922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    @Override
71022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    protected void onResume() {
7110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        super.onResume();
71231a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort        if (LOGV_ENABLED) {
7130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Log.v(LOGTAG, "BrowserActivity.onResume: this=" + this);
7140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
7150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
7160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (!mActivityInPause) {
7170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Log.e(LOGTAG, "BrowserActivity is already resumed.");
7180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
7190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
7200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
7217bfa63b55644fbf2da1fe6a24b3be0267529202cMike Reed        mTabControl.resumeCurrentTab();
7220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mActivityInPause = false;
7237bfa63b55644fbf2da1fe6a24b3be0267529202cMike Reed        resumeWebViewTimers();
7240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
7250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mWakeLock.isHeld()) {
7260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mHandler.removeMessages(RELEASE_WAKELOCK);
7270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mWakeLock.release();
7280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
7290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
7300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mCredsDlg != null) {
7310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (!mHandler.hasMessages(CANCEL_CREDS_REQUEST)) {
7320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project             // In case credential request never comes back
7330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mHandler.sendEmptyMessageDelayed(CANCEL_CREDS_REQUEST, 6000);
7340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
7350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
7360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
7370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        registerReceiver(mNetworkStateIntentReceiver,
7380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                         mNetworkStateChangedFilter);
7390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebView.enablePlatformNotifications();
7400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
7410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
7423bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    /**
7433bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     * Since the actual title bar is embedded in the WebView, and removing it
744fe87bd3a3897e4bad65bb3d284659ae2f4e57570Leon Scroggins     * would change its appearance, use a different TitleBar to show overlayed
745fe87bd3a3897e4bad65bb3d284659ae2f4e57570Leon Scroggins     * at the top of the screen, when the menu is open or the page is loading.
7463bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     */
7473bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    private TitleBar mFakeTitleBar;
7483bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins
7493bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    /**
750d8fd2fcf4eb037fd65ae923c6dbeff6c6ecb4d4fLeon Scroggins     * Holder for the fake title bar.  It will have a foreground shadow, as well
751d8fd2fcf4eb037fd65ae923c6dbeff6c6ecb4d4fLeon Scroggins     * as a white background, so the fake title bar looks like the real one.
752d8fd2fcf4eb037fd65ae923c6dbeff6c6ecb4d4fLeon Scroggins     */
753d8fd2fcf4eb037fd65ae923c6dbeff6c6ecb4d4fLeon Scroggins    private ViewGroup mFakeTitleBarHolder;
754d8fd2fcf4eb037fd65ae923c6dbeff6c6ecb4d4fLeon Scroggins
755d8fd2fcf4eb037fd65ae923c6dbeff6c6ecb4d4fLeon Scroggins    /**
756d8fd2fcf4eb037fd65ae923c6dbeff6c6ecb4d4fLeon Scroggins     * Layout parameters for the fake title bar within mFakeTitleBarHolder
757d8fd2fcf4eb037fd65ae923c6dbeff6c6ecb4d4fLeon Scroggins     */
758d8fd2fcf4eb037fd65ae923c6dbeff6c6ecb4d4fLeon Scroggins    private FrameLayout.LayoutParams mFakeTitleBarParams
759d8fd2fcf4eb037fd65ae923c6dbeff6c6ecb4d4fLeon Scroggins            = new FrameLayout.LayoutParams(
76015b8ec6b226f4d57307716e1f495e10a91f8cbf4Romain Guy            ViewGroup.LayoutParams.MATCH_PARENT,
761d8fd2fcf4eb037fd65ae923c6dbeff6c6ecb4d4fLeon Scroggins            ViewGroup.LayoutParams.WRAP_CONTENT);
762d8fd2fcf4eb037fd65ae923c6dbeff6c6ecb4d4fLeon Scroggins    /**
7633bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     * Keeps track of whether the options menu is open.  This is important in
7643bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     * determining whether to show or hide the title bar overlay.
7653bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     */
7663bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    private boolean mOptionsMenuOpen;
7673bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins
7683bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    /**
7693bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     * Only meaningful when mOptionsMenuOpen is true.  This variable keeps track
7703bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     * of whether the configuration has changed.  The first onMenuOpened call
7713bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     * after a configuration change is simply a reopening of the same menu
7723bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     * (i.e. mIconView did not change).
7733bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     */
7743bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    private boolean mConfigChanged;
7753bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins
7763bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    /**
7773bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     * Whether or not the options menu is in its smaller, icon menu form.  When
7783bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     * true, we want the title bar overlay to be up.  When false, we do not.
7793bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     * Only meaningful if mOptionsMenuOpen is true.
7803bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     */
7813bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    private boolean mIconView;
7823bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins
783a81a764063d2f849fba0cbc3039f86e67c2960ddLeon Scroggins    @Override
784a81a764063d2f849fba0cbc3039f86e67c2960ddLeon Scroggins    public boolean onMenuOpened(int featureId, Menu menu) {
7853bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins        if (Window.FEATURE_OPTIONS_PANEL == featureId) {
7863bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins            if (mOptionsMenuOpen) {
7873bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                if (mConfigChanged) {
7883bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                    // We do not need to make any changes to the state of the
7893bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                    // title bar, since the only thing that happened was a
7903bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                    // change in orientation
7913bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                    mConfigChanged = false;
7923bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                } else {
7933bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                    if (mIconView) {
7943bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                        // Switching the menu to expanded view, so hide the
7953bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                        // title bar.
7963bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                        hideFakeTitleBar();
7973bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                        mIconView = false;
7983bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                    } else {
7993bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                        // Switching the menu back to icon view, so show the
8003bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                        // title bar once again.
8013bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                        showFakeTitleBar();
8023bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                        mIconView = true;
8033bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                    }
8043bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                }
8053bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins            } else {
8063bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                // The options menu is closed, so open it, and show the title
8073bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                showFakeTitleBar();
8083bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                mOptionsMenuOpen = true;
8093bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                mConfigChanged = false;
8103bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                mIconView = true;
8113bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins            }
8123bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins        }
813a81a764063d2f849fba0cbc3039f86e67c2960ddLeon Scroggins        return true;
814a81a764063d2f849fba0cbc3039f86e67c2960ddLeon Scroggins    }
815a81a764063d2f849fba0cbc3039f86e67c2960ddLeon Scroggins
816b94bf27370329abb27e5e33b493d6edb5662b36eLeon Scroggins    /**
817b94bf27370329abb27e5e33b493d6edb5662b36eLeon Scroggins     * Special class used exclusively for the shadow drawn underneath the fake
818b94bf27370329abb27e5e33b493d6edb5662b36eLeon Scroggins     * title bar.  The shadow does not need to be drawn if the WebView
819b94bf27370329abb27e5e33b493d6edb5662b36eLeon Scroggins     * underneath is scrolled to the top, because it will draw directly on top
820b94bf27370329abb27e5e33b493d6edb5662b36eLeon Scroggins     * of the embedded shadow.
821b94bf27370329abb27e5e33b493d6edb5662b36eLeon Scroggins     */
822b94bf27370329abb27e5e33b493d6edb5662b36eLeon Scroggins    private static class Shadow extends View {
823b94bf27370329abb27e5e33b493d6edb5662b36eLeon Scroggins        private WebView mWebView;
824b94bf27370329abb27e5e33b493d6edb5662b36eLeon Scroggins
825b94bf27370329abb27e5e33b493d6edb5662b36eLeon Scroggins        public Shadow(Context context, AttributeSet attrs) {
826b94bf27370329abb27e5e33b493d6edb5662b36eLeon Scroggins            super(context, attrs);
827b94bf27370329abb27e5e33b493d6edb5662b36eLeon Scroggins        }
828b94bf27370329abb27e5e33b493d6edb5662b36eLeon Scroggins
829b94bf27370329abb27e5e33b493d6edb5662b36eLeon Scroggins        public void setWebView(WebView view) {
830b94bf27370329abb27e5e33b493d6edb5662b36eLeon Scroggins            mWebView = view;
831b94bf27370329abb27e5e33b493d6edb5662b36eLeon Scroggins        }
832b94bf27370329abb27e5e33b493d6edb5662b36eLeon Scroggins
833b94bf27370329abb27e5e33b493d6edb5662b36eLeon Scroggins        @Override
834b94bf27370329abb27e5e33b493d6edb5662b36eLeon Scroggins        public void draw(Canvas canvas) {
835b94bf27370329abb27e5e33b493d6edb5662b36eLeon Scroggins            // In general onDraw is the method to override, but we care about
836b94bf27370329abb27e5e33b493d6edb5662b36eLeon Scroggins            // whether or not the background gets drawn, which happens in draw()
837b94bf27370329abb27e5e33b493d6edb5662b36eLeon Scroggins            if (mWebView == null || mWebView.getScrollY() > getHeight()) {
838b94bf27370329abb27e5e33b493d6edb5662b36eLeon Scroggins                super.draw(canvas);
839b94bf27370329abb27e5e33b493d6edb5662b36eLeon Scroggins            }
840b94bf27370329abb27e5e33b493d6edb5662b36eLeon Scroggins            // Need to invalidate so that if the scroll position changes, we
841b94bf27370329abb27e5e33b493d6edb5662b36eLeon Scroggins            // still draw as appropriate.
842b94bf27370329abb27e5e33b493d6edb5662b36eLeon Scroggins            invalidate();
843b94bf27370329abb27e5e33b493d6edb5662b36eLeon Scroggins        }
844b94bf27370329abb27e5e33b493d6edb5662b36eLeon Scroggins    }
845b94bf27370329abb27e5e33b493d6edb5662b36eLeon Scroggins
8463bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    private void showFakeTitleBar() {
847f8de8ecc321fe5b45846adc38d174d5bc2208f20Patrick Scott        final View decor = getWindow().peekDecorView();
848fe87bd3a3897e4bad65bb3d284659ae2f4e57570Leon Scroggins        if (mFakeTitleBar.getParent() == null && mActiveTabsPage == null
849f8de8ecc321fe5b45846adc38d174d5bc2208f20Patrick Scott                && !mActivityInPause && decor != null
850f8de8ecc321fe5b45846adc38d174d5bc2208f20Patrick Scott                && decor.getWindowToken() != null) {
851a04645545690d9f637ccae4d043a5a1b8478a832Cary Clark            Rect visRect = new Rect();
852a04645545690d9f637ccae4d043a5a1b8478a832Cary Clark            if (!mBrowserFrameLayout.getGlobalVisibleRect(visRect)) {
853a04645545690d9f637ccae4d043a5a1b8478a832Cary Clark                if (LOGD_ENABLED) {
854a04645545690d9f637ccae4d043a5a1b8478a832Cary Clark                    Log.d(LOGTAG, "showFakeTitleBar visRect failed");
855a04645545690d9f637ccae4d043a5a1b8478a832Cary Clark                }
856a04645545690d9f637ccae4d043a5a1b8478a832Cary Clark                return;
857a04645545690d9f637ccae4d043a5a1b8478a832Cary Clark            }
8583bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins
8593bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins            WindowManager manager
8603bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                    = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
8613bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins
8623bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins            // Add the title bar to the window manager so it can receive touches
8633bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins            // while the menu is up
8643bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins            WindowManager.LayoutParams params
8653bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                    = new WindowManager.LayoutParams(
86615b8ec6b226f4d57307716e1f495e10a91f8cbf4Romain Guy                    ViewGroup.LayoutParams.MATCH_PARENT,
8673bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                    ViewGroup.LayoutParams.WRAP_CONTENT,
8683bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                    WindowManager.LayoutParams.TYPE_APPLICATION_SUB_PANEL,
8693bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                    WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
870685498685d8424f48d77d26d8d5790da34645f44Leon Scroggins                    PixelFormat.TRANSLUCENT);
8713bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins            params.gravity = Gravity.TOP;
872a27ff19e24cb1c9fef5624dbc4554548349b5b31Leon Scroggins            WebView mainView = mTabControl.getCurrentWebView();
873685498685d8424f48d77d26d8d5790da34645f44Leon Scroggins            boolean atTop = mainView != null && mainView.getScrollY() == 0;
87483932c74ba031eb2f581f1557c1a90f4b5bbb423Leon Scroggins            params.windowAnimations = atTop ? 0 : R.style.TitleBar;
8753bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins            // XXX : Without providing an offset, the fake title bar will be
8763bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins            // placed underneath the status bar.  Use the global visible rect
8773bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins            // of mBrowserFrameLayout to determine the bottom of the status bar
878a04645545690d9f637ccae4d043a5a1b8478a832Cary Clark            params.y = visRect.top;
879685498685d8424f48d77d26d8d5790da34645f44Leon Scroggins            // Add a holder for the title bar.  It also holds a shadow to show
880685498685d8424f48d77d26d8d5790da34645f44Leon Scroggins            // below the title bar.
881d8fd2fcf4eb037fd65ae923c6dbeff6c6ecb4d4fLeon Scroggins            if (mFakeTitleBarHolder == null) {
882d8fd2fcf4eb037fd65ae923c6dbeff6c6ecb4d4fLeon Scroggins                mFakeTitleBarHolder = (ViewGroup) LayoutInflater.from(this)
883d8fd2fcf4eb037fd65ae923c6dbeff6c6ecb4d4fLeon Scroggins                    .inflate(R.layout.title_bar_bg, null);
884d8fd2fcf4eb037fd65ae923c6dbeff6c6ecb4d4fLeon Scroggins            }
885b94bf27370329abb27e5e33b493d6edb5662b36eLeon Scroggins            Shadow shadow = (Shadow) mFakeTitleBarHolder.findViewById(
886b94bf27370329abb27e5e33b493d6edb5662b36eLeon Scroggins                    R.id.shadow);
887b94bf27370329abb27e5e33b493d6edb5662b36eLeon Scroggins            shadow.setWebView(mainView);
888685498685d8424f48d77d26d8d5790da34645f44Leon Scroggins            mFakeTitleBarHolder.addView(mFakeTitleBar, 0, mFakeTitleBarParams);
889d8fd2fcf4eb037fd65ae923c6dbeff6c6ecb4d4fLeon Scroggins            manager.addView(mFakeTitleBarHolder, params);
8903bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins        }
8913bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    }
8923bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins
8933bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    @Override
8943bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    public void onOptionsMenuClosed(Menu menu) {
8953bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins        mOptionsMenuOpen = false;
896a27ff19e24cb1c9fef5624dbc4554548349b5b31Leon Scroggins        if (!mInLoad) {
897a27ff19e24cb1c9fef5624dbc4554548349b5b31Leon Scroggins            hideFakeTitleBar();
898a27ff19e24cb1c9fef5624dbc4554548349b5b31Leon Scroggins        } else if (!mIconView) {
899a27ff19e24cb1c9fef5624dbc4554548349b5b31Leon Scroggins            // The page is currently loading, and we are in expanded mode, so
900a27ff19e24cb1c9fef5624dbc4554548349b5b31Leon Scroggins            // we were not showing the menu.  Show it once again.  It will be
901a27ff19e24cb1c9fef5624dbc4554548349b5b31Leon Scroggins            // removed when the page finishes.
902a27ff19e24cb1c9fef5624dbc4554548349b5b31Leon Scroggins            showFakeTitleBar();
903a27ff19e24cb1c9fef5624dbc4554548349b5b31Leon Scroggins        }
9043bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    }
90522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
9063bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    private void hideFakeTitleBar() {
907fe87bd3a3897e4bad65bb3d284659ae2f4e57570Leon Scroggins        if (mFakeTitleBar.getParent() == null) return;
90820329570ba9409637298da90b83f25801d7a3d55Leon Scroggins        WindowManager.LayoutParams params = (WindowManager.LayoutParams)
90920329570ba9409637298da90b83f25801d7a3d55Leon Scroggins                mFakeTitleBarHolder.getLayoutParams();
91020329570ba9409637298da90b83f25801d7a3d55Leon Scroggins        WebView mainView = mTabControl.getCurrentWebView();
91120329570ba9409637298da90b83f25801d7a3d55Leon Scroggins        // Although we decided whether or not to animate based on the current
91220329570ba9409637298da90b83f25801d7a3d55Leon Scroggins        // scroll position, the scroll position may have changed since the
91320329570ba9409637298da90b83f25801d7a3d55Leon Scroggins        // fake title bar was displayed.  Make sure it has the appropriate
91420329570ba9409637298da90b83f25801d7a3d55Leon Scroggins        // animation/lack thereof before removing.
91520329570ba9409637298da90b83f25801d7a3d55Leon Scroggins        params.windowAnimations = mainView != null && mainView.getScrollY() == 0
91683932c74ba031eb2f581f1557c1a90f4b5bbb423Leon Scroggins                ? 0 : R.style.TitleBar;
9173bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins        WindowManager manager
9183bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                    = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
91920329570ba9409637298da90b83f25801d7a3d55Leon Scroggins        manager.updateViewLayout(mFakeTitleBarHolder, params);
920d8fd2fcf4eb037fd65ae923c6dbeff6c6ecb4d4fLeon Scroggins        mFakeTitleBarHolder.removeView(mFakeTitleBar);
921d8fd2fcf4eb037fd65ae923c6dbeff6c6ecb4d4fLeon Scroggins        manager.removeView(mFakeTitleBarHolder);
9223bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    }
9233bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins
9240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
925c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins     * Special method for the fake title bar to call when displaying its context
926c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins     * menu, since it is in its own Window, and its parent does not show a
927c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins     * context menu.
928c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins     */
929c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins    /* package */ void showTitleBarContextMenu() {
93065f4a3ce9e5c4a5227bbcbb995e5e15f1f85d3d7Cary Clark        if (null == mTitleBar.getParent()) {
93165f4a3ce9e5c4a5227bbcbb995e5e15f1f85d3d7Cary Clark            return;
93265f4a3ce9e5c4a5227bbcbb995e5e15f1f85d3d7Cary Clark        }
933c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins        openContextMenu(mTitleBar);
934c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins    }
935c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins
936b2b19f501ee05448ca81bddaaca70e9b2f51cb54Leon Scroggins    @Override
937b2b19f501ee05448ca81bddaaca70e9b2f51cb54Leon Scroggins    public void onContextMenuClosed(Menu menu) {
938b2b19f501ee05448ca81bddaaca70e9b2f51cb54Leon Scroggins        super.onContextMenuClosed(menu);
939b2b19f501ee05448ca81bddaaca70e9b2f51cb54Leon Scroggins        if (mInLoad) {
940b2b19f501ee05448ca81bddaaca70e9b2f51cb54Leon Scroggins            showFakeTitleBar();
941b2b19f501ee05448ca81bddaaca70e9b2f51cb54Leon Scroggins        }
942b2b19f501ee05448ca81bddaaca70e9b2f51cb54Leon Scroggins    }
943b2b19f501ee05448ca81bddaaca70e9b2f51cb54Leon Scroggins
944c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins    /**
9450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *  onSaveInstanceState(Bundle map)
9460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *  onSaveInstanceState is called right before onStop(). The map contains
9470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *  the saved state.
9480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
94922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    @Override
95022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    protected void onSaveInstanceState(Bundle outState) {
95131a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort        if (LOGV_ENABLED) {
9520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Log.v(LOGTAG, "BrowserActivity.onSaveInstanceState: this=" + this);
9530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
9540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // the default implementation requires each view to have an id. As the
9550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // browser handles the state itself and it doesn't use id for the views,
9560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // don't call the default implementation. Otherwise it will trigger the
9570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // warning like this, "couldn't save which view has focus because the
9580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // focused view XXX has no id".
9590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
9600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Save all the tabs
9610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mTabControl.saveState(outState);
9620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
9630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
96422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    @Override
96522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    protected void onPause() {
9660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        super.onPause();
9670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
9680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mActivityInPause) {
9690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Log.e(LOGTAG, "BrowserActivity is already paused.");
9700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
9710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
9720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
9737bfa63b55644fbf2da1fe6a24b3be0267529202cMike Reed        mTabControl.pauseCurrentTab();
9740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mActivityInPause = true;
9757bfa63b55644fbf2da1fe6a24b3be0267529202cMike Reed        if (mTabControl.getCurrentIndex() >= 0 && !pauseWebViewTimers()) {
9760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mWakeLock.acquire();
9770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mHandler.sendMessageDelayed(mHandler
9780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    .obtainMessage(RELEASE_WAKELOCK), WAKELOCK_TIMEOUT);
9790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
9800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
9810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Clear the credentials toast if it is up
9820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mCredsDlg != null && mCredsDlg.isShowing()) {
9830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mCredsDlg.dismiss();
9840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
9850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mCredsDlg = null;
9860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
987a2ab6a7dc0f7023c1d7ebb1cbad397c5dc3d6453Leon Scroggins        // FIXME: This removes the active tabs page and resets the menu to
988a2ab6a7dc0f7023c1d7ebb1cbad397c5dc3d6453Leon Scroggins        // MAIN_MENU.  A better solution might be to do this work in onNewIntent
989a2ab6a7dc0f7023c1d7ebb1cbad397c5dc3d6453Leon Scroggins        // but then we would need to save it in onSaveInstanceState and restore
990a2ab6a7dc0f7023c1d7ebb1cbad397c5dc3d6453Leon Scroggins        // it in onCreate/onRestoreInstanceState
991a2ab6a7dc0f7023c1d7ebb1cbad397c5dc3d6453Leon Scroggins        if (mActiveTabsPage != null) {
992a2ab6a7dc0f7023c1d7ebb1cbad397c5dc3d6453Leon Scroggins            removeActiveTabPage(true);
993a2ab6a7dc0f7023c1d7ebb1cbad397c5dc3d6453Leon Scroggins        }
994a2ab6a7dc0f7023c1d7ebb1cbad397c5dc3d6453Leon Scroggins
9950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        cancelStopToast();
9960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
9970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // unregister network state listener
9980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        unregisterReceiver(mNetworkStateIntentReceiver);
9990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebView.disablePlatformNotifications();
10000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
10010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
100222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    @Override
100322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    protected void onDestroy() {
100431a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort        if (LOGV_ENABLED) {
10050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Log.v(LOGTAG, "BrowserActivity.onDestroy: this=" + this);
10060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
10070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        super.onDestroy();
10080923d69a8ca45222cabd82a80eaa88da9f132e9aGrace Kloba
10098d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins        if (mUploadMessage != null) {
10108d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins            mUploadMessage.onReceiveValue(null);
10118d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins            mUploadMessage = null;
10128d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins        }
10138d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins
10140923d69a8ca45222cabd82a80eaa88da9f132e9aGrace Kloba        if (mTabControl == null) return;
10150923d69a8ca45222cabd82a80eaa88da9f132e9aGrace Kloba
10161fc98a322e9df6b0e797c26de6b2cb23d69ad5d3Grace Kloba        // Remove the fake title bar if it is there
10171fc98a322e9df6b0e797c26de6b2cb23d69ad5d3Grace Kloba        hideFakeTitleBar();
10181fc98a322e9df6b0e797c26de6b2cb23d69ad5d3Grace Kloba
10190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Remove the current tab and sub window
102022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        Tab t = mTabControl.getCurrentTab();
1021fb5e77fac7b8b311fe72827183f8988f5ee92a5fPatrick Scott        if (t != null) {
1022fb5e77fac7b8b311fe72827183f8988f5ee92a5fPatrick Scott            dismissSubWindow(t);
1023fb5e77fac7b8b311fe72827183f8988f5ee92a5fPatrick Scott            removeTabFromContentView(t);
1024fb5e77fac7b8b311fe72827183f8988f5ee92a5fPatrick Scott        }
10250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Destroy all the tabs
10260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mTabControl.destroy();
10270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebIconDatabase.getInstance().close();
10280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
1029b4da0ad0351996f639b50f9f29b123a9b5c24fd0Grace Kloba        unregisterReceiver(mPackageInstallationReceiver);
10300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
10310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
10320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    @Override
10330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public void onConfigurationChanged(Configuration newConfig) {
10343bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins        mConfigChanged = true;
10350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        super.onConfigurationChanged(newConfig);
10360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
10370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mPageInfoDialog != null) {
10380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mPageInfoDialog.dismiss();
10390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            showPageInfo(
10400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mPageInfoView,
1041c7b92f811dfa3572578ddc6714c98a03936d9ce5Leon Scroggins                mPageInfoFromShowSSLCertificateOnError);
10420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
10430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mSSLCertificateDialog != null) {
10440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mSSLCertificateDialog.dismiss();
10450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            showSSLCertificate(
10460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mSSLCertificateView);
10470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
10480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mSSLCertificateOnErrorDialog != null) {
10490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mSSLCertificateOnErrorDialog.dismiss();
10500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            showSSLCertificateOnError(
10510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mSSLCertificateOnErrorView,
10520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mSSLCertificateOnErrorHandler,
10530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mSSLCertificateOnErrorError);
10540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
10550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mHttpAuthenticationDialog != null) {
10560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            String title = ((TextView) mHttpAuthenticationDialog
10570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    .findViewById(com.android.internal.R.id.alertTitle)).getText()
10580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    .toString();
10590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            String name = ((TextView) mHttpAuthenticationDialog
10600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    .findViewById(R.id.username_edit)).getText().toString();
10610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            String password = ((TextView) mHttpAuthenticationDialog
10620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    .findViewById(R.id.password_edit)).getText().toString();
10630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            int focusId = mHttpAuthenticationDialog.getCurrentFocus()
10640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    .getId();
10650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mHttpAuthenticationDialog.dismiss();
10660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            showHttpAuthentication(mHttpAuthHandler, null, null, title,
10670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    name, password, focusId);
10680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
10690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
10700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
107122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    @Override
107222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    public void onLowMemory() {
10730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        super.onLowMemory();
10740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mTabControl.freeMemory();
10750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
10760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
10777bfa63b55644fbf2da1fe6a24b3be0267529202cMike Reed    private boolean resumeWebViewTimers() {
107822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        Tab tab = mTabControl.getCurrentTab();
107922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        boolean inLoad = tab.inLoad();
108022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if ((!mActivityInPause && !inLoad) || (mActivityInPause && inLoad)) {
10810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            CookieSyncManager.getInstance().startSync();
108222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            WebView w = tab.getWebView();
10830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (w != null) {
10840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                w.resumeTimers();
10850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
10860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return true;
10870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
10880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return false;
10890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
10900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
10910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
10927bfa63b55644fbf2da1fe6a24b3be0267529202cMike Reed    private boolean pauseWebViewTimers() {
109322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        Tab tab = mTabControl.getCurrentTab();
109422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        boolean inLoad = tab.inLoad();
109522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mActivityInPause && !inLoad) {
10960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            CookieSyncManager.getInstance().stopSync();
10970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            WebView w = mTabControl.getCurrentWebView();
10980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (w != null) {
10990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                w.pauseTimers();
11000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
11010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return true;
11020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
11030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return false;
11040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
11050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
11060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
11071f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins    // FIXME: Do we want to call this when loading google for the first time?
11080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /*
11090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * This function is called when we are launching for the first time. We
11100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * are waiting for the login credentials before loading Google home
11110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * pages. This way the user will be logged in straight away.
11120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
11130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void waitForCredentials() {
11140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Show a toast
11150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mCredsDlg = new ProgressDialog(this);
11160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mCredsDlg.setIndeterminate(true);
11170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mCredsDlg.setMessage(getText(R.string.retrieving_creds_dlg_msg));
11180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // If the user cancels the operation, then cancel the Google
11190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Credentials request.
11200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mCredsDlg.setCancelMessage(mHandler.obtainMessage(CANCEL_CREDS_REQUEST));
11210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mCredsDlg.show();
11220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
11230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // We set a timeout for the retrieval of credentials in onResume()
11240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // as that is when we have freed up some CPU time to get
11250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // the login credentials.
11260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
11270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
11280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /*
11290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * If we have received the credentials or we have timed out and we are
11300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * showing the credentials dialog, then it is time to move on.
11310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
11320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void resumeAfterCredentials() {
11330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mCredsDlg == null) {
11340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
11350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
11360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
11370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Clear the toast
11380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mCredsDlg.isShowing()) {
11390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mCredsDlg.dismiss();
11400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
11410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mCredsDlg = null;
11420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
11430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Clear any pending timeout
11440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mHandler.removeMessages(CANCEL_CREDS_REQUEST);
11450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
11460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Load the page
11470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebView w = mTabControl.getCurrentWebView();
11480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (w != null) {
11490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            w.loadUrl(mSettings.getHomePage());
11500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
11510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
11520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Update the settings, need to do this last as it can take a moment
11530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // to persist the settings. In the mean time we could be loading
11540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // content.
11550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mSettings.setLoginInitialized(this);
11560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
11570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
11580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Open the icon database and retain all the icons for visited sites.
11590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void retainIconsOnStartup() {
11600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final WebIconDatabase db = WebIconDatabase.getInstance();
11610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        db.open(getDir("icons", 0).getPath());
11620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        try {
11630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Cursor c = Browser.getAllBookmarks(mResolver);
11640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (!c.moveToFirst()) {
11650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                c.deactivate();
11660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                return;
11670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
11680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            int urlIndex = c.getColumnIndex(Browser.BookmarkColumns.URL);
11690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            do {
11700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                String url = c.getString(urlIndex);
11710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                db.retainIconForPageUrl(url);
11720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } while (c.moveToNext());
11730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            c.deactivate();
11740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } catch (IllegalStateException e) {
11750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Log.e(LOGTAG, "retainIconsOnStartup", e);
11760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
11770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
11780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
11790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Helper method for getting the top window.
11800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    WebView getTopWindow() {
11810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return mTabControl.getCurrentTopWebView();
11820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
11830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
118422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    TabControl getTabControl() {
118522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return mTabControl;
118622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
118722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
11880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    @Override
11890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public boolean onCreateOptionsMenu(Menu menu) {
11900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        super.onCreateOptionsMenu(menu);
11910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
11920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        MenuInflater inflater = getMenuInflater();
11930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        inflater.inflate(R.menu.browser, menu);
11940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mMenu = menu;
11950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        updateInLoadMenuItems();
11960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return true;
11970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
11980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
11990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
12000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * As the menu can be open when loading state changes
12010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * we must manually update the state of the stop/reload menu
12020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * item
12030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
12040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void updateInLoadMenuItems() {
12050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mMenu == null) {
12060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
12070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
12080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        MenuItem src = mInLoad ?
12090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mMenu.findItem(R.id.stop_menu_id):
12100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    mMenu.findItem(R.id.reload_menu_id);
12110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        MenuItem dest = mMenu.findItem(R.id.stop_reload_menu_id);
12120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        dest.setIcon(src.getIcon());
12130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        dest.setTitle(src.getTitle());
12140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
12150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
12160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    @Override
12170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public boolean onContextItemSelected(MenuItem item) {
12180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // chording is not an issue with context menus, but we use the same
12190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // options selector, so set mCanChord to true so we can access them.
12200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mCanChord = true;
12210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        int id = item.getItemId();
122296afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins        boolean result = true;
12230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        switch (id) {
1224c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins            // For the context menu from the title bar
1225c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins            case R.id.title_bar_copy_page_url:
122696afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                Tab currentTab = mTabControl.getCurrentTab();
122796afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                if (null == currentTab) {
122896afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                    result = false;
122996afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                    break;
1230c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins                }
123196afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                WebView mainView = currentTab.getWebView();
123296afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                if (null == mainView) {
123396afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                    result = false;
123496afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                    break;
1235c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins                }
123696afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                copy(mainView.getUrl());
1237c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins                break;
12380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // -- Browser context menu
12390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.open_context_menu_id:
12400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.open_newtab_context_menu_id:
12410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.bookmark_context_menu_id:
12420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.save_link_context_menu_id:
12430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.share_link_context_menu_id:
12440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.copy_link_context_menu_id:
1245c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins                final WebView webView = getTopWindow();
1246c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins                if (null == webView) {
124796afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                    result = false;
124896afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                    break;
1249c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins                }
1250c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins                final HashMap hrefMap = new HashMap();
1251c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins                hrefMap.put("webview", webView);
1252c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins                final Message msg = mHandler.obtainMessage(
1253c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins                        FOCUS_NODE_HREF, id, 0, hrefMap);
12540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                webView.requestFocusNodeHref(msg);
12550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
12560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
12570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            default:
12580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // For other context menus
125996afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                result = onOptionsItemSelected(item);
12600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
12610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mCanChord = false;
126296afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins        return result;
12630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
12640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
12650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private Bundle createGoogleSearchSourceBundle(String source) {
12660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        Bundle bundle = new Bundle();
12670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        bundle.putString(SearchManager.SOURCE, source);
12680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return bundle;
12690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
12700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
12710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
12724e5f58704099c37186d4825c3d55ea5b0527867fThe Android Open Source Project     * Overriding this to insert a local information bundle
12730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
12740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    @Override
12750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public boolean onSearchRequested() {
127668579393973f745fc65a2781061af9bb8f2d7020Leon Scroggins        if (mOptionsMenuOpen) closeOptionsMenu();
12775bbe98025a2c606a35c91b826760020890daadb1Leon Scroggins        String url = (getTopWindow() == null) ? null : getTopWindow().getUrl();
127883f473462fcd7869031a423c02b957c6e938a2f6Grace Kloba        startSearch(mSettings.getHomePage().equals(url) ? null : url, true,
12794e5f58704099c37186d4825c3d55ea5b0527867fThe Android Open Source Project                createGoogleSearchSourceBundle(GOOGLE_SEARCH_SOURCE_SEARCHKEY), false);
12800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return true;
12810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
12820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
12830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    @Override
12840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public void startSearch(String initialQuery, boolean selectInitialQuery,
12850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Bundle appSearchData, boolean globalSearch) {
12860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (appSearchData == null) {
12870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            appSearchData = createGoogleSearchSourceBundle(GOOGLE_SEARCH_SOURCE_TYPE);
12880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
12890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        super.startSearch(initialQuery, selectInitialQuery, appSearchData, globalSearch);
12900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
12910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
12921f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins    /**
12931f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins     * Switch tabs.  Called by the TitleBarSet when sliding the title bar
12941f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins     * results in changing tabs.
1295160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins     * @param index Index of the tab to change to, as defined by
1296160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins     *              mTabControl.getTabIndex(Tab t).
1297160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins     * @return boolean True if we successfully switched to a different tab.  If
1298160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins     *                 the indexth tab is null, or if that tab is the same as
1299160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins     *                 the current one, return false.
13001f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins     */
1301160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins    /* package */ boolean switchToTab(int index) {
130222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        Tab tab = mTabControl.getTab(index);
130322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        Tab currentTab = mTabControl.getCurrentTab();
13041f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins        if (tab == null || tab == currentTab) {
1305160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins            return false;
13061f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins        }
13071f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins        if (currentTab != null) {
13081f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins            // currentTab may be null if it was just removed.  In that case,
13091f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins            // we do not need to remove it
13101f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins            removeTabFromContentView(currentTab);
13111f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins        }
13121f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins        mTabControl.setCurrentTab(tab);
13131f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins        attachTabToContentView(tab);
1314eb6eef4c45df2d65c3e70660493a147a2be405e3Grace Kloba        resetTitleIconAndProgress();
1315eb6eef4c45df2d65c3e70660493a147a2be405e3Grace Kloba        updateLockIconToLatest();
1316160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins        return true;
13171f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins    }
13181f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins
131922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /* package */ Tab openTabToHomePage() {
13200a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins        return openTabAndShow(mSettings.getHomePage(), false, null);
13210a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins    }
13220a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins
13231f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins    /* package */ void closeCurrentWindow() {
132422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        final Tab current = mTabControl.getCurrentTab();
1325160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins        if (mTabControl.getTabCount() == 1) {
1326304442375719effd41dbd53ae62de7a8d0cec7d9Leon Scroggins            // This is the last tab.  Open a new one, with the home
1327304442375719effd41dbd53ae62de7a8d0cec7d9Leon Scroggins            // page and close the current one.
132822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            openTabToHomePage();
1329160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins            closeTab(current);
1330160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins            return;
1331160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins        }
133222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        final Tab parent = current.getParentTab();
13331f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins        int indexToShow = -1;
13341f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins        if (parent != null) {
13351f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins            indexToShow = mTabControl.getTabIndex(parent);
13361f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins        } else {
1337160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins            final int currentIndex = mTabControl.getCurrentIndex();
1338160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins            // Try to move to the tab to the right
1339160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins            indexToShow = currentIndex + 1;
1340160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins            if (indexToShow > mTabControl.getTabCount() - 1) {
1341160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins                // Try to move to the tab to the left
1342160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins                indexToShow = currentIndex - 1;
13431f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins            }
13441f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins        }
1345160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins        if (switchToTab(indexToShow)) {
1346160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins            // Close window
1347160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins            closeTab(current);
1348160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins        }
13491f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins    }
13501f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins
13510a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins    private ActiveTabsPage mActiveTabsPage;
13520a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins
13530a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins    /**
13540a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins     * Remove the active tabs page.
13550a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins     * @param needToAttach If true, the active tabs page did not attach a tab
13560a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins     *                     to the content view, so we need to do that here.
13570a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins     */
13580a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins    /* package */ void removeActiveTabPage(boolean needToAttach) {
13590a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins        mContentView.removeView(mActiveTabsPage);
13600a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins        mActiveTabsPage = null;
13610a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins        mMenuState = R.id.MAIN_MENU;
13620a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins        if (needToAttach) {
13630a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins            attachTabToContentView(mTabControl.getCurrentTab());
13640a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins        }
13650a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins        getTopWindow().requestFocus();
13660a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins    }
13670a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins
13680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    @Override
13690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public boolean onOptionsItemSelected(MenuItem item) {
13700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (!mCanChord) {
13710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // The user has already fired a shortcut with this hold down of the
13720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // menu key.
13730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return false;
13740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
13751f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins        if (null == getTopWindow()) {
13760d7ae0ed82e21d472cde8cf92b5657d8ee8ca0d8Leon Scroggins            return false;
13770d7ae0ed82e21d472cde8cf92b5657d8ee8ca0d8Leon Scroggins        }
13786ee9c498b8cf648f1507281ed5a1834ba3390907Grace Kloba        if (mMenuIsDown) {
13796ee9c498b8cf648f1507281ed5a1834ba3390907Grace Kloba            // The shortcut action consumes the MENU. Even if it is still down,
13806ee9c498b8cf648f1507281ed5a1834ba3390907Grace Kloba            // it won't trigger the next shortcut action. In the case of the
13816ee9c498b8cf648f1507281ed5a1834ba3390907Grace Kloba            // shortcut action triggering a new activity, like Bookmarks, we
13826ee9c498b8cf648f1507281ed5a1834ba3390907Grace Kloba            // won't get onKeyUp for MENU. So it is important to reset it here.
13836ee9c498b8cf648f1507281ed5a1834ba3390907Grace Kloba            mMenuIsDown = false;
13846ee9c498b8cf648f1507281ed5a1834ba3390907Grace Kloba        }
13850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        switch (item.getItemId()) {
13860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // -- Main menu
1387a81a764063d2f849fba0cbc3039f86e67c2960ddLeon Scroggins            case R.id.new_tab_menu_id:
13880a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins                openTabToHomePage();
1389a81a764063d2f849fba0cbc3039f86e67c2960ddLeon Scroggins                break;
1390a81a764063d2f849fba0cbc3039f86e67c2960ddLeon Scroggins
139164b80f3efd95d7b5192731e995ccde79c4c6c11fLeon Scroggins            case R.id.goto_menu_id:
1392b3a5bedeede968b53363a6c517f92bc2484bb42dLeon Scroggins                onSearchRequested();
1393b3a5bedeede968b53363a6c517f92bc2484bb42dLeon Scroggins                break;
1394b3a5bedeede968b53363a6c517f92bc2484bb42dLeon Scroggins
1395b3a5bedeede968b53363a6c517f92bc2484bb42dLeon Scroggins            case R.id.bookmarks_menu_id:
1396304442375719effd41dbd53ae62de7a8d0cec7d9Leon Scroggins                bookmarksOrHistoryPicker(false);
13970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
13980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
13990a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins            case R.id.active_tabs_menu_id:
14000a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins                mActiveTabsPage = new ActiveTabsPage(this, mTabControl);
14010a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins                removeTabFromContentView(mTabControl.getCurrentTab());
140243de61666cfc98a3acc41c7161a1a8b0bdb2b72bLeon Scroggins                hideFakeTitleBar();
14030a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins                mContentView.addView(mActiveTabsPage, COVER_SCREEN_PARAMS);
14040a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins                mActiveTabsPage.requestFocus();
14050a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins                mMenuState = EMPTY_MENU;
14060a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins                break;
14070a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins
14081f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins            case R.id.add_bookmark_menu_id:
14091f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                Intent i = new Intent(BrowserActivity.this,
14101f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                        AddBookmarkPage.class);
14111f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                WebView w = getTopWindow();
14121f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                i.putExtra("url", w.getUrl());
14131f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                i.putExtra("title", w.getTitle());
141483cdb2c40f2dbcbdf522a2af0ec8224c7195c6c1Grace Kloba                i.putExtra("touch_icon_url", w.getTouchIconUrl());
1415dcc2b6f08dd5677bc6ba761a9ba6f1c655113051Ben Murdoch                i.putExtra("thumbnail", createScreenshot(w));
14161f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                startActivity(i);
14170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
14180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
14190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.stop_reload_menu_id:
14200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (mInLoad) {
14210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    stopLoading();
14220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                } else {
14230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    getTopWindow().reload();
14240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
14250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
14260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
14270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.back_menu_id:
14280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                getTopWindow().goBack();
14290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
14300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
14310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.forward_menu_id:
14320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                getTopWindow().goForward();
14330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
14340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
14350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.close_menu_id:
14360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // Close the subwindow if it exists.
14370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (mTabControl.getCurrentSubWindow() != null) {
14380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    dismissSubWindow(mTabControl.getCurrentTab());
14390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    break;
14400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
14411f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                closeCurrentWindow();
14420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
14430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
14440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.homepage_menu_id:
144522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                Tab current = mTabControl.getCurrentTab();
14460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (current != null) {
14470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    dismissSubWindow(current);
14480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    current.getWebView().loadUrl(mSettings.getHomePage());
14490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
14500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
14510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
14520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.preferences_menu_id:
14530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                Intent intent = new Intent(this,
14540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        BrowserPreferencesPage.class);
1455d530494de9c182af4aff97ddd46343b32594da51Leon Scroggins                intent.putExtra(BrowserPreferencesPage.CURRENT_PAGE,
1456d530494de9c182af4aff97ddd46343b32594da51Leon Scroggins                        getTopWindow().getUrl());
14570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                startActivityForResult(intent, PREFERENCES_PAGE);
14580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
14590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
14600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.find_menu_id:
14610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (null == mFindDialog) {
14620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    mFindDialog = new FindDialog(this);
14630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
14640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mFindDialog.setWebView(getTopWindow());
14650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mFindDialog.show();
14660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mMenuState = EMPTY_MENU;
14670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
14680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
14690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.select_text_id:
14700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                getTopWindow().emulateShiftHeld();
14710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
14720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.page_info_menu_id:
14730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                showPageInfo(mTabControl.getCurrentTab(), false);
14740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
14750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
14760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.classic_history_menu_id:
1477304442375719effd41dbd53ae62de7a8d0cec7d9Leon Scroggins                bookmarksOrHistoryPicker(true);
14780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
14790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
148096afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins            case R.id.title_bar_share_page_url:
14810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.share_page_menu_id:
148296afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                Tab currentTab = mTabControl.getCurrentTab();
148396afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                if (null == currentTab) {
148496afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                    mCanChord = false;
148596afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                    return false;
148696afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                }
148796afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                currentTab.populatePickerData();
148896afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                sharePage(this, currentTab.getTitle(),
148996afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                        currentTab.getUrl(), currentTab.getFavicon(),
149096afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                        createScreenshot(currentTab.getWebView()));
14910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
14920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
14930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.dump_nav_menu_id:
14940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                getTopWindow().debugDump();
14950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
14960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
14970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.zoom_in_menu_id:
14980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                getTopWindow().zoomIn();
14990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
15000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
15010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.zoom_out_menu_id:
15020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                getTopWindow().zoomOut();
15030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
15040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
15050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.view_downloads_menu_id:
15060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                viewDownloads(null);
15070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
15080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
15090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.window_one_menu_id:
15100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.window_two_menu_id:
15110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.window_three_menu_id:
15120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.window_four_menu_id:
15130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.window_five_menu_id:
15140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.window_six_menu_id:
15150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.window_seven_menu_id:
15160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.window_eight_menu_id:
15170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                {
15180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    int menuid = item.getItemId();
15190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    for (int id = 0; id < WINDOW_SHORTCUT_ID_ARRAY.length; id++) {
15200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        if (WINDOW_SHORTCUT_ID_ARRAY[id] == menuid) {
152122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            Tab desiredTab = mTabControl.getTab(id);
15220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            if (desiredTab != null &&
15230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    desiredTab != mTabControl.getCurrentTab()) {
15241f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                                switchToTab(id);
15250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            }
15260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            break;
15270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }
15280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
15290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
15300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
15310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
15320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            default:
15330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (!super.onOptionsItemSelected(item)) {
15340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    return false;
15350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
15360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // Otherwise fall through.
15370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
15380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mCanChord = false;
15390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return true;
15400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
15410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
15420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public void closeFind() {
15430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mMenuState = R.id.MAIN_MENU;
15440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
15450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
154622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    @Override
154722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    public boolean onPrepareOptionsMenu(Menu menu) {
15480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // This happens when the user begins to hold down the menu key, so
15490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // allow them to chord to get a shortcut.
15500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mCanChord = true;
15510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Note: setVisible will decide whether an item is visible; while
15520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // setEnabled() will decide whether an item is enabled, which also means
15530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // whether the matching shortcut key will function.
15540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        super.onPrepareOptionsMenu(menu);
15550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        switch (mMenuState) {
15560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case EMPTY_MENU:
15570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (mCurrentMenuState != mMenuState) {
15580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    menu.setGroupVisible(R.id.MAIN_MENU, false);
15590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    menu.setGroupEnabled(R.id.MAIN_MENU, false);
15600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    menu.setGroupEnabled(R.id.MAIN_SHORTCUT_MENU, false);
15610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
15620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
15630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            default:
15640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (mCurrentMenuState != mMenuState) {
15650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    menu.setGroupVisible(R.id.MAIN_MENU, true);
15660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    menu.setGroupEnabled(R.id.MAIN_MENU, true);
15670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    menu.setGroupEnabled(R.id.MAIN_SHORTCUT_MENU, true);
15680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
15690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                final WebView w = getTopWindow();
15700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                boolean canGoBack = false;
15710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                boolean canGoForward = false;
15720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                boolean isHome = false;
15730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (w != null) {
15740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    canGoBack = w.canGoBack();
15750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    canGoForward = w.canGoForward();
15760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    isHome = mSettings.getHomePage().equals(w.getUrl());
15770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
15780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                final MenuItem back = menu.findItem(R.id.back_menu_id);
15790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                back.setEnabled(canGoBack);
15800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
15810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                final MenuItem home = menu.findItem(R.id.homepage_menu_id);
15820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                home.setEnabled(!isHome);
15830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
15840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.forward_menu_id)
15850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        .setEnabled(canGoForward);
15860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
1587a81a764063d2f849fba0cbc3039f86e67c2960ddLeon Scroggins                menu.findItem(R.id.new_tab_menu_id).setEnabled(
158822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        mTabControl.canCreateNewTab());
1589a81a764063d2f849fba0cbc3039f86e67c2960ddLeon Scroggins
15900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // decide whether to show the share link option
15910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                PackageManager pm = getPackageManager();
15920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                Intent send = new Intent(Intent.ACTION_SEND);
15930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                send.setType("text/plain");
15940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                ResolveInfo ri = pm.resolveActivity(send, PackageManager.MATCH_DEFAULT_ONLY);
15950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.share_page_menu_id).setVisible(ri != null);
15960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
15970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                boolean isNavDump = mSettings.isNavDump();
15980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                final MenuItem nav = menu.findItem(R.id.dump_nav_menu_id);
15990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                nav.setVisible(isNavDump);
16000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                nav.setEnabled(isNavDump);
16010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
16020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
16030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mCurrentMenuState = mMenuState;
16040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return true;
16050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
16060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
16070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    @Override
16080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public void onCreateContextMenu(ContextMenu menu, View v,
16090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ContextMenuInfo menuInfo) {
16100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebView webview = (WebView) v;
16110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebView.HitTestResult result = webview.getHitTestResult();
16120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (result == null) {
16130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
16140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
16150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
16160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        int type = result.getType();
16170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (type == WebView.HitTestResult.UNKNOWN_TYPE) {
16180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Log.w(LOGTAG,
16190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    "We should not show context menu when nothing is touched");
16200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
16210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
16220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (type == WebView.HitTestResult.EDIT_TEXT_TYPE) {
16230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // let TextView handles context menu
16240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
16250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
16260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
16270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Note, http://b/issue?id=1106666 is requesting that
16280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // an inflated menu can be used again. This is not available
16290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // yet, so inflate each time (yuk!)
16300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        MenuInflater inflater = getMenuInflater();
16310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        inflater.inflate(R.menu.browsercontext, menu);
16320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
16330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Show the correct menu group
16340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String extra = result.getExtra();
16350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        menu.setGroupVisible(R.id.PHONE_MENU,
16360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                type == WebView.HitTestResult.PHONE_TYPE);
16370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        menu.setGroupVisible(R.id.EMAIL_MENU,
16380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                type == WebView.HitTestResult.EMAIL_TYPE);
16390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        menu.setGroupVisible(R.id.GEO_MENU,
16400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                type == WebView.HitTestResult.GEO_TYPE);
16410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        menu.setGroupVisible(R.id.IMAGE_MENU,
16420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                type == WebView.HitTestResult.IMAGE_TYPE
16430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                || type == WebView.HitTestResult.SRC_IMAGE_ANCHOR_TYPE);
16440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        menu.setGroupVisible(R.id.ANCHOR_MENU,
16450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                type == WebView.HitTestResult.SRC_ANCHOR_TYPE
16460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                || type == WebView.HitTestResult.SRC_IMAGE_ANCHOR_TYPE);
16470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
16480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Setup custom handling depending on the type
16490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        switch (type) {
16500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case WebView.HitTestResult.PHONE_TYPE:
16510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.setHeaderTitle(Uri.decode(extra));
16520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.dial_context_menu_id).setIntent(
16530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new Intent(Intent.ACTION_VIEW, Uri
16540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                .parse(WebView.SCHEME_TEL + extra)));
16550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                Intent addIntent = new Intent(Intent.ACTION_INSERT_OR_EDIT);
16560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                addIntent.putExtra(Insert.PHONE, Uri.decode(extra));
16575e335a381a0cd66e94117b202c1f34f5cb29c9b8Cary Clark                addIntent.setType(ContactsContract.Contacts.CONTENT_ITEM_TYPE);
16580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.add_contact_context_menu_id).setIntent(
16590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        addIntent);
16600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.copy_phone_context_menu_id).setOnMenuItemClickListener(
16610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new Copy(extra));
16620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
16630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
16640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case WebView.HitTestResult.EMAIL_TYPE:
16650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.setHeaderTitle(extra);
16660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.email_context_menu_id).setIntent(
16670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new Intent(Intent.ACTION_VIEW, Uri
16680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                .parse(WebView.SCHEME_MAILTO + extra)));
16690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.copy_mail_context_menu_id).setOnMenuItemClickListener(
16700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new Copy(extra));
16710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
16720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
16730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case WebView.HitTestResult.GEO_TYPE:
16740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.setHeaderTitle(extra);
16750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.map_context_menu_id).setIntent(
16760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new Intent(Intent.ACTION_VIEW, Uri
16770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                .parse(WebView.SCHEME_GEO
16780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        + URLEncoder.encode(extra))));
16790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.copy_geo_context_menu_id).setOnMenuItemClickListener(
16800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new Copy(extra));
16810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
16820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
16830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case WebView.HitTestResult.SRC_ANCHOR_TYPE:
16840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case WebView.HitTestResult.SRC_IMAGE_ANCHOR_TYPE:
16850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                TextView titleView = (TextView) LayoutInflater.from(this)
16860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        .inflate(android.R.layout.browser_link_context_header,
16870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        null);
16880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                titleView.setText(extra);
16890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.setHeaderView(titleView);
16900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // decide whether to show the open link in new tab option
16910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.open_newtab_context_menu_id).setVisible(
169222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        mTabControl.canCreateNewTab());
1693de353621650d17a412b6ffe2cbf0366db5f11c40Ben Murdoch                menu.findItem(R.id.bookmark_context_menu_id).setVisible(
1694de353621650d17a412b6ffe2cbf0366db5f11c40Ben Murdoch                        Bookmarks.urlHasAcceptableScheme(extra));
16950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                PackageManager pm = getPackageManager();
16960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                Intent send = new Intent(Intent.ACTION_SEND);
16970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                send.setType("text/plain");
16980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                ResolveInfo ri = pm.resolveActivity(send, PackageManager.MATCH_DEFAULT_ONLY);
16990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.share_link_context_menu_id).setVisible(ri != null);
17000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (type == WebView.HitTestResult.SRC_ANCHOR_TYPE) {
17010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    break;
17020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
17030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // otherwise fall through to handle image part
17040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case WebView.HitTestResult.IMAGE_TYPE:
17050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (type == WebView.HitTestResult.IMAGE_TYPE) {
17060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    menu.setHeaderTitle(extra);
17070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
17080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.view_image_context_menu_id).setIntent(
17090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new Intent(Intent.ACTION_VIEW, Uri.parse(extra)));
17100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.download_context_menu_id).
17110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        setOnMenuItemClickListener(new Download(extra));
17124f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                menu.findItem(R.id.set_wallpaper_context_menu_id).
17134f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                        setOnMenuItemClickListener(new SetAsWallpaper(extra));
17140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
17150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
17160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            default:
17170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                Log.w(LOGTAG, "We should not get here.");
17180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
17190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
1720b2b19f501ee05448ca81bddaaca70e9b2f51cb54Leon Scroggins        hideFakeTitleBar();
17210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
17220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
17230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Attach the given tab to the content view.
1724c928c30a51eee84b40cb7045842c288c1cfafff0Grace Kloba    // this should only be called for the current tab.
172522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private void attachTabToContentView(Tab t) {
17262bc69918d97a767a02132090e58718077381ba1aSteve Block        // Attach the container that contains the main WebView and any other UI
17272bc69918d97a767a02132090e58718077381ba1aSteve Block        // associated with the tab.
1728d0119535d0c490e087be114ae8fd1639bb1945dcPatrick Scott        t.attachTabToContentView(mContentView);
1729bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch
1730bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch        if (mShouldShowErrorConsole) {
173122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            ErrorConsoleView errorConsole = t.getErrorConsole(true);
1732bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch            if (errorConsole.numberOfErrors() == 0) {
1733bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch                errorConsole.showConsole(ErrorConsoleView.SHOW_NONE);
1734bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch            } else {
1735bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch                errorConsole.showConsole(ErrorConsoleView.SHOW_MINIMIZED);
1736bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch            }
1737bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch
1738bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch            mErrorConsoleContainer.addView(errorConsole,
173915b8ec6b226f4d57307716e1f495e10a91f8cbf4Romain Guy                    new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
1740bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch                                                  ViewGroup.LayoutParams.WRAP_CONTENT));
1741bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch        }
1742bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch
174339ab28eba0c8c837ac80851ec0dd2af336aa3f85Leon Scroggins        WebView view = t.getWebView();
174455a5bc2a8f3c9a0721eeaa5a45241e00d5da95efLeon Scroggins        view.setEmbeddedTitleBar(mTitleBar);
17450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Request focus on the top window.
17460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        t.getTopWindow().requestFocus();
17470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
17480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
17490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Attach a sub window to the main WebView of the given tab.
175022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void attachSubWindow(Tab t) {
1751d0119535d0c490e087be114ae8fd1639bb1945dcPatrick Scott        t.attachSubWindow(mContentView);
1752d0119535d0c490e087be114ae8fd1639bb1945dcPatrick Scott        getTopWindow().requestFocus();
17530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
17540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
17550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Remove the given tab from the content view.
175622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private void removeTabFromContentView(Tab t) {
17572bc69918d97a767a02132090e58718077381ba1aSteve Block        // Remove the container that contains the main WebView.
1758d0119535d0c490e087be114ae8fd1639bb1945dcPatrick Scott        t.removeTabFromContentView(mContentView);
1759bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch
176022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        ErrorConsoleView errorConsole = t.getErrorConsole(false);
176122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (errorConsole != null) {
176222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mErrorConsoleContainer.removeView(errorConsole);
1763bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch        }
1764bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch
176539ab28eba0c8c837ac80851ec0dd2af336aa3f85Leon Scroggins        WebView view = t.getWebView();
1766bb85b9016201d45ea939d7cb7edd0ba6616a111cLeon Scroggins        if (view != null) {
1767bb85b9016201d45ea939d7cb7edd0ba6616a111cLeon Scroggins            view.setEmbeddedTitleBar(null);
1768bb85b9016201d45ea939d7cb7edd0ba6616a111cLeon Scroggins        }
17690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
17700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
17710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Remove the sub window if it exists. Also called by TabControl when the
17720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // user clicks the 'X' to dismiss a sub window.
177322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /* package */ void dismissSubWindow(Tab t) {
1774d0119535d0c490e087be114ae8fd1639bb1945dcPatrick Scott        t.removeSubWindow(mContentView);
177522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // dismiss the subwindow. This will destroy the WebView.
177622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        t.dismissSubWindow();
1777d0119535d0c490e087be114ae8fd1639bb1945dcPatrick Scott        getTopWindow().requestFocus();
17780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
17790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
17801f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins    // A wrapper function of {@link #openTabAndShow(UrlData, boolean, String)}
178125ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima    // that accepts url as string.
178222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private Tab openTabAndShow(String url, boolean closeOnExit, String appId) {
17831f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins        return openTabAndShow(new UrlData(url), closeOnExit, appId);
17840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
17850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
17860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // This method does a ton of stuff. It will attempt to create a new tab
17870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // if we haven't reached MAX_TABS. Otherwise it uses the current tab. If
17881f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins    // url isn't null, it will load the given url.
178922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /* package */Tab openTabAndShow(UrlData urlData, boolean closeOnExit,
179022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            String appId) {
179122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        final Tab currentTab = mTabControl.getCurrentTab();
179222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mTabControl.canCreateNewTab()) {
179322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            final Tab tab = mTabControl.createNewTab(closeOnExit, appId,
179422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    urlData.mUrl);
17951f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins            WebView webview = tab.getWebView();
17960a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins            // If the last tab was removed from the active tabs page, currentTab
17970a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins            // will be null.
17980a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins            if (currentTab != null) {
17990a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins                removeTabFromContentView(currentTab);
18000a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins            }
18018bbd69f50abd537bfe7eb314b3a3e20241ac22bdPatrick Scott            // We must set the new tab as the current tab to reflect the old
18028bbd69f50abd537bfe7eb314b3a3e20241ac22bdPatrick Scott            // animation behavior.
18038bbd69f50abd537bfe7eb314b3a3e20241ac22bdPatrick Scott            mTabControl.setCurrentTab(tab);
1804eb6eef4c45df2d65c3e70660493a147a2be405e3Grace Kloba            attachTabToContentView(tab);
1805160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins            if (!urlData.isEmpty()) {
18061f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                urlData.loadIn(webview);
18070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
18081f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins            return tab;
180964b80f3efd95d7b5192731e995ccde79c4c6c11fLeon Scroggins        } else {
18101f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins            // Get rid of the subwindow if it exists
18111f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins            dismissSubWindow(currentTab);
18121f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins            if (!urlData.isEmpty()) {
18131f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                // Load the given url.
18141f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                urlData.loadIn(currentTab.getWebView());
18150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
18160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
1817c9181841c7ed6b9f7dfc953eab8dc7ba1047022cGrace Kloba        return currentTab;
18180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
18190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
182022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private Tab openTab(String url) {
18210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mSettings.openInBackground()) {
182222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            Tab t = mTabControl.createNewTab();
18230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (t != null) {
18241f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                WebView view = t.getWebView();
18251f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                view.loadUrl(url);
18260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
1827c9181841c7ed6b9f7dfc953eab8dc7ba1047022cGrace Kloba            return t;
18280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
18291f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins            return openTabAndShow(url, false, null);
18300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
18310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
18320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
18330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private class Copy implements OnMenuItemClickListener {
18340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        private CharSequence mText;
18350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
18360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public boolean onMenuItemClick(MenuItem item) {
18370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            copy(mText);
18380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return true;
18390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
18400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
18410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public Copy(CharSequence toCopy) {
18420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mText = toCopy;
18430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
18440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
18450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
18460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private class Download implements OnMenuItemClickListener {
18470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        private String mText;
18480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
18490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public boolean onMenuItemClick(MenuItem item) {
18500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            onDownloadStartNoStream(mText, null, null, null, -1);
18510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return true;
18520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
18530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
18540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public Download(String toDownload) {
18550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mText = toDownload;
18560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
18570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
18580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
18594f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch    private class SetAsWallpaper extends Thread implements
18604f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch            OnMenuItemClickListener, DialogInterface.OnCancelListener {
18614f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch        private URL mUrl;
18624f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch        private ProgressDialog mWallpaperProgress;
18634f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch        private boolean mCanceled = false;
18644f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch
18654f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch        public SetAsWallpaper(String url) {
18664f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch            try {
18674f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                mUrl = new URL(url);
18684f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch            } catch (MalformedURLException e) {
18694f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                mUrl = null;
18704f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch            }
18714f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch        }
18724f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch
18734f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch        public void onCancel(DialogInterface dialog) {
18744f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch            mCanceled = true;
18754f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch        }
18764f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch
18774f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch        public boolean onMenuItemClick(MenuItem item) {
18784f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch            if (mUrl != null) {
18794f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                // The user may have tried to set a image with a large file size as their
18804f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                // background so it may take a few moments to perform the operation. Display
18814f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                // a progress spinner while it is working.
18824f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                mWallpaperProgress = new ProgressDialog(BrowserActivity.this);
18834f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                mWallpaperProgress.setIndeterminate(true);
18844f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                mWallpaperProgress.setMessage(getText(R.string.progress_dialog_setting_wallpaper));
18854f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                mWallpaperProgress.setCancelable(true);
18864f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                mWallpaperProgress.setOnCancelListener(this);
18874f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                mWallpaperProgress.show();
18884f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                start();
18894f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch            }
18904f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch            return true;
18914f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch        }
18924f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch
18934f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch        public void run() {
18944f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch            Drawable oldWallpaper = BrowserActivity.this.getWallpaper();
18954f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch            try {
18964f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                // TODO: This will cause the resource to be downloaded again, when we
18974f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                // should in most cases be able to grab it from the cache. To fix this
18984f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                // we should query WebCore to see if we can access a cached version and
18994f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                // instead open an input stream on that. This pattern could also be used
19004f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                // in the download manager where the same problem exists.
19014f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                InputStream inputstream = mUrl.openStream();
19024f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                if (inputstream != null) {
19034f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                    setWallpaper(inputstream);
19044f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                }
19054f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch            } catch (IOException e) {
19064f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                Log.e(LOGTAG, "Unable to set new wallpaper");
19074f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                // Act as though the user canceled the operation so we try to
19084f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                // restore the old wallpaper.
19094f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                mCanceled = true;
19104f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch            }
19114f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch
19124f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch            if (mCanceled) {
19134f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                // Restore the old wallpaper if the user cancelled whilst we were setting
19144f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                // the new wallpaper.
19154f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                int width = oldWallpaper.getIntrinsicWidth();
19164f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                int height = oldWallpaper.getIntrinsicHeight();
19174f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                Bitmap bm = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);
19184f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                Canvas canvas = new Canvas(bm);
19194f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                oldWallpaper.setBounds(0, 0, width, height);
19204f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                oldWallpaper.draw(canvas);
19214f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                try {
19224f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                    setWallpaper(bm);
19234f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                } catch (IOException e) {
19244f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                    Log.e(LOGTAG, "Unable to restore old wallpaper.");
19254f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                }
19264f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                mCanceled = false;
19274f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch            }
19284f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch
19294f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch            if (mWallpaperProgress.isShowing()) {
19304f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                mWallpaperProgress.dismiss();
19314f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch            }
19324f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch        }
19334f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch    }
19344f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch
19350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void copy(CharSequence text) {
19360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        try {
19370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            IClipboard clip = IClipboard.Stub.asInterface(ServiceManager.getService("clipboard"));
19380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (clip != null) {
19390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                clip.setClipboardText(text);
19400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
19410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } catch (android.os.RemoteException e) {
19420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Log.e(LOGTAG, "Copy failed", e);
19430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
19440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
19450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
19460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
19470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Resets the browser title-view to whatever it must be
19480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * (for example, if we had a loading error)
19490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * When we have a new page, we call resetTitle, when we
19500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * have to reset the titlebar to whatever it used to be
19510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * (for example, if the user chose to stop loading), we
19520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * call resetTitleAndRevertLockIcon.
19530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
19540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /* package */ void resetTitleAndRevertLockIcon() {
195522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mTabControl.getCurrentTab().revertLockIcon();
195622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        updateLockIconToLatest();
19570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        resetTitleIconAndProgress();
19580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
19590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
19600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
19610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Reset the title, favicon, and progress.
19620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
19630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void resetTitleIconAndProgress() {
19640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebView current = mTabControl.getCurrentWebView();
19650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (current == null) {
19660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
19670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
19680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        resetTitleAndIcon(current);
19690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        int progress = current.getProgress();
197022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        current.getWebChromeClient().onProgressChanged(current, progress);
19710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
19720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
19730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Reset the title and the icon based on the given item.
19740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void resetTitleAndIcon(WebView view) {
19750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebHistoryItem item = view.copyBackForwardList().getCurrentItem();
19760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (item != null) {
197768579393973f745fc65a2781061af9bb8f2d7020Leon Scroggins            setUrlTitle(item.getUrl(), item.getTitle());
19780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            setFavicon(item.getFavicon());
19790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
198068579393973f745fc65a2781061af9bb8f2d7020Leon Scroggins            setUrlTitle(null, null);
19810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            setFavicon(null);
19820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
19830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
19840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
19850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
19860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Sets a title composed of the URL and the title string.
19870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param url The URL of the site being loaded.
19880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param title The title of the site being loaded.
19890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
199022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void setUrlTitle(String url, String title) {
19910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mUrl = url;
19920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mTitle = title;
19930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
199468579393973f745fc65a2781061af9bb8f2d7020Leon Scroggins        mTitleBar.setTitleAndUrl(title, url);
1995fe87bd3a3897e4bad65bb3d284659ae2f4e57570Leon Scroggins        mFakeTitleBar.setTitleAndUrl(title, url);
19960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
19970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
19980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
19990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param url The URL to build a title version of the URL from.
20000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @return The title version of the URL or null if fails.
20010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * The title version of the URL can be either the URL hostname,
20020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * or the hostname with an "https://" prefix (for secure URLs),
20030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * or an empty string if, for example, the URL in question is a
20040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * file:// URL with no hostname.
20050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
200632e14a6deccfa75490b3032bb4ddd5ae90f89de8Leon Scroggins    /* package */ static String buildTitleUrl(String url) {
20070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String titleUrl = null;
20080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
20090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (url != null) {
20100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            try {
20110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // parse the url string
20120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                URL urlObj = new URL(url);
20130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (urlObj != null) {
20140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    titleUrl = "";
20150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
20160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    String protocol = urlObj.getProtocol();
20170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    String host = urlObj.getHost();
20180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
20190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    if (host != null && 0 < host.length()) {
20200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        titleUrl = host;
20210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        if (protocol != null) {
20220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            // if a secure site, add an "https://" prefix!
20230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            if (protocol.equalsIgnoreCase("https")) {
20240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                titleUrl = protocol + "://" + host;
20250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            }
20260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }
20270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
20280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
20290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } catch (MalformedURLException e) {}
20300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
20310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
20320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return titleUrl;
20330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
20340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
20350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Set the favicon in the title bar.
203622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void setFavicon(Bitmap icon) {
203768579393973f745fc65a2781061af9bb8f2d7020Leon Scroggins        mTitleBar.setFavicon(icon);
2038fe87bd3a3897e4bad65bb3d284659ae2f4e57570Leon Scroggins        mFakeTitleBar.setFavicon(icon);
20390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
20400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
20410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
20420a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins     * Close the tab, remove its associated title bar, and adjust mTabControl's
20430a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins     * current tab to a valid value.
20441f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins     */
204522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /* package */ void closeTab(Tab t) {
20460a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins        int currentIndex = mTabControl.getCurrentIndex();
20470a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins        int removeIndex = mTabControl.getTabIndex(t);
20481f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins        mTabControl.removeTab(t);
20490a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins        if (currentIndex >= removeIndex && currentIndex != 0) {
20500a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins            currentIndex--;
20510a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins        }
20520a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins        mTabControl.setCurrentTab(mTabControl.getTab(currentIndex));
2053a5bf1deca120315a2643ea5b010f94d853461b15Andrei Popescu        resetTitleIconAndProgress();
20540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
20550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
20560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void goBackOnePageOrQuit() {
205722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        Tab current = mTabControl.getCurrentTab();
20580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (current == null) {
20590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            /*
20600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project             * Instead of finishing the activity, simply push this to the back
20610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project             * of the stack and let ActivityManager to choose the foreground
20620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project             * activity. As BrowserActivity is singleTask, it will be always the
20630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project             * root of the task. So we can use either true or false for
20640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project             * moveTaskToBack().
20650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project             */
20660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            moveTaskToBack(true);
206700d85e74921459b34e70eb93368245b4c0a9bf5fGrace Kloba            return;
20680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
20690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebView w = current.getWebView();
20700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (w.canGoBack()) {
20710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            w.goBack();
20720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
20730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Check to see if we are closing a window that was created by
20740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // another window. If so, we switch back to that window.
207522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            Tab parent = current.getParentTab();
20760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (parent != null) {
20771f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                switchToTab(mTabControl.getTabIndex(parent));
20781f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                // Now we close the other tab
20791f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                closeTab(current);
20800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } else {
20810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (current.closeOnExit()) {
208222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    // force the tab's inLoad() to be false as we are going to
208322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    // either finish the activity or remove the tab. This will
208422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    // ensure pauseWebViewTimers() taking action.
208522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    mTabControl.getCurrentTab().clearInLoad();
20860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    if (mTabControl.getTabCount() == 1) {
20870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        finish();
20880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        return;
20890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
20907bfa63b55644fbf2da1fe6a24b3be0267529202cMike Reed                    // call pauseWebViewTimers() now, we won't be able to call
20917bfa63b55644fbf2da1fe6a24b3be0267529202cMike Reed                    // it in onPause() as the WebView won't be valid.
2092ec1b5ad8d8283b1fbbc5d7fa1cd50ef95b9e594dGrace Kloba                    // Temporarily change mActivityInPause to be true as
2093ec1b5ad8d8283b1fbbc5d7fa1cd50ef95b9e594dGrace Kloba                    // pauseWebViewTimers() will do nothing if mActivityInPause
2094ec1b5ad8d8283b1fbbc5d7fa1cd50ef95b9e594dGrace Kloba                    // is false.
2095918e1d78b2db6ef21c71a07868572d9cda498476Grace Kloba                    boolean savedState = mActivityInPause;
2096918e1d78b2db6ef21c71a07868572d9cda498476Grace Kloba                    if (savedState) {
2097ec1b5ad8d8283b1fbbc5d7fa1cd50ef95b9e594dGrace Kloba                        Log.e(LOGTAG, "BrowserActivity is already paused "
2098ec1b5ad8d8283b1fbbc5d7fa1cd50ef95b9e594dGrace Kloba                                + "while handing goBackOnePageOrQuit.");
2099918e1d78b2db6ef21c71a07868572d9cda498476Grace Kloba                    }
2100918e1d78b2db6ef21c71a07868572d9cda498476Grace Kloba                    mActivityInPause = true;
21017bfa63b55644fbf2da1fe6a24b3be0267529202cMike Reed                    pauseWebViewTimers();
2102918e1d78b2db6ef21c71a07868572d9cda498476Grace Kloba                    mActivityInPause = savedState;
21030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    removeTabFromContentView(current);
21040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    mTabControl.removeTab(current);
21050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
21060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                /*
21070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                 * Instead of finishing the activity, simply push this to the back
21080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                 * of the stack and let ActivityManager to choose the foreground
21090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                 * activity. As BrowserActivity is singleTask, it will be always the
21100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                 * root of the task. So we can use either true or false for
21110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                 * moveTaskToBack().
21120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                 */
21130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                moveTaskToBack(true);
21140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
21150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
21160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
21170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
211822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    boolean isMenuDown() {
211922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return mMenuIsDown;
212022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
212122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
21225942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba    @Override
21235942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba    public boolean onKeyDown(int keyCode, KeyEvent event) {
2124f65b50ddd2f7ed1205002d74082fff1ac2336d5cLeon Scroggins        // Even if MENU is already held down, we need to call to super to open
2125f65b50ddd2f7ed1205002d74082fff1ac2336d5cLeon Scroggins        // the IME on long press.
2126f65b50ddd2f7ed1205002d74082fff1ac2336d5cLeon Scroggins        if (KeyEvent.KEYCODE_MENU == keyCode) {
2127f65b50ddd2f7ed1205002d74082fff1ac2336d5cLeon Scroggins            mMenuIsDown = true;
2128f65b50ddd2f7ed1205002d74082fff1ac2336d5cLeon Scroggins            return super.onKeyDown(keyCode, event);
2129f65b50ddd2f7ed1205002d74082fff1ac2336d5cLeon Scroggins        }
21305942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba        // The default key mode is DEFAULT_KEYS_SEARCH_LOCAL. As the MENU is
21315942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba        // still down, we don't want to trigger the search. Pretend to consume
21325942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba        // the key and do nothing.
21335942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba        if (mMenuIsDown) return true;
21345942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba
21355942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba        switch(keyCode) {
21365942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba            case KeyEvent.KEYCODE_SPACE:
2137da0fe556a00773ce2af25eb6dcc5442bd08c7addGrace Kloba                // WebView/WebTextView handle the keys in the KeyDown. As
2138da0fe556a00773ce2af25eb6dcc5442bd08c7addGrace Kloba                // the Activity's shortcut keys are only handled when WebView
2139da0fe556a00773ce2af25eb6dcc5442bd08c7addGrace Kloba                // doesn't, have to do it in onKeyDown instead of onKeyUp.
2140da0fe556a00773ce2af25eb6dcc5442bd08c7addGrace Kloba                if (event.isShiftPressed()) {
2141da0fe556a00773ce2af25eb6dcc5442bd08c7addGrace Kloba                    getTopWindow().pageUp(false);
2142da0fe556a00773ce2af25eb6dcc5442bd08c7addGrace Kloba                } else {
2143da0fe556a00773ce2af25eb6dcc5442bd08c7addGrace Kloba                    getTopWindow().pageDown(false);
2144da0fe556a00773ce2af25eb6dcc5442bd08c7addGrace Kloba                }
21455942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                return true;
21465942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba            case KeyEvent.KEYCODE_BACK:
21475942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                if (event.getRepeatCount() == 0) {
21485942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                    event.startTracking();
21495942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                    return true;
21505942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                } else if (mCustomView == null && mActiveTabsPage == null
21515942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                        && event.isLongPress()) {
21525942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                    bookmarksOrHistoryPicker(true);
21535942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                    return true;
21540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
21555942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                break;
21560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
21575942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba        return super.onKeyDown(keyCode, event);
21580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
21590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
21605942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba    @Override
21615942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba    public boolean onKeyUp(int keyCode, KeyEvent event) {
21625942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba        switch(keyCode) {
21635942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba            case KeyEvent.KEYCODE_MENU:
21645942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                mMenuIsDown = false;
21655942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                break;
21665942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba            case KeyEvent.KEYCODE_BACK:
21675942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                if (event.isTracking() && !event.isCanceled()) {
21685942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                    if (mCustomView != null) {
21695942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                        // if a custom view is showing, hide it
217022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        mTabControl.getCurrentWebView().getWebChromeClient()
217122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                .onHideCustomView();
21725942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                    } else if (mActiveTabsPage != null) {
21735942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                        // if tab page is showing, hide it
21745942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                        removeActiveTabPage(true);
21750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    } else {
21765942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                        WebView subwindow = mTabControl.getCurrentSubWindow();
21775942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                        if (subwindow != null) {
21785942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                            if (subwindow.canGoBack()) {
21795942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                                subwindow.goBack();
21805942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                            } else {
21815942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                                dismissSubWindow(mTabControl.getCurrentTab());
21825942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                            }
21835942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                        } else {
21845942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                            goBackOnePageOrQuit();
21855942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                        }
21860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
21875942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                    return true;
21885942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                }
21895942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                break;
21900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
21915942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba        return super.onKeyUp(keyCode, event);
21920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
21930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
219468579393973f745fc65a2781061af9bb8f2d7020Leon Scroggins    /* package */ void stopLoading() {
2195b7cc8b439dc595dc48e1c2183b35d23ad72dfbe5Ben Murdoch        mDidStopLoad = true;
21960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        resetTitleAndRevertLockIcon();
21970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebView w = getTopWindow();
21980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        w.stopLoading();
219922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // FIXME: before refactor, it is using mWebViewClient. So I keep the
220022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // same logic here. But for subwindow case, should we call into the main
220122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // WebView's onPageFinished as we never call its onPageStarted and if
220222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // the page finishes itself, we don't call onPageFinished.
220322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mTabControl.getCurrentWebView().getWebViewClient().onPageFinished(w,
220422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                w.getUrl());
22050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
22060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        cancelStopToast();
22070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mStopToast = Toast
22080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .makeText(this, R.string.stopping, Toast.LENGTH_SHORT);
22090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mStopToast.show();
22100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
22110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
221222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    boolean didUserStopLoading() {
221322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return mDidStopLoad;
221422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
221522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
22160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void cancelStopToast() {
22170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mStopToast != null) {
22180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mStopToast.cancel();
22190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mStopToast = null;
22200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
22210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
22220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
222322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // called by a UI or non-UI thread to post the message
222422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    public void postMessage(int what, int arg1, int arg2, Object obj,
222522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            long delayMillis) {
222622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mHandler.sendMessageDelayed(mHandler.obtainMessage(what, arg1, arg2,
222722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                obj), delayMillis);
222822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
222922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
223022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // called by a UI or non-UI thread to remove the message
223122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void removeMessages(int what, Object object) {
223222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mHandler.removeMessages(what, object);
22330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
22340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
22350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // public message ids
22360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public final static int LOAD_URL                = 1001;
22370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public final static int STOP_LOAD               = 1002;
22380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
22390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Message Ids
22400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private static final int FOCUS_NODE_HREF         = 102;
22410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private static final int CANCEL_CREDS_REQUEST    = 103;
224292c18a52ca7a79c114028b5ba22c3dfe443bd1a4Grace Kloba    private static final int RELEASE_WAKELOCK        = 107;
22430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
224422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    static final int UPDATE_BOOKMARK_THUMBNAIL       = 108;
22452694e23a55d5ca526fc29534a80a200e2c58698bBen Murdoch
22460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Private handler for handling javascript and saving passwords
22470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private Handler mHandler = new Handler() {
22480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
22490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public void handleMessage(Message msg) {
22500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            switch (msg.what) {
22510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                case FOCUS_NODE_HREF:
22522694e23a55d5ca526fc29534a80a200e2c58698bBen Murdoch                {
22530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    String url = (String) msg.getData().get("url");
225490d088caeee718f89755ee9c25249ba6da15ab97Ben Murdoch                    String title = (String) msg.getData().get("title");
22550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    if (url == null || url.length() == 0) {
22560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        break;
22570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
22580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    HashMap focusNodeMap = (HashMap) msg.obj;
22590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    WebView view = (WebView) focusNodeMap.get("webview");
22600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // Only apply the action if the top window did not change.
22610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    if (getTopWindow() != view) {
22620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        break;
22630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
22640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    switch (msg.arg1) {
22650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        case R.id.open_context_menu_id:
22660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        case R.id.view_image_context_menu_id:
22670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            loadURL(getTopWindow(), url);
22680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            break;
22690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        case R.id.open_newtab_context_menu_id:
227022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            final Tab parent = mTabControl.getCurrentTab();
227122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            final Tab newTab = openTab(url);
2272c9181841c7ed6b9f7dfc953eab8dc7ba1047022cGrace Kloba                            if (newTab != parent) {
2273c9181841c7ed6b9f7dfc953eab8dc7ba1047022cGrace Kloba                                parent.addChildTab(newTab);
2274c9181841c7ed6b9f7dfc953eab8dc7ba1047022cGrace Kloba                            }
22750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            break;
22760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        case R.id.bookmark_context_menu_id:
22770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            Intent intent = new Intent(BrowserActivity.this,
22780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    AddBookmarkPage.class);
22790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            intent.putExtra("url", url);
228090d088caeee718f89755ee9c25249ba6da15ab97Ben Murdoch                            intent.putExtra("title", title);
22810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            startActivity(intent);
22820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            break;
22830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        case R.id.share_link_context_menu_id:
228496afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                            // See if this site has been visited before
228596afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                            StringBuilder sb = new StringBuilder(
228696afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                                    Browser.BookmarkColumns.URL + " = ");
228796afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                            DatabaseUtils.appendEscapedSQLString(sb, url);
228896afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                            Cursor c = mResolver.query(Browser.BOOKMARKS_URI,
228996afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                                    Browser.HISTORY_PROJECTION,
229096afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                                    sb.toString(),
229196afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                                    null,
229296afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                                    null);
229396afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                            if (c.moveToFirst()) {
229496afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                                // The site has been visited before, so grab the
229596afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                                // info from the database.
229696afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                                Bitmap favicon = null;
229796afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                                Bitmap thumbnail = null;
229896afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                                String linkTitle = c.getString(Browser.
229996afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                                        HISTORY_PROJECTION_TITLE_INDEX);
230096afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                                byte[] data = c.getBlob(Browser.
230196afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                                        HISTORY_PROJECTION_FAVICON_INDEX);
230296afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                                if (data != null) {
230396afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                                    favicon = BitmapFactory.decodeByteArray(
230496afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                                            data, 0, data.length);
230596afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                                }
230696afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                                data = c.getBlob(Browser.
230796afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                                        HISTORY_PROJECTION_THUMBNAIL_INDEX);
230896afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                                if (data != null) {
230996afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                                    thumbnail = BitmapFactory.decodeByteArray(
231096afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                                            data, 0, data.length);
231196afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                                }
231296afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                                sharePage(BrowserActivity.this,
231396afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                                        linkTitle, url, favicon, thumbnail);
231496afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                            } else {
231596afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                                Browser.sendString(BrowserActivity.this, url,
231696afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                                        getString(
231796afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                                        R.string.choosertitle_sharevia));
231896afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                            }
23190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            break;
23200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        case R.id.copy_link_context_menu_id:
23210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            copy(url);
23220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            break;
23230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        case R.id.save_link_context_menu_id:
23240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        case R.id.download_context_menu_id:
23250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            onDownloadStartNoStream(url, null, null, null, -1);
23260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            break;
23270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
23280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    break;
23292694e23a55d5ca526fc29534a80a200e2c58698bBen Murdoch                }
23300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
23310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                case LOAD_URL:
23320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    loadURL(getTopWindow(), (String) msg.obj);
23330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    break;
23340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
23350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                case STOP_LOAD:
23360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    stopLoading();
23370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    break;
23380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
23390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                case CANCEL_CREDS_REQUEST:
23400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    resumeAfterCredentials();
23410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    break;
23420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
23430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                case RELEASE_WAKELOCK:
23440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    if (mWakeLock.isHeld()) {
23450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        mWakeLock.release();
23465d0e02e646e46b14289168f75c2a8f6ed43cac54Grace Kloba                        // if we reach here, Browser should be still in the
23475d0e02e646e46b14289168f75c2a8f6ed43cac54Grace Kloba                        // background loading after WAKELOCK_TIMEOUT (5-min).
23485d0e02e646e46b14289168f75c2a8f6ed43cac54Grace Kloba                        // To avoid burning the battery, stop loading.
23495d0e02e646e46b14289168f75c2a8f6ed43cac54Grace Kloba                        mTabControl.stopAllLoading();
23500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
23510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    break;
23522694e23a55d5ca526fc29534a80a200e2c58698bBen Murdoch
23532694e23a55d5ca526fc29534a80a200e2c58698bBen Murdoch                case UPDATE_BOOKMARK_THUMBNAIL:
23542694e23a55d5ca526fc29534a80a200e2c58698bBen Murdoch                    WebView view = (WebView) msg.obj;
23552694e23a55d5ca526fc29534a80a200e2c58698bBen Murdoch                    if (view != null) {
23562694e23a55d5ca526fc29534a80a200e2c58698bBen Murdoch                        updateScreenshot(view);
23572694e23a55d5ca526fc29534a80a200e2c58698bBen Murdoch                    }
23582694e23a55d5ca526fc29534a80a200e2c58698bBen Murdoch                    break;
23590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
23600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
23610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    };
23620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
236396afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins    /**
236496afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins     * Share a page, providing the title, url, favicon, and a screenshot.  Uses
236596afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins     * an {@link Intent} to launch the Activity chooser.
236696afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins     * @param c Context used to launch a new Activity.
236796afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins     * @param title Title of the page.  Stored in the Intent with
236896afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins     *          {@link Browser#EXTRA_SHARE_TITLE}
236996afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins     * @param url URL of the page.  Stored in the Intent with
237096afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins     *          {@link Intent#EXTRA_TEXT}
237196afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins     * @param favicon Bitmap of the favicon for the page.  Stored in the Intent
237296afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins     *          with {@link Browser#EXTRA_SHARE_FAVICON}
237396afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins     * @param screenshot Bitmap of a screenshot of the page.  Stored in the
237496afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins     *          Intent with {@link Browser#EXTRA_SHARE_SCREENSHOT}
237596afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins     */
237696afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins    public static final void sharePage(Context c, String title, String url,
237796afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins            Bitmap favicon, Bitmap screenshot) {
237896afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins        Intent send = new Intent(Intent.ACTION_SEND);
237996afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins        send.setType("text/plain");
238096afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins        send.putExtra(Intent.EXTRA_TEXT, url);
238196afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins        send.putExtra(Browser.EXTRA_SHARE_TITLE, title);
238296afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins        send.putExtra(Browser.EXTRA_SHARE_FAVICON, favicon);
238396afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins        send.putExtra(Browser.EXTRA_SHARE_SCREENSHOT, screenshot);
238496afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins        try {
238596afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins            c.startActivity(Intent.createChooser(send, c.getString(
238696afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                    R.string.choosertitle_sharevia)));
238796afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins        } catch(android.content.ActivityNotFoundException ex) {
238896afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins            // if no app handles it, do nothing
238996afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins        }
239096afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins    }
239196afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins
239289c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins    private void updateScreenshot(WebView view) {
239389c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins        // If this is a bookmarked site, add a screenshot to the database.
239489c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins        // FIXME: When should we update?  Every time?
239589c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins        // FIXME: Would like to make sure there is actually something to
239689c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins        // draw, but the API for that (WebViewCore.pictureReady()) is not
239789c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins        // currently accessible here.
2398aac7aa6fcfcb519755987ec126be066323f589c8Ben Murdoch
23993918d4443ff38ef1870e02aa51a8b29f8352bb1aPatrick Scott        ContentResolver cr = getContentResolver();
24003918d4443ff38ef1870e02aa51a8b29f8352bb1aPatrick Scott        final Cursor c = BrowserBookmarksAdapter.queryBookmarksForUrl(
2401aac7aa6fcfcb519755987ec126be066323f589c8Ben Murdoch                cr, view.getOriginalUrl(), view.getUrl(), true);
24023918d4443ff38ef1870e02aa51a8b29f8352bb1aPatrick Scott        if (c != null) {
240389c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins            boolean succeed = c.moveToFirst();
240489c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins            ContentValues values = null;
240589c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins            while (succeed) {
240689c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins                if (values == null) {
240789c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins                    final ByteArrayOutputStream os
240889c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins                            = new ByteArrayOutputStream();
2409dcc2b6f08dd5677bc6ba761a9ba6f1c655113051Ben Murdoch                    Bitmap bm = createScreenshot(view);
24104580057e772b60433272af5cd691825748892693Leon Scroggins                    if (bm == null) {
24114580057e772b60433272af5cd691825748892693Leon Scroggins                        c.close();
24124580057e772b60433272af5cd691825748892693Leon Scroggins                        return;
24134580057e772b60433272af5cd691825748892693Leon Scroggins                    }
241489c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins                    bm.compress(Bitmap.CompressFormat.PNG, 100, os);
241589c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins                    values = new ContentValues();
241689c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins                    values.put(Browser.BookmarkColumns.THUMBNAIL,
241789c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins                            os.toByteArray());
241889c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins                }
241989c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins                cr.update(ContentUris.withAppendedId(Browser.BOOKMARKS_URI,
242089c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins                        c.getInt(0)), values, null, null);
242189c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins                succeed = c.moveToNext();
242289c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins            }
242389c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins            c.close();
242489c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins        }
242589c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins    }
242689c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins
242706ec5f2d8735d1ba17b779deb0f8da032e0a62eaLeon Scroggins    /**
2428f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins     * Values for the size of the thumbnail created when taking a screenshot.
2429f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins     * Lazily initialized.  Instead of using these directly, use
2430f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins     * getDesiredThumbnailWidth() or getDesiredThumbnailHeight().
243106ec5f2d8735d1ba17b779deb0f8da032e0a62eaLeon Scroggins     */
2432f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins    private static int THUMBNAIL_WIDTH = 0;
2433f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins    private static int THUMBNAIL_HEIGHT = 0;
2434f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins
2435f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins    /**
2436f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins     * Return the desired width for thumbnail screenshots, which are stored in
2437f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins     * the database, and used on the bookmarks screen.
2438f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins     * @param context Context for finding out the density of the screen.
2439f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins     * @return int desired width for thumbnail screenshot.
2440f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins     */
2441f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins    /* package */ static int getDesiredThumbnailWidth(Context context) {
2442f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins        if (THUMBNAIL_WIDTH == 0) {
2443f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins            float density = context.getResources().getDisplayMetrics().density;
2444f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins            THUMBNAIL_WIDTH = (int) (90 * density);
2445f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins            THUMBNAIL_HEIGHT = (int) (80 * density);
2446f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins        }
2447f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins        return THUMBNAIL_WIDTH;
2448f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins    }
2449f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins
2450f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins    /**
2451f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins     * Return the desired height for thumbnail screenshots, which are stored in
2452f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins     * the database, and used on the bookmarks screen.
2453f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins     * @param context Context for finding out the density of the screen.
2454f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins     * @return int desired height for thumbnail screenshot.
2455f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins     */
2456f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins    /* package */ static int getDesiredThumbnailHeight(Context context) {
2457f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins        // To ensure that they are both initialized.
2458f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins        getDesiredThumbnailWidth(context);
2459f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins        return THUMBNAIL_HEIGHT;
2460f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins    }
246106ec5f2d8735d1ba17b779deb0f8da032e0a62eaLeon Scroggins
2462dcc2b6f08dd5677bc6ba761a9ba6f1c655113051Ben Murdoch    private Bitmap createScreenshot(WebView view) {
2463dcc2b6f08dd5677bc6ba761a9ba6f1c655113051Ben Murdoch        Picture thumbnail = view.capturePicture();
24644580057e772b60433272af5cd691825748892693Leon Scroggins        if (thumbnail == null) {
24654580057e772b60433272af5cd691825748892693Leon Scroggins            return null;
24664580057e772b60433272af5cd691825748892693Leon Scroggins        }
2467f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins        Bitmap bm = Bitmap.createBitmap(getDesiredThumbnailWidth(this),
2468f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins                getDesiredThumbnailHeight(this), Bitmap.Config.ARGB_4444);
2469dcc2b6f08dd5677bc6ba761a9ba6f1c655113051Ben Murdoch        Canvas canvas = new Canvas(bm);
2470dcc2b6f08dd5677bc6ba761a9ba6f1c655113051Ben Murdoch        // May need to tweak these values to determine what is the
2471dcc2b6f08dd5677bc6ba761a9ba6f1c655113051Ben Murdoch        // best scale factor
24722694e23a55d5ca526fc29534a80a200e2c58698bBen Murdoch        int thumbnailWidth = thumbnail.getWidth();
2473ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch        int thumbnailHeight = thumbnail.getHeight();
2474ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch        float scaleFactorX = 1.0f;
2475ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch        float scaleFactorY = 1.0f;
24762694e23a55d5ca526fc29534a80a200e2c58698bBen Murdoch        if (thumbnailWidth > 0) {
2477ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch            scaleFactorX = (float) getDesiredThumbnailWidth(this) /
24782694e23a55d5ca526fc29534a80a200e2c58698bBen Murdoch                    (float)thumbnailWidth;
2479ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch        } else {
2480ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch            return null;
248106ec5f2d8735d1ba17b779deb0f8da032e0a62eaLeon Scroggins        }
2482ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch
2483ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch        if (view.getWidth() > view.getHeight() &&
2484ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch                thumbnailHeight < view.getHeight() && thumbnailHeight > 0) {
2485ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch            // If the device is in landscape and the page is shorter
2486ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch            // than the height of the view, stretch the thumbnail to fill the
2487ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch            // space.
2488ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch            scaleFactorY = (float) getDesiredThumbnailHeight(this) /
2489ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch                    (float)thumbnailHeight;
2490ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch        } else {
2491ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch            // In the portrait case, this looks nice.
2492ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch            scaleFactorY = scaleFactorX;
2493ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch        }
2494ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch
2495ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch        canvas.scale(scaleFactorX, scaleFactorY);
2496ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch
2497dcc2b6f08dd5677bc6ba761a9ba6f1c655113051Ben Murdoch        thumbnail.draw(canvas);
2498dcc2b6f08dd5677bc6ba761a9ba6f1c655113051Ben Murdoch        return bm;
2499dcc2b6f08dd5677bc6ba761a9ba6f1c655113051Ben Murdoch    }
2500dcc2b6f08dd5677bc6ba761a9ba6f1c655113051Ben Murdoch
25010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // -------------------------------------------------------------------------
250222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // Helper function for WebViewClient.
25030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    //-------------------------------------------------------------------------
25040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
25050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Use in overrideUrlLoading
25060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /* package */ final static String SCHEME_WTAI = "wtai://wp/";
25070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /* package */ final static String SCHEME_WTAI_MC = "wtai://wp/mc;";
25080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /* package */ final static String SCHEME_WTAI_SD = "wtai://wp/sd;";
25090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /* package */ final static String SCHEME_WTAI_AP = "wtai://wp/ap;";
25100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
251122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void onPageStarted(WebView view, String url, Bitmap favicon) {
251222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // when BrowserActivity just starts, onPageStarted may be called before
251322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // onResume as it is triggered from onCreate. Call resumeWebViewTimers
251422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // to start the timer. As we won't switch tabs while an activity is in
251522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // pause state, we can ensure calling resume and pause in pair.
251622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mActivityInPause) resumeWebViewTimers();
251722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
251822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        resetLockIcon(url);
251922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        setUrlTitle(url, null);
252022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        setFavicon(favicon);
25218cf8f682e90f004d4b8028d2f5b74f72c0cf4e19Leon Scroggins        // Keep this initial progress in sync with initialProgressValue (* 100)
25228cf8f682e90f004d4b8028d2f5b74f72c0cf4e19Leon Scroggins        // in ProgressTracker.cpp
25238cf8f682e90f004d4b8028d2f5b74f72c0cf4e19Leon Scroggins        // Show some progress so that the user knows the page is beginning to
25248cf8f682e90f004d4b8028d2f5b74f72c0cf4e19Leon Scroggins        // load
25258cf8f682e90f004d4b8028d2f5b74f72c0cf4e19Leon Scroggins        onProgressChanged(view, 10);
252622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mDidStopLoad = false;
252722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (!mIsNetworkUp) createAndShowNetworkDialog();
25280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
252922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mSettings.isTracing()) {
253022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            String host;
253122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            try {
253222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                WebAddress uri = new WebAddress(url);
253322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                host = uri.mHost;
253422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            } catch (android.net.ParseException ex) {
253522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                host = "browser";
253622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
253722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            host = host.replace('.', '_');
253822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            host += ".trace";
253922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mInTrace = true;
254022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            Debug.startMethodTracing(host, 20 * 1024 * 1024);
254115525d48024d325c8a52766d8ca727191251a8d4Patrick Scott        }
254215525d48024d325c8a52766d8ca727191251a8d4Patrick Scott
254322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Performance probe
254422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (false) {
254522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mStart = SystemClock.uptimeMillis();
254622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mProcessStart = Process.getElapsedCpuTime();
254722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            long[] sysCpu = new long[7];
254822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (Process.readProcFile("/proc/stat", SYSTEM_CPU_FORMAT, null,
254922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    sysCpu, null)) {
255022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                mUserStart = sysCpu[0] + sysCpu[1];
255122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                mSystemStart = sysCpu[2];
255222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                mIdleStart = sysCpu[3];
255322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                mIrqStart = sysCpu[4] + sysCpu[5] + sysCpu[6];
255422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
255522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mUiStart = SystemClock.currentThreadTimeMillis();
25560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
25570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
25580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
255922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void onPageFinished(WebView view, String url) {
256022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Reset the title and icon in case we stopped a provisional load.
256122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        resetTitleAndIcon(view);
256222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Update the lock icon image only once we are done loading
256322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        updateLockIconToLatest();
256422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // pause the WebView timer and release the wake lock if it is finished
256522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // while BrowserActivity is in pause state.
256622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mActivityInPause && pauseWebViewTimers()) {
256722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (mWakeLock.isHeld()) {
256822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                mHandler.removeMessages(RELEASE_WAKELOCK);
256922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                mWakeLock.release();
257022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
257122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
257222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
257322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Performance probe
257422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (false) {
257522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            long[] sysCpu = new long[7];
257622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (Process.readProcFile("/proc/stat", SYSTEM_CPU_FORMAT, null,
257722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    sysCpu, null)) {
257822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                String uiInfo = "UI thread used "
257922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        + (SystemClock.currentThreadTimeMillis() - mUiStart)
258022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        + " ms";
258122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                if (LOGD_ENABLED) {
258222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    Log.d(LOGTAG, uiInfo);
258322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                }
258422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                //The string that gets written to the log
258522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                String performanceString = "It took total "
258622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        + (SystemClock.uptimeMillis() - mStart)
258722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        + " ms clock time to load the page."
258822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        + "\nbrowser process used "
258922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        + (Process.getElapsedCpuTime() - mProcessStart)
259022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        + " ms, user processes used "
259122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        + (sysCpu[0] + sysCpu[1] - mUserStart) * 10
259222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        + " ms, kernel used "
259322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        + (sysCpu[2] - mSystemStart) * 10
259422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        + " ms, idle took " + (sysCpu[3] - mIdleStart) * 10
259522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        + " ms and irq took "
259622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        + (sysCpu[4] + sysCpu[5] + sysCpu[6] - mIrqStart)
259722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        * 10 + " ms, " + uiInfo;
259822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                if (LOGD_ENABLED) {
259922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    Log.d(LOGTAG, performanceString + "\nWebpage: " + url);
26000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
260122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                if (url != null) {
260222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    // strip the url to maintain consistency
260322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    String newUrl = new String(url);
260422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    if (newUrl.startsWith("http://www.")) {
260522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        newUrl = newUrl.substring(11);
260622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    } else if (newUrl.startsWith("http://")) {
260722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        newUrl = newUrl.substring(7);
260822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    } else if (newUrl.startsWith("https://www.")) {
260922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        newUrl = newUrl.substring(12);
261022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    } else if (newUrl.startsWith("https://")) {
261122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        newUrl = newUrl.substring(8);
26120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
261331a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort                    if (LOGD_ENABLED) {
261422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        Log.d(LOGTAG, newUrl + " loaded");
26150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
26160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
26170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
261822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         }
26190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
262022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mInTrace) {
262122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mInTrace = false;
262222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            Debug.stopMethodTracing();
26230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
262422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
26250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
262622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    boolean shouldOverrideUrlLoading(WebView view, String url) {
262722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (url.startsWith(SCHEME_WTAI)) {
262822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // wtai://wp/mc;number
262922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // number=string(phone-number)
263022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (url.startsWith(SCHEME_WTAI_MC)) {
263122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                Intent intent = new Intent(Intent.ACTION_VIEW,
263222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        Uri.parse(WebView.SCHEME_TEL +
263322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        url.substring(SCHEME_WTAI_MC.length())));
263422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                startActivity(intent);
263522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                return true;
26360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
263722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // wtai://wp/sd;dtmf
263822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // dtmf=string(dialstring)
263922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (url.startsWith(SCHEME_WTAI_SD)) {
264022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                // TODO: only send when there is active voice connection
26419918943559193e3e047a1c18442e2cdb0fe22b15Dianne Hackborn                return false;
26429918943559193e3e047a1c18442e2cdb0fe22b15Dianne Hackborn            }
264322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // wtai://wp/ap;number;name
264422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // number=string(phone-number)
264522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // name=string
264622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (url.startsWith(SCHEME_WTAI_AP)) {
264722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                // TODO
26480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                return false;
26490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
26500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
26510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
265222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // The "about:" schemes are internal to the browser; don't want these to
265322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // be dispatched to other apps.
265422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (url.startsWith("about:")) {
265522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            return false;
26560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
26570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
265822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        Intent intent;
265922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // perform generic parsing of the URI to turn it into an Intent.
266022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        try {
266122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            intent = Intent.parseUri(url, Intent.URI_INTENT_SCHEME);
266222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        } catch (URISyntaxException ex) {
266322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            Log.w("Browser", "Bad URI " + url + ": " + ex.getMessage());
266422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            return false;
26650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
26660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
266722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // check whether the intent can be resolved. If not, we will see
266822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // whether we can download it from the Market.
266922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (getPackageManager().resolveActivity(intent, 0) == null) {
267022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            String packagename = intent.getPackage();
267122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (packagename != null) {
267222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                intent = new Intent(Intent.ACTION_VIEW, Uri
267322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        .parse("market://search?q=pname:" + packagename));
267422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                intent.addCategory(Intent.CATEGORY_BROWSABLE);
267522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                startActivity(intent);
267622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                return true;
26770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } else {
26780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                return false;
26790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
26800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
26810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
268222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // sanitize the Intent, ensuring web pages can not bypass browser
268322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // security (only access to BROWSABLE activities).
268422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        intent.addCategory(Intent.CATEGORY_BROWSABLE);
268522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        intent.setComponent(null);
268622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        try {
268722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (startActivityIfNeeded(intent, -1)) {
26880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                return true;
26890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
269022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        } catch (ActivityNotFoundException ex) {
269122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // ignore the error. If no application can handle the URL,
269222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // eg about:blank, assume the browser can handle it.
269322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
26940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
269522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mMenuIsDown) {
269622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            openTab(url);
269722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            closeOptionsMenu();
26980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return true;
26990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
270022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return false;
270122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
27020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
270322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // -------------------------------------------------------------------------
270422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // Helper function for WebChromeClient
270522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // -------------------------------------------------------------------------
27060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
270722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void onProgressChanged(WebView view, int newProgress) {
270822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mTitleBar.setProgress(newProgress);
270922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mFakeTitleBar.setProgress(newProgress);
271022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
271122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (newProgress == 100) {
271222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // onProgressChanged() may continue to be called after the main
271322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // frame has finished loading, as any remaining sub frames continue
271422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // to load. We'll only get called once though with newProgress as
271522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // 100 when everything is loaded. (onPageFinished is called once
271622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // when the main frame completes loading regardless of the state of
271722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // any sub frames so calls to onProgressChanges may continue after
271822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // onPageFinished has executed)
271922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (mInLoad) {
272022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                mInLoad = false;
2721a27ff19e24cb1c9fef5624dbc4554548349b5b31Leon Scroggins                updateInLoadMenuItems();
272222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                // If the options menu is open, leave the title bar
272322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                if (!mOptionsMenuOpen || !mIconView) {
272422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    hideFakeTitleBar();
27250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
27260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
272722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        } else if (!mInLoad) {
272822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // onPageFinished may have already been called but a subframe is
272922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // still loading and updating the progress. Reset mInLoad and update
273022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // the menu items.
273122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mInLoad = true;
273222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            updateInLoadMenuItems();
273322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (!mOptionsMenuOpen || mIconView) {
273422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                // This page has begun to load, so show the title bar
273522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                showFakeTitleBar();
27363918d4443ff38ef1870e02aa51a8b29f8352bb1aPatrick Scott            }
27370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
273822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
2739092dd5d22d7f2ee0efcc68bd6e5a3afd1ea98953Ben Murdoch
274022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void onShowCustomView(View view, WebChromeClient.CustomViewCallback callback) {
27418ff57db0a8dc8eb659fbcdcd4a856208609e6070Derek Sollenberger        // if a view already exists then immediately terminate the new one
27428ff57db0a8dc8eb659fbcdcd4a856208609e6070Derek Sollenberger        if (mCustomView != null) {
27438ff57db0a8dc8eb659fbcdcd4a856208609e6070Derek Sollenberger            callback.onCustomViewHidden();
274422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            return;
27458ff57db0a8dc8eb659fbcdcd4a856208609e6070Derek Sollenberger        }
27462bc69918d97a767a02132090e58718077381ba1aSteve Block
274722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Add the custom view to its container.
274822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mCustomViewContainer.addView(view, COVER_SCREEN_GRAVITY_CENTER);
274922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mCustomView = view;
275022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mCustomViewCallback = callback;
275122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Save the menu state and set it to empty while the custom
275222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // view is showing.
275322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mOldMenuState = mMenuState;
275422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mMenuState = EMPTY_MENU;
275522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Hide the content view.
275622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mContentView.setVisibility(View.GONE);
275722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Finally show the custom view container.
2758163ab74e2f85b53a1a374c49677073fb64d35f28Andrei Popescu        setStatusBarVisibility(false);
275922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mCustomViewContainer.setVisibility(View.VISIBLE);
276022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mCustomViewContainer.bringToFront();
276122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
276222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
276322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void onHideCustomView() {
276422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mCustomView == null)
276522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            return;
27662bc69918d97a767a02132090e58718077381ba1aSteve Block
276722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Hide the custom view.
276822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mCustomView.setVisibility(View.GONE);
276922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Remove the custom view from its container.
277022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mCustomViewContainer.removeView(mCustomView);
277122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mCustomView = null;
277222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Reset the old menu state.
277322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mMenuState = mOldMenuState;
277422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mOldMenuState = EMPTY_MENU;
277522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mCustomViewContainer.setVisibility(View.GONE);
277622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mCustomViewCallback.onCustomViewHidden();
277722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Show the content view.
2778163ab74e2f85b53a1a374c49677073fb64d35f28Andrei Popescu        setStatusBarVisibility(true);
277922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mContentView.setVisibility(View.VISIBLE);
278022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
2781540035dfd1347c78eeec10ec0847e18fcc50ef36Andrei Popescu
278222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    Bitmap getDefaultVideoPoster() {
278322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mDefaultVideoPoster == null) {
278422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mDefaultVideoPoster = BitmapFactory.decodeResource(
278522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    getResources(), R.drawable.default_video_poster);
2786540035dfd1347c78eeec10ec0847e18fcc50ef36Andrei Popescu        }
278722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return mDefaultVideoPoster;
278822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
2789540035dfd1347c78eeec10ec0847e18fcc50ef36Andrei Popescu
279022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    View getVideoLoadingProgressView() {
279122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mVideoProgressView == null) {
279222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            LayoutInflater inflater = LayoutInflater.from(BrowserActivity.this);
279322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mVideoProgressView = inflater.inflate(
279422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    R.layout.video_loading_progress, null);
2795540035dfd1347c78eeec10ec0847e18fcc50ef36Andrei Popescu        }
279622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return mVideoProgressView;
279722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
27980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
27998d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins    /*
28008d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins     * The Object used to inform the WebView of the file to upload.
28018d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins     */
28028d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins    private ValueCallback<Uri> mUploadMessage;
28038d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins
280422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void openFileChooser(ValueCallback<Uri> uploadMsg) {
280522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mUploadMessage != null) return;
280622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mUploadMessage = uploadMsg;
280722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        Intent i = new Intent(Intent.ACTION_GET_CONTENT);
280822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        i.addCategory(Intent.CATEGORY_OPENABLE);
280922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        i.setType("*/*");
281022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        BrowserActivity.this.startActivityForResult(Intent.createChooser(i,
281122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                getString(R.string.choose_upload)), FILE_SELECTED);
281222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
281322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
281422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // -------------------------------------------------------------------------
281522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // Implement functions for DownloadListener
281622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // -------------------------------------------------------------------------
281722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
28180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
28190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Notify the host application a download should be done, or that
28200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * the data should be streamed if a streaming viewer is available.
28210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param url The full url to the content that should be downloaded
28220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param contentDisposition Content-disposition http header, if
28230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *                           present.
28240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param mimetype The mimetype of the content reported by the server
28250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param contentLength The file size reported by the server
28260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
28270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public void onDownloadStart(String url, String userAgent,
28280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            String contentDisposition, String mimetype, long contentLength) {
28290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // if we're dealing wih A/V content that's not explicitly marked
28300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        //     for download, check if it's streamable.
28310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (contentDisposition == null
2832e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                || !contentDisposition.regionMatches(
2833e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                        true, 0, "attachment", 0, 10)) {
28340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // query the package manager to see if there's a registered handler
28350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            //     that matches.
28360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Intent intent = new Intent(Intent.ACTION_VIEW);
28370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            intent.setDataAndType(Uri.parse(url), mimetype);
2838e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott            ResolveInfo info = getPackageManager().resolveActivity(intent,
2839e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                    PackageManager.MATCH_DEFAULT_ONLY);
2840e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott            if (info != null) {
2841e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                ComponentName myName = getComponentName();
2842e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                // If we resolved to ourselves, we don't want to attempt to
2843e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                // load the url only to try and download it again.
2844e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                if (!myName.getPackageName().equals(
2845e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                        info.activityInfo.packageName)
2846e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                        || !myName.getClassName().equals(
2847e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                                info.activityInfo.name)) {
2848e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                    // someone (other than us) knows how to handle this mime
2849e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                    // type with this scheme, don't download.
2850e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                    try {
2851e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                        startActivity(intent);
2852e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                        return;
2853e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                    } catch (ActivityNotFoundException ex) {
2854e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                        if (LOGD_ENABLED) {
2855e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                            Log.d(LOGTAG, "activity not found for " + mimetype
2856e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                                    + " over " + Uri.parse(url).getScheme(),
2857e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                                    ex);
2858e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                        }
2859e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                        // Best behavior is to fall back to a download in this
2860e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                        // case
28610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
28620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
28630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
28640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
28650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        onDownloadStartNoStream(url, userAgent, contentDisposition, mimetype, contentLength);
28660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
28670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
28680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
28690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Notify the host application a download should be done, even if there
28700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * is a streaming viewer available for thise type.
28710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param url The full url to the content that should be downloaded
28720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param contentDisposition Content-disposition http header, if
28730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *                           present.
28740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param mimetype The mimetype of the content reported by the server
28750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param contentLength The file size reported by the server
28760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
28770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /*package */ void onDownloadStartNoStream(String url, String userAgent,
28780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            String contentDisposition, String mimetype, long contentLength) {
28790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
28800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String filename = URLUtil.guessFileName(url,
28810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                contentDisposition, mimetype);
28820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
28830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Check to see if we have an SDCard
28840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String status = Environment.getExternalStorageState();
28850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (!status.equals(Environment.MEDIA_MOUNTED)) {
28860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            int title;
28870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            String msg;
28880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
28890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Check to see if the SDCard is busy, same as the music app
28900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (status.equals(Environment.MEDIA_SHARED)) {
28910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                msg = getString(R.string.download_sdcard_busy_dlg_msg);
28920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                title = R.string.download_sdcard_busy_dlg_title;
28930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } else {
28940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                msg = getString(R.string.download_no_sdcard_dlg_msg, filename);
28950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                title = R.string.download_no_sdcard_dlg_title;
28960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
28970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
28980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            new AlertDialog.Builder(this)
28990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setTitle(title)
29000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setIcon(android.R.drawable.ic_dialog_alert)
29010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setMessage(msg)
29020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setPositiveButton(R.string.ok, null)
29030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .show();
29040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
29050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
29060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
29070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // java.net.URI is a lot stricter than KURL so we have to undo
29080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // KURL's percent-encoding and redo the encoding using java.net.URI.
29090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        URI uri = null;
29100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        try {
29110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Undo the percent-encoding that KURL may have done.
29120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            String newUrl = new String(URLUtil.decode(url.getBytes()));
29130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Parse the url into pieces
29140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            WebAddress w = new WebAddress(newUrl);
29150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            String frag = null;
29160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            String query = null;
29170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            String path = w.mPath;
29180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Break the path into path, query, and fragment
29190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (path.length() > 0) {
29200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // Strip the fragment
29210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                int idx = path.lastIndexOf('#');
29220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (idx != -1) {
29230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    frag = path.substring(idx + 1);
29240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    path = path.substring(0, idx);
29250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
29260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                idx = path.lastIndexOf('?');
29270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (idx != -1) {
29280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    query = path.substring(idx + 1);
29290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    path = path.substring(0, idx);
29300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
29310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
29320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            uri = new URI(w.mScheme, w.mAuthInfo, w.mHost, w.mPort, path,
29330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    query, frag);
29340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } catch (Exception e) {
29350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Log.e(LOGTAG, "Could not parse url for download: " + url, e);
29360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
29370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
29380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
29390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // XXX: Have to use the old url since the cookies were stored using the
29400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // old percent-encoded url.
29410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String cookies = CookieManager.getInstance().getCookie(url);
29420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
29430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        ContentValues values = new ContentValues();
29441e5bad97ca8fb9b12501f4f747941d02f03e1362Jean-Baptiste Queru        values.put(Downloads.Impl.COLUMN_URI, uri.toString());
29451e5bad97ca8fb9b12501f4f747941d02f03e1362Jean-Baptiste Queru        values.put(Downloads.Impl.COLUMN_COOKIE_DATA, cookies);
29461e5bad97ca8fb9b12501f4f747941d02f03e1362Jean-Baptiste Queru        values.put(Downloads.Impl.COLUMN_USER_AGENT, userAgent);
29471e5bad97ca8fb9b12501f4f747941d02f03e1362Jean-Baptiste Queru        values.put(Downloads.Impl.COLUMN_NOTIFICATION_PACKAGE,
29480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                getPackageName());
29491e5bad97ca8fb9b12501f4f747941d02f03e1362Jean-Baptiste Queru        values.put(Downloads.Impl.COLUMN_NOTIFICATION_CLASS,
29500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                BrowserDownloadPage.class.getCanonicalName());
29511e5bad97ca8fb9b12501f4f747941d02f03e1362Jean-Baptiste Queru        values.put(Downloads.Impl.COLUMN_VISIBILITY,
29521e5bad97ca8fb9b12501f4f747941d02f03e1362Jean-Baptiste Queru                Downloads.Impl.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
29531e5bad97ca8fb9b12501f4f747941d02f03e1362Jean-Baptiste Queru        values.put(Downloads.Impl.COLUMN_MIME_TYPE, mimetype);
29541e5bad97ca8fb9b12501f4f747941d02f03e1362Jean-Baptiste Queru        values.put(Downloads.Impl.COLUMN_FILE_NAME_HINT, filename);
29551e5bad97ca8fb9b12501f4f747941d02f03e1362Jean-Baptiste Queru        values.put(Downloads.Impl.COLUMN_DESCRIPTION, uri.getHost());
29560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (contentLength > 0) {
29571e5bad97ca8fb9b12501f4f747941d02f03e1362Jean-Baptiste Queru            values.put(Downloads.Impl.COLUMN_TOTAL_BYTES, contentLength);
29580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
29590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mimetype == null) {
29600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // We must have long pressed on a link or image to download it. We
29610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // are not sure of the mimetype in this case, so do a head request
29620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            new FetchUrlMimeType(this).execute(values);
29630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
29640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            final Uri contentUri =
29651e5bad97ca8fb9b12501f4f747941d02f03e1362Jean-Baptiste Queru                    getContentResolver().insert(Downloads.Impl.CONTENT_URI, values);
29660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
29670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
29680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
29690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
297022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // -------------------------------------------------------------------------
297122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
29720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
29730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Resets the lock icon. This method is called when we start a new load and
29740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * know the url to be loaded.
29750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
29760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void resetLockIcon(String url) {
29770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Save the lock-icon state (we revert to it if the load gets cancelled)
297822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mTabControl.getCurrentTab().resetLockIcon(url);
29790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        updateLockIconImage(LOCK_ICON_UNSECURE);
29800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
29810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
29820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
29833bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     * Update the lock icon to correspond to our latest state.
29843bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     */
298522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private void updateLockIconToLatest() {
298622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        updateLockIconImage(mTabControl.getCurrentTab().getLockIconType());
29873bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    }
29883bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins
29893bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    /**
29900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Updates the lock-icon image in the title-bar.
29910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
29920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void updateLockIconImage(int lockIconType) {
29930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        Drawable d = null;
29940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (lockIconType == LOCK_ICON_SECURE) {
29950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            d = mSecLockIcon;
29960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else if (lockIconType == LOCK_ICON_MIXED) {
29970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            d = mMixLockIcon;
29980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
299968579393973f745fc65a2781061af9bb8f2d7020Leon Scroggins        mTitleBar.setLock(d);
3000fe87bd3a3897e4bad65bb3d284659ae2f4e57570Leon Scroggins        mFakeTitleBar.setLock(d);
30010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
30020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
30030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
30040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Displays a page-info dialog.
30050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param tab The tab to show info about
30060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param fromShowSSLCertificateOnError The flag that indicates whether
30070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * this dialog was opened from the SSL-certificate-on-error dialog or
30080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * not. This is important, since we need to know whether to return to
30090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * the parent dialog or simply dismiss.
30100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
301122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private void showPageInfo(final Tab tab,
30120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                              final boolean fromShowSSLCertificateOnError) {
30130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final LayoutInflater factory = LayoutInflater
30140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .from(this);
30150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
30160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final View pageInfoView = factory.inflate(R.layout.page_info, null);
30170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
30180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final WebView view = tab.getWebView();
30190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
30200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String url = null;
30210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String title = null;
30220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
30230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (view == null) {
30240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            url = tab.getUrl();
30250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            title = tab.getTitle();
30260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else if (view == mTabControl.getCurrentWebView()) {
30270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project             // Use the cached title and url if this is the current WebView
30280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            url = mUrl;
30290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            title = mTitle;
30300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
30310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            url = view.getUrl();
30320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            title = view.getTitle();
30330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
30340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
30350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (url == null) {
30360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            url = "";
30370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
30380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (title == null) {
30390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            title = "";
30400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
30410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
30420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        ((TextView) pageInfoView.findViewById(R.id.address)).setText(url);
30430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        ((TextView) pageInfoView.findViewById(R.id.title)).setText(title);
30440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
30450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mPageInfoView = tab;
3046c7b92f811dfa3572578ddc6714c98a03936d9ce5Leon Scroggins        mPageInfoFromShowSSLCertificateOnError = fromShowSSLCertificateOnError;
30470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
30480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        AlertDialog.Builder alertDialogBuilder =
30490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            new AlertDialog.Builder(this)
30500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            .setTitle(R.string.page_info).setIcon(android.R.drawable.ic_dialog_info)
30510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            .setView(pageInfoView)
30520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            .setPositiveButton(
30530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                R.string.ok,
30540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                new DialogInterface.OnClickListener() {
30550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    public void onClick(DialogInterface dialog,
30560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        int whichButton) {
30570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        mPageInfoDialog = null;
30580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        mPageInfoView = null;
30590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
30600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        // if we came here from the SSL error dialog
30610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        if (fromShowSSLCertificateOnError) {
30620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            // go back to the SSL error dialog
30630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            showSSLCertificateOnError(
30640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorView,
30650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorHandler,
30660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorError);
30670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }
30680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
30690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                })
30700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            .setOnCancelListener(
30710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                new DialogInterface.OnCancelListener() {
30720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    public void onCancel(DialogInterface dialog) {
30730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        mPageInfoDialog = null;
30740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        mPageInfoView = null;
30750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
30760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        // if we came here from the SSL error dialog
30770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        if (fromShowSSLCertificateOnError) {
30780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            // go back to the SSL error dialog
30790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            showSSLCertificateOnError(
30800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorView,
30810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorHandler,
30820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorError);
30830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }
30840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
30850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                });
30860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
30870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // if we have a main top-level page SSL certificate set or a certificate
30880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // error
30890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (fromShowSSLCertificateOnError ||
30900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                (view != null && view.getCertificate() != null)) {
30910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // add a 'View Certificate' button
30920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            alertDialogBuilder.setNeutralButton(
30930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                R.string.view_certificate,
30940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                new DialogInterface.OnClickListener() {
30950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    public void onClick(DialogInterface dialog,
30960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        int whichButton) {
30970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        mPageInfoDialog = null;
30980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        mPageInfoView = null;
30990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
31000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        // if we came here from the SSL error dialog
31010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        if (fromShowSSLCertificateOnError) {
31020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            // go back to the SSL error dialog
31030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            showSSLCertificateOnError(
31040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorView,
31050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorHandler,
31060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorError);
31070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        } else {
31080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            // otherwise, display the top-most certificate from
31090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            // the chain
31100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            if (view.getCertificate() != null) {
31110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                showSSLCertificate(tab);
31120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            }
31130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }
31140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
31150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                });
31160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
31170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
31180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mPageInfoDialog = alertDialogBuilder.show();
31190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
31200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
31210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project       /**
31220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Displays the main top-level page SSL certificate dialog
31230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * (accessible from the Page-Info dialog).
31240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param tab The tab to show certificate for.
31250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
312622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private void showSSLCertificate(final Tab tab) {
31270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final View certificateView =
31280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                inflateCertificateView(tab.getWebView().getCertificate());
31290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (certificateView == null) {
31300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
31310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
31320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
31330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        LayoutInflater factory = LayoutInflater.from(this);
31340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
31350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final LinearLayout placeholder =
31360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                (LinearLayout)certificateView.findViewById(R.id.placeholder);
31370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
31380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        LinearLayout ll = (LinearLayout) factory.inflate(
31390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            R.layout.ssl_success, placeholder);
31400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        ((TextView)ll.findViewById(R.id.success))
31410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            .setText(R.string.ssl_certificate_is_valid);
31420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
31430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mSSLCertificateView = tab;
31440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mSSLCertificateDialog =
31450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            new AlertDialog.Builder(this)
31460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setTitle(R.string.ssl_certificate).setIcon(
31470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    R.drawable.ic_dialog_browser_certificate_secure)
31480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setView(certificateView)
31490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setPositiveButton(R.string.ok,
31500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new DialogInterface.OnClickListener() {
31510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            public void onClick(DialogInterface dialog,
31520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    int whichButton) {
31530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateDialog = null;
31540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateView = null;
31550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
31560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                showPageInfo(tab, false);
31570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            }
31580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        })
31590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setOnCancelListener(
31600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new DialogInterface.OnCancelListener() {
31610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            public void onCancel(DialogInterface dialog) {
31620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateDialog = null;
31630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateView = null;
31640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
31650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                showPageInfo(tab, false);
31660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            }
31670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        })
31680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .show();
31690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
31700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
31710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
31720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Displays the SSL error certificate dialog.
31730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param view The target web-view.
31740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param handler The SSL error handler responsible for cancelling the
31750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * connection that resulted in an SSL error or proceeding per user request.
31760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param error The SSL error object.
31770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
317822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void showSSLCertificateOnError(
31790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final WebView view, final SslErrorHandler handler, final SslError error) {
31800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
31810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final View certificateView =
31820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            inflateCertificateView(error.getCertificate());
31830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (certificateView == null) {
31840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
31850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
31860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
31870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        LayoutInflater factory = LayoutInflater.from(this);
31880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
31890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final LinearLayout placeholder =
31900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                (LinearLayout)certificateView.findViewById(R.id.placeholder);
31910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
31920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (error.hasError(SslError.SSL_UNTRUSTED)) {
31930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            LinearLayout ll = (LinearLayout)factory
31940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .inflate(R.layout.ssl_warning, placeholder);
31950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((TextView)ll.findViewById(R.id.warning))
31960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setText(R.string.ssl_untrusted);
31970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
31980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
31990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (error.hasError(SslError.SSL_IDMISMATCH)) {
32000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            LinearLayout ll = (LinearLayout)factory
32010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .inflate(R.layout.ssl_warning, placeholder);
32020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((TextView)ll.findViewById(R.id.warning))
32030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setText(R.string.ssl_mismatch);
32040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
32050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
32060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (error.hasError(SslError.SSL_EXPIRED)) {
32070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            LinearLayout ll = (LinearLayout)factory
32080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .inflate(R.layout.ssl_warning, placeholder);
32090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((TextView)ll.findViewById(R.id.warning))
32100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setText(R.string.ssl_expired);
32110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
32120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
32130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (error.hasError(SslError.SSL_NOTYETVALID)) {
32140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            LinearLayout ll = (LinearLayout)factory
32150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .inflate(R.layout.ssl_warning, placeholder);
32160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((TextView)ll.findViewById(R.id.warning))
32170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setText(R.string.ssl_not_yet_valid);
32180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
32190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
32200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mSSLCertificateOnErrorHandler = handler;
32210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mSSLCertificateOnErrorView = view;
32220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mSSLCertificateOnErrorError = error;
32230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mSSLCertificateOnErrorDialog =
32240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            new AlertDialog.Builder(this)
32250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setTitle(R.string.ssl_certificate).setIcon(
32260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    R.drawable.ic_dialog_browser_certificate_partially_secure)
32270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setView(certificateView)
32280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setPositiveButton(R.string.ok,
32290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new DialogInterface.OnClickListener() {
32300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            public void onClick(DialogInterface dialog,
32310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    int whichButton) {
32320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorDialog = null;
32330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorView = null;
32340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorHandler = null;
32350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorError = null;
32360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
323722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                view.getWebViewClient().onReceivedSslError(
323822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                                view, handler, error);
32390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            }
32400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        })
32410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                 .setNeutralButton(R.string.page_info_view,
32420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new DialogInterface.OnClickListener() {
32430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            public void onClick(DialogInterface dialog,
32440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    int whichButton) {
32450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorDialog = null;
32460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
32470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                // do not clear the dialog state: we will
32480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                // need to show the dialog again once the
32490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                // user is done exploring the page-info details
32500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
32510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                showPageInfo(mTabControl.getTabFromView(view),
32520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        true);
32530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            }
32540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        })
32550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setOnCancelListener(
32560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new DialogInterface.OnCancelListener() {
32570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            public void onCancel(DialogInterface dialog) {
32580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorDialog = null;
32590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorView = null;
32600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorHandler = null;
32610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorError = null;
32620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
326322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                view.getWebViewClient().onReceivedSslError(
326422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                                view, handler, error);
32650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            }
32660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        })
32670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .show();
32680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
32690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
32700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
32710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Inflates the SSL certificate view (helper method).
32720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param certificate The SSL certificate.
32730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @return The resultant certificate view with issued-to, issued-by,
32740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * issued-on, expires-on, and possibly other fields set.
32750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * If the input certificate is null, returns null.
32760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
32770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private View inflateCertificateView(SslCertificate certificate) {
32780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (certificate == null) {
32790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return null;
32800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
32810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
32820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        LayoutInflater factory = LayoutInflater.from(this);
32830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
32840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        View certificateView = factory.inflate(
32850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            R.layout.ssl_certificate, null);
32860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
32870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // issued to:
32880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        SslCertificate.DName issuedTo = certificate.getIssuedTo();
32890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (issuedTo != null) {
32900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((TextView) certificateView.findViewById(R.id.to_common))
32910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setText(issuedTo.getCName());
32920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((TextView) certificateView.findViewById(R.id.to_org))
32930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setText(issuedTo.getOName());
32940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((TextView) certificateView.findViewById(R.id.to_org_unit))
32950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setText(issuedTo.getUName());
32960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
32970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
32980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // issued by:
32990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        SslCertificate.DName issuedBy = certificate.getIssuedBy();
33000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (issuedBy != null) {
33010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((TextView) certificateView.findViewById(R.id.by_common))
33020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setText(issuedBy.getCName());
33030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((TextView) certificateView.findViewById(R.id.by_org))
33040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setText(issuedBy.getOName());
33050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((TextView) certificateView.findViewById(R.id.by_org_unit))
33060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setText(issuedBy.getUName());
33070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
33080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
33090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // issued on:
33100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String issuedOn = reformatCertificateDate(
33110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            certificate.getValidNotBefore());
33120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        ((TextView) certificateView.findViewById(R.id.issued_on))
33130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            .setText(issuedOn);
33140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
33150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // expires on:
33160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String expiresOn = reformatCertificateDate(
33170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            certificate.getValidNotAfter());
33180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        ((TextView) certificateView.findViewById(R.id.expires_on))
33190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            .setText(expiresOn);
33200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
33210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return certificateView;
33220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
33230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
33240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
33250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Re-formats the certificate date (Date.toString()) string to
33260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * a properly localized date string.
33270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @return Properly localized version of the certificate date string and
33280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * the original certificate date string if fails to localize.
33290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * If the original string is null, returns an empty string "".
33300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
33310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private String reformatCertificateDate(String certificateDate) {
33320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project      String reformattedDate = null;
33330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
33340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project      if (certificateDate != null) {
33350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project          Date date = null;
33360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project          try {
33370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project              date = java.text.DateFormat.getInstance().parse(certificateDate);
33380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project          } catch (ParseException e) {
33390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project              date = null;
33400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project          }
33410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
33420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project          if (date != null) {
33430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project              reformattedDate =
33440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                  DateFormat.getDateFormat(this).format(date);
33450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project          }
33460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project      }
33470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
33480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project      return reformattedDate != null ? reformattedDate :
33490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project          (certificateDate != null ? certificateDate : "");
33500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
33510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
33520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
33530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Displays an http-authentication dialog.
33540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
335522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void showHttpAuthentication(final HttpAuthHandler handler,
33560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            final String host, final String realm, final String title,
33570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            final String name, final String password, int focusId) {
33580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        LayoutInflater factory = LayoutInflater.from(this);
33590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final View v = factory
33600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .inflate(R.layout.http_authentication, null);
33610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (name != null) {
33620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((EditText) v.findViewById(R.id.username_edit)).setText(name);
33630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
33640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (password != null) {
33650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((EditText) v.findViewById(R.id.password_edit)).setText(password);
33660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
33670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
33680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String titleText = title;
33690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (titleText == null) {
33700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            titleText = getText(R.string.sign_in_to).toString().replace(
33710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    "%s1", host).replace("%s2", realm);
33720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
33730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
33740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mHttpAuthHandler = handler;
33750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        AlertDialog dialog = new AlertDialog.Builder(this)
33760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setTitle(titleText)
33770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setIcon(android.R.drawable.ic_dialog_alert)
33780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setView(v)
33790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setPositiveButton(R.string.action,
33800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new DialogInterface.OnClickListener() {
33810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                             public void onClick(DialogInterface dialog,
33820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                     int whichButton) {
33830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                String nm = ((EditText) v
33840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        .findViewById(R.id.username_edit))
33850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        .getText().toString();
33860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                String pw = ((EditText) v
33870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        .findViewById(R.id.password_edit))
33880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        .getText().toString();
33890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                BrowserActivity.this.setHttpAuthUsernamePassword
33900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        (host, realm, nm, pw);
33910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                handler.proceed(nm, pw);
33920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mHttpAuthenticationDialog = null;
33930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mHttpAuthHandler = null;
33940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            }})
33950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setNegativeButton(R.string.cancel,
33960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new DialogInterface.OnClickListener() {
33970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            public void onClick(DialogInterface dialog,
33980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    int whichButton) {
33990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                handler.cancel();
34000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                BrowserActivity.this.resetTitleAndRevertLockIcon();
34010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mHttpAuthenticationDialog = null;
34020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mHttpAuthHandler = null;
34030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            }})
34040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setOnCancelListener(new DialogInterface.OnCancelListener() {
34050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        public void onCancel(DialogInterface dialog) {
34060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            handler.cancel();
34070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            BrowserActivity.this.resetTitleAndRevertLockIcon();
34080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            mHttpAuthenticationDialog = null;
34090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            mHttpAuthHandler = null;
34100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }})
34110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .create();
34120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Make the IME appear when the dialog is displayed if applicable.
34130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        dialog.getWindow().setSoftInputMode(
34140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);
34150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        dialog.show();
34160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (focusId != 0) {
34170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            dialog.findViewById(focusId).requestFocus();
34180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
34190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            v.findViewById(R.id.username_edit).requestFocus();
34200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
34210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mHttpAuthenticationDialog = dialog;
34220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
34230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
34240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public int getProgress() {
34250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebView w = mTabControl.getCurrentWebView();
34260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (w != null) {
34270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return w.getProgress();
34280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
34290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return 100;
34300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
34310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
34320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
34330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
34340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Set HTTP authentication password.
34350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *
34360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param host The host for the password
34370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param realm The realm for the password
34380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param username The username for the password. If it is null, it means
34390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *            password can't be saved.
34400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param password The password
34410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
34420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public void setHttpAuthUsernamePassword(String host, String realm,
34430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                            String username,
34440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                            String password) {
34450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebView w = mTabControl.getCurrentWebView();
34460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (w != null) {
34470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            w.setHttpAuthUsernamePassword(host, realm, username, password);
34480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
34490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
34500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
34510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
34520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * connectivity manager says net has come or gone... inform the user
34530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param up true if net has come up, false if net has gone down
34540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
34550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public void onNetworkToggle(boolean up) {
34560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (up == mIsNetworkUp) {
34570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
34580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else if (up) {
34590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mIsNetworkUp = true;
34600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (mAlertDialog != null) {
34610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mAlertDialog.cancel();
34620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mAlertDialog = null;
34630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
34640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
34650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mIsNetworkUp = false;
3466eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott            if (mInLoad) {
3467eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott                createAndShowNetworkDialog();
3468eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott           }
34690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
34700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebView w = mTabControl.getCurrentWebView();
34710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (w != null) {
34720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            w.setNetworkAvailable(up);
34730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
34740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
34750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
347622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    boolean isNetworkUp() {
347722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return mIsNetworkUp;
347822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
347922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
3480eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott    // This method shows the network dialog alerting the user that the net is
3481eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott    // down. It will only show the dialog if mAlertDialog is null.
3482eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott    private void createAndShowNetworkDialog() {
3483eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott        if (mAlertDialog == null) {
3484eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott            mAlertDialog = new AlertDialog.Builder(this)
3485eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott                    .setTitle(R.string.loadSuspendedTitle)
3486eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott                    .setMessage(R.string.loadSuspended)
3487eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott                    .setPositiveButton(R.string.ok, null)
3488eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott                    .show();
3489eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott        }
3490eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott    }
3491eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott
34920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    @Override
34930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    protected void onActivityResult(int requestCode, int resultCode,
34940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    Intent intent) {
3495bb394f3e134b6e5898ef7ae861b75e95e618688fGrace Kloba        if (getTopWindow() == null) return;
3496bb394f3e134b6e5898ef7ae861b75e95e618688fGrace Kloba
34970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        switch (requestCode) {
34980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case COMBO_PAGE:
34990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (resultCode == RESULT_OK && intent != null) {
35000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    String data = intent.getAction();
35010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    Bundle extras = intent.getExtras();
35020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    if (extras != null && extras.getBoolean("new_window", false)) {
350325d3547e0df084f963e38c6a93c99b02bd619de3Leon Scroggins                        openTab(data);
35040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    } else {
350522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        final Tab currentTab =
35060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mTabControl.getCurrentTab();
35071f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                        dismissSubWindow(currentTab);
35081f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                        if (data != null && data.length() != 0) {
35091f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                            getTopWindow().loadUrl(data);
35100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }
35110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
35120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
3513fde9746ac3055848e110c35f19ec5893c621f766Leon Scroggins                // Deliberately fall through to PREFERENCES_PAGE, since the
3514fde9746ac3055848e110c35f19ec5893c621f766Leon Scroggins                // same extra may be attached to the COMBO_PAGE
3515fde9746ac3055848e110c35f19ec5893c621f766Leon Scroggins            case PREFERENCES_PAGE:
3516fde9746ac3055848e110c35f19ec5893c621f766Leon Scroggins                if (resultCode == RESULT_OK && intent != null) {
3517fde9746ac3055848e110c35f19ec5893c621f766Leon Scroggins                    String action = intent.getStringExtra(Intent.EXTRA_TEXT);
3518fde9746ac3055848e110c35f19ec5893c621f766Leon Scroggins                    if (BrowserSettings.PREF_CLEAR_HISTORY.equals(action)) {
3519fde9746ac3055848e110c35f19ec5893c621f766Leon Scroggins                        mTabControl.removeParentChildRelationShips();
3520fde9746ac3055848e110c35f19ec5893c621f766Leon Scroggins                    }
3521fde9746ac3055848e110c35f19ec5893c621f766Leon Scroggins                }
35220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
35238d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins            // Choose a file from the file picker.
35248d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins            case FILE_SELECTED:
35258d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins                if (null == mUploadMessage) break;
35268d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins                Uri result = intent == null || resultCode != RESULT_OK ? null
35278d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins                        : intent.getData();
35288d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins                mUploadMessage.onReceiveValue(result);
35298d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins                mUploadMessage = null;
35308d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins                break;
35310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            default:
35320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
35330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
3534304442375719effd41dbd53ae62de7a8d0cec7d9Leon Scroggins        getTopWindow().requestFocus();
35350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
35360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
35370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /*
35380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * This method is called as a result of the user selecting the options
3539f08809b2cf7e502fef5965691a7fb6d7cf0322afLeon Scroggins     * menu to see the download window. It shows the download window on top of
3540f08809b2cf7e502fef5965691a7fb6d7cf0322afLeon Scroggins     * the current window.
35410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
3542f08809b2cf7e502fef5965691a7fb6d7cf0322afLeon Scroggins    private void viewDownloads(Uri downloadRecord) {
35430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        Intent intent = new Intent(this,
35440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                BrowserDownloadPage.class);
35450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        intent.setData(downloadRecord);
354622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        startActivityForResult(intent, BrowserActivity.DOWNLOAD_PAGE);
35470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
35480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
35490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
3550160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins    /**
3551160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins     * Open the Go page.
3552160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins     * @param startWithHistory If true, open starting on the history tab.
3553160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins     *                         Otherwise, start with the bookmarks tab.
3554160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins     */
3555304442375719effd41dbd53ae62de7a8d0cec7d9Leon Scroggins    /* package */ void bookmarksOrHistoryPicker(boolean startWithHistory) {
35560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebView current = mTabControl.getCurrentWebView();
35570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (current == null) {
35580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
35590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
35600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        Intent intent = new Intent(this,
35610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                CombinedBookmarkHistoryActivity.class);
35620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String title = current.getTitle();
35630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String url = current.getUrl();
3564dcc2b6f08dd5677bc6ba761a9ba6f1c655113051Ben Murdoch        Bitmap thumbnail = createScreenshot(current);
3565dcc2b6f08dd5677bc6ba761a9ba6f1c655113051Ben Murdoch
35660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Just in case the user opens bookmarks before a page finishes loading
35670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // so the current history item, and therefore the page, is null.
35680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (null == url) {
35690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            url = mLastEnteredUrl;
35700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // This can happen.
35710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (null == url) {
35720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                url = mSettings.getHomePage();
35730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
35740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
35750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // In case the web page has not yet received its associated title.
35760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (title == null) {
35770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            title = url;
35780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
35790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        intent.putExtra("title", title);
35800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        intent.putExtra("url", url);
3581dcc2b6f08dd5677bc6ba761a9ba6f1c655113051Ben Murdoch        intent.putExtra("thumbnail", thumbnail);
3582304442375719effd41dbd53ae62de7a8d0cec7d9Leon Scroggins        // Disable opening in a new window if we have maxed out the windows
358322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        intent.putExtra("disable_new_window", !mTabControl.canCreateNewTab());
35843918d4443ff38ef1870e02aa51a8b29f8352bb1aPatrick Scott        intent.putExtra("touch_icon_url", current.getTouchIconUrl());
35850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (startWithHistory) {
35860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            intent.putExtra(CombinedBookmarkHistoryActivity.STARTING_TAB,
35870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    CombinedBookmarkHistoryActivity.HISTORY_TAB);
35880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
35890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        startActivityForResult(intent, COMBO_PAGE);
35900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
35910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
35920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Called when loading from context menu or LOAD_URL message
35930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void loadURL(WebView view, String url) {
35940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // In case the user enters nothing.
35950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (url != null && url.length() != 0 && view != null) {
35960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            url = smartUrlFilter(url);
359722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (!view.getWebViewClient().shouldOverrideUrlLoading(view, url)) {
35980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                view.loadUrl(url);
35990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
36000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
36010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
36020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
36030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private String smartUrlFilter(Uri inUri) {
36040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (inUri != null) {
36050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return smartUrlFilter(inUri.toString());
36060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
36070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return null;
36080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
36090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
3610b34f87a2e13af13d697130482af01b537ab7c5fdFeng Qian    protected static final Pattern ACCEPTED_URI_SCHEMA = Pattern.compile(
36110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            "(?i)" + // switch on case insensitive matching
36120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            "(" +    // begin group for schema
36130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            "(?:http|https|file):\\/\\/" +
361425ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima            "|(?:inline|data|about|content|javascript):" +
36150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ")" +
36160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            "(.*)" );
36170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
36180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
36190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Attempts to determine whether user input is a URL or search
36200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * terms.  Anything with a space is passed to search.
36210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *
36220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Converts to lowercase any mistakenly uppercased schema (i.e.,
36230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * "Http://" converts to "http://"
36240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *
36250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @return Original or modified URL
36260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *
36270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
36280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    String smartUrlFilter(String url) {
36290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
36300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String inUrl = url.trim();
36310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        boolean hasSpace = inUrl.indexOf(' ') != -1;
36320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
36330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        Matcher matcher = ACCEPTED_URI_SCHEMA.matcher(inUrl);
36340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (matcher.matches()) {
36350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // force scheme to lowercase
36360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            String scheme = matcher.group(1);
36370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            String lcScheme = scheme.toLowerCase();
36380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (!lcScheme.equals(scheme)) {
3639123ecfb21e7ca670e3d04efe58780b3bac54a9a1Mitsuru Oshima                inUrl = lcScheme + matcher.group(2);
3640123ecfb21e7ca670e3d04efe58780b3bac54a9a1Mitsuru Oshima            }
3641123ecfb21e7ca670e3d04efe58780b3bac54a9a1Mitsuru Oshima            if (hasSpace) {
3642123ecfb21e7ca670e3d04efe58780b3bac54a9a1Mitsuru Oshima                inUrl = inUrl.replace(" ", "%20");
36430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
36440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return inUrl;
36450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
36460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (hasSpace) {
3647565505b1a2c1d3099496af5910760087602e994aSatish Sampath            // FIXME: Is this the correct place to add to searches?
3648565505b1a2c1d3099496af5910760087602e994aSatish Sampath            // what if someone else calls this function?
3649565505b1a2c1d3099496af5910760087602e994aSatish Sampath            int shortcut = parseUrlShortcut(inUrl);
3650565505b1a2c1d3099496af5910760087602e994aSatish Sampath            if (shortcut != SHORTCUT_INVALID) {
3651565505b1a2c1d3099496af5910760087602e994aSatish Sampath                Browser.addSearchUrl(mResolver, inUrl);
3652565505b1a2c1d3099496af5910760087602e994aSatish Sampath                String query = inUrl.substring(2);
3653565505b1a2c1d3099496af5910760087602e994aSatish Sampath                switch (shortcut) {
3654565505b1a2c1d3099496af5910760087602e994aSatish Sampath                case SHORTCUT_GOOGLE_SEARCH:
365547fdfdb989ffb79590a39c40792be995de32e521Grace Kloba                    return URLUtil.composeSearchUrl(query, QuickSearch_G, QUERY_PLACE_HOLDER);
3656565505b1a2c1d3099496af5910760087602e994aSatish Sampath                case SHORTCUT_WIKIPEDIA_SEARCH:
3657565505b1a2c1d3099496af5910760087602e994aSatish Sampath                    return URLUtil.composeSearchUrl(query, QuickSearch_W, QUERY_PLACE_HOLDER);
3658565505b1a2c1d3099496af5910760087602e994aSatish Sampath                case SHORTCUT_DICTIONARY_SEARCH:
3659565505b1a2c1d3099496af5910760087602e994aSatish Sampath                    return URLUtil.composeSearchUrl(query, QuickSearch_D, QUERY_PLACE_HOLDER);
3660565505b1a2c1d3099496af5910760087602e994aSatish Sampath                case SHORTCUT_GOOGLE_MOBILE_LOCAL_SEARCH:
36610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // FIXME: we need location in this case
3662565505b1a2c1d3099496af5910760087602e994aSatish Sampath                    return URLUtil.composeSearchUrl(query, QuickSearch_L, QUERY_PLACE_HOLDER);
36630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
36640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
36650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
36665ee906c089567bca705e18561357510d7b55cb5aDan Egnor            if (Patterns.WEB_URL.matcher(inUrl).matches()) {
36670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                return URLUtil.guessUrl(inUrl);
36680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
36690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
36700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
36710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        Browser.addSearchUrl(mResolver, inUrl);
367247fdfdb989ffb79590a39c40792be995de32e521Grace Kloba        return URLUtil.composeSearchUrl(inUrl, QuickSearch_G, QUERY_PLACE_HOLDER);
36730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
36740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
3675bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch    /* package */ void setShouldShowErrorConsole(boolean flag) {
3676bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch        if (flag == mShouldShowErrorConsole) {
3677bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch            // Nothing to do.
3678bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch            return;
3679bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch        }
3680bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch
3681bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch        mShouldShowErrorConsole = flag;
3682bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch
368322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        ErrorConsoleView errorConsole = mTabControl.getCurrentTab()
368422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                .getErrorConsole(true);
3685bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch
3686bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch        if (flag) {
3687bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch            // Setting the show state of the console will cause it's the layout to be inflated.
3688bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch            if (errorConsole.numberOfErrors() > 0) {
3689bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch                errorConsole.showConsole(ErrorConsoleView.SHOW_MINIMIZED);
3690bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch            } else {
3691bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch                errorConsole.showConsole(ErrorConsoleView.SHOW_NONE);
3692bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch            }
3693bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch
3694bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch            // Now we can add it to the main view.
3695bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch            mErrorConsoleContainer.addView(errorConsole,
369615b8ec6b226f4d57307716e1f495e10a91f8cbf4Romain Guy                    new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
3697bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch                                                  ViewGroup.LayoutParams.WRAP_CONTENT));
3698bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch        } else {
3699bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch            mErrorConsoleContainer.removeView(errorConsole);
3700bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch        }
3701bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch
3702bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch    }
3703bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch
370422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    boolean shouldShowErrorConsole() {
370522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return mShouldShowErrorConsole;
370622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
370722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
3708163ab74e2f85b53a1a374c49677073fb64d35f28Andrei Popescu    private void setStatusBarVisibility(boolean visible) {
3709163ab74e2f85b53a1a374c49677073fb64d35f28Andrei Popescu        int flag = visible ? 0 : WindowManager.LayoutParams.FLAG_FULLSCREEN;
3710163ab74e2f85b53a1a374c49677073fb64d35f28Andrei Popescu        getWindow().setFlags(flag, WindowManager.LayoutParams.FLAG_FULLSCREEN);
3711163ab74e2f85b53a1a374c49677073fb64d35f28Andrei Popescu    }
3712163ab74e2f85b53a1a374c49677073fb64d35f28Andrei Popescu
371356199cc25e7ee0455ec2a8099098b66b8554f677Andrei Popescu
371456199cc25e7ee0455ec2a8099098b66b8554f677Andrei Popescu    private void sendNetworkType(String type, String subtype) {
371556199cc25e7ee0455ec2a8099098b66b8554f677Andrei Popescu        WebView w = mTabControl.getCurrentWebView();
371656199cc25e7ee0455ec2a8099098b66b8554f677Andrei Popescu        if (w != null) {
371756199cc25e7ee0455ec2a8099098b66b8554f677Andrei Popescu            w.setNetworkType(type, subtype);
371856199cc25e7ee0455ec2a8099098b66b8554f677Andrei Popescu        }
371956199cc25e7ee0455ec2a8099098b66b8554f677Andrei Popescu    }
372056199cc25e7ee0455ec2a8099098b66b8554f677Andrei Popescu
3721eb6eef4c45df2d65c3e70660493a147a2be405e3Grace Kloba    final static int LOCK_ICON_UNSECURE = 0;
3722eb6eef4c45df2d65c3e70660493a147a2be405e3Grace Kloba    final static int LOCK_ICON_SECURE   = 1;
3723eb6eef4c45df2d65c3e70660493a147a2be405e3Grace Kloba    final static int LOCK_ICON_MIXED    = 2;
37240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
37250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private BrowserSettings mSettings;
37260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private TabControl      mTabControl;
37270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private ContentResolver mResolver;
37280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private FrameLayout     mContentView;
3729adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu    private View            mCustomView;
3730adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu    private FrameLayout     mCustomViewContainer;
3731c9b5556351b59caec77b4eec1ad30652fec6a4d9Andrei Popescu    private WebChromeClient.CustomViewCallback mCustomViewCallback;
37320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
37330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // FIXME, temp address onPrepareMenu performance problem. When we move everything out of
37340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // view, we should rewrite this.
37350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private int mCurrentMenuState = 0;
37360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private int mMenuState = R.id.MAIN_MENU;
3737adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu    private int mOldMenuState = EMPTY_MENU;
37380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private static final int EMPTY_MENU = -1;
37390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private Menu mMenu;
37400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
37410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private FindDialog mFindDialog;
37420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Used to prevent chording to result in firing two shortcuts immediately
37430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // one after another.  Fixes bug 1211714.
37440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    boolean mCanChord;
37450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
37460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private boolean mInLoad;
37470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private boolean mIsNetworkUp;
3748b7cc8b439dc595dc48e1c2183b35d23ad72dfbe5Ben Murdoch    private boolean mDidStopLoad;
37490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
37500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private boolean mActivityInPause = true;
37510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
37520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private boolean mMenuIsDown;
37530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
37540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private static boolean mInTrace;
37550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
37560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Performance probe
37570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private static final int[] SYSTEM_CPU_FORMAT = new int[] {
37580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Process.PROC_SPACE_TERM | Process.PROC_COMBINE,
37590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Process.PROC_SPACE_TERM | Process.PROC_OUT_LONG, // 1: user time
37600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Process.PROC_SPACE_TERM | Process.PROC_OUT_LONG, // 2: nice time
37610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Process.PROC_SPACE_TERM | Process.PROC_OUT_LONG, // 3: sys time
37620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Process.PROC_SPACE_TERM | Process.PROC_OUT_LONG, // 4: idle time
37630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Process.PROC_SPACE_TERM | Process.PROC_OUT_LONG, // 5: iowait time
37640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Process.PROC_SPACE_TERM | Process.PROC_OUT_LONG, // 6: irq time
37650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Process.PROC_SPACE_TERM | Process.PROC_OUT_LONG  // 7: softirq time
37660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    };
37670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
37680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private long mStart;
37690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private long mProcessStart;
37700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private long mUserStart;
37710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private long mSystemStart;
37720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private long mIdleStart;
37730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private long mIrqStart;
37740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
37750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private long mUiStart;
37760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
37770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private Drawable    mMixLockIcon;
37780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private Drawable    mSecLockIcon;
37790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
37800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /* hold a ref so we can auto-cancel if necessary */
37810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private AlertDialog mAlertDialog;
37820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
37830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Wait for credentials before loading google.com
37840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private ProgressDialog mCredsDlg;
37850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
37860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // The up-to-date URL and title (these can be different from those stored
37870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // in WebView, since it takes some time for the information in WebView to
37880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // get updated)
37890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private String mUrl;
37900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private String mTitle;
37910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
37920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // As PageInfo has different style for landscape / portrait, we have
37930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // to re-open it when configuration changed
37940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private AlertDialog mPageInfoDialog;
379522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private Tab mPageInfoView;
37960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // If the Page-Info dialog is launched from the SSL-certificate-on-error
37970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // dialog, we should not just dismiss it, but should get back to the
37980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // SSL-certificate-on-error dialog. This flag is used to store this state
3799c7b92f811dfa3572578ddc6714c98a03936d9ce5Leon Scroggins    private boolean mPageInfoFromShowSSLCertificateOnError;
38000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
38010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // as SSLCertificateOnError has different style for landscape / portrait,
38020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // we have to re-open it when configuration changed
38030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private AlertDialog mSSLCertificateOnErrorDialog;
38040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private WebView mSSLCertificateOnErrorView;
38050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private SslErrorHandler mSSLCertificateOnErrorHandler;
38060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private SslError mSSLCertificateOnErrorError;
38070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
38080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // as SSLCertificate has different style for landscape / portrait, we
38090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // have to re-open it when configuration changed
38100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private AlertDialog mSSLCertificateDialog;
381122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private Tab mSSLCertificateView;
38120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
38130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // as HttpAuthentication has different style for landscape / portrait, we
38140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // have to re-open it when configuration changed
38150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private AlertDialog mHttpAuthenticationDialog;
38160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private HttpAuthHandler mHttpAuthHandler;
38170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
38180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /*package*/ static final FrameLayout.LayoutParams COVER_SCREEN_PARAMS =
38190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                            new FrameLayout.LayoutParams(
382015b8ec6b226f4d57307716e1f495e10a91f8cbf4Romain Guy                                            ViewGroup.LayoutParams.MATCH_PARENT,
382115b8ec6b226f4d57307716e1f495e10a91f8cbf4Romain Guy                                            ViewGroup.LayoutParams.MATCH_PARENT);
3822adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu    /*package*/ static final FrameLayout.LayoutParams COVER_SCREEN_GRAVITY_CENTER =
3823adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu                                            new FrameLayout.LayoutParams(
382415b8ec6b226f4d57307716e1f495e10a91f8cbf4Romain Guy                                            ViewGroup.LayoutParams.MATCH_PARENT,
382515b8ec6b226f4d57307716e1f495e10a91f8cbf4Romain Guy                                            ViewGroup.LayoutParams.MATCH_PARENT,
3826adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu                                            Gravity.CENTER);
382747fdfdb989ffb79590a39c40792be995de32e521Grace Kloba    // Google search
382847fdfdb989ffb79590a39c40792be995de32e521Grace Kloba    final static String QuickSearch_G = "http://www.google.com/m?q=%s";
38290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Wikipedia search
38300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    final static String QuickSearch_W = "http://en.wikipedia.org/w/index.php?search=%s&go=Go";
38310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Dictionary search
38320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    final static String QuickSearch_D = "http://dictionary.reference.com/search?q=%s";
38330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Google Mobile Local search
38340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    final static String QuickSearch_L = "http://www.google.com/m/search?site=local&q=%s&near=mountain+view";
38350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
38360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    final static String QUERY_PLACE_HOLDER = "%s";
38370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
38380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // "source" parameter for Google search through search key
38390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    final static String GOOGLE_SEARCH_SOURCE_SEARCHKEY = "browser-key";
38400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // "source" parameter for Google search through goto menu
38410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    final static String GOOGLE_SEARCH_SOURCE_GOTO = "browser-goto";
38420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // "source" parameter for Google search through simplily type
38430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    final static String GOOGLE_SEARCH_SOURCE_TYPE = "browser-type";
38440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // "source" parameter for Google search suggested by the browser
38450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    final static String GOOGLE_SEARCH_SOURCE_SUGGEST = "browser-suggest";
38460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // "source" parameter for Google search from unknown source
38470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    final static String GOOGLE_SEARCH_SOURCE_UNKNOWN = "unknown";
38480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
38490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private final static String LOGTAG = "browser";
38500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
38510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private String mLastEnteredUrl;
38520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
38530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private PowerManager.WakeLock mWakeLock;
38540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private final static int WAKELOCK_TIMEOUT = 5 * 60 * 1000; // 5 minutes
38550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
38560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private Toast mStopToast;
38570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
385868579393973f745fc65a2781061af9bb8f2d7020Leon Scroggins    private TitleBar mTitleBar;
385981db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins
3860bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch    private LinearLayout mErrorConsoleContainer = null;
3861bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch    private boolean mShouldShowErrorConsole = false;
3862bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch
38630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // As the ids are dynamically created, we can't guarantee that they will
38640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // be in sequence, so this static array maps ids to a window number.
38650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    final static private int[] WINDOW_SHORTCUT_ID_ARRAY =
38660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    { R.id.window_one_menu_id, R.id.window_two_menu_id, R.id.window_three_menu_id,
38670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project      R.id.window_four_menu_id, R.id.window_five_menu_id, R.id.window_six_menu_id,
38680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project      R.id.window_seven_menu_id, R.id.window_eight_menu_id };
38690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
38700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // monitor platform changes
38710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private IntentFilter mNetworkStateChangedFilter;
38720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private BroadcastReceiver mNetworkStateIntentReceiver;
38730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
3874b4da0ad0351996f639b50f9f29b123a9b5c24fd0Grace Kloba    private BroadcastReceiver mPackageInstallationReceiver;
3875b4da0ad0351996f639b50f9f29b123a9b5c24fd0Grace Kloba
38760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // activity requestCode
387778a98e459323f938e97789a6131beddbebb459ceNicolas Roard    final static int COMBO_PAGE                 = 1;
387878a98e459323f938e97789a6131beddbebb459ceNicolas Roard    final static int DOWNLOAD_PAGE              = 2;
387978a98e459323f938e97789a6131beddbebb459ceNicolas Roard    final static int PREFERENCES_PAGE           = 3;
38808d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins    final static int FILE_SELECTED              = 4;
38810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
3882540035dfd1347c78eeec10ec0847e18fcc50ef36Andrei Popescu    // the default <video> poster
3883540035dfd1347c78eeec10ec0847e18fcc50ef36Andrei Popescu    private Bitmap mDefaultVideoPoster;
3884540035dfd1347c78eeec10ec0847e18fcc50ef36Andrei Popescu    // the video progress view
3885540035dfd1347c78eeec10ec0847e18fcc50ef36Andrei Popescu    private View mVideoProgressView;
3886540035dfd1347c78eeec10ec0847e18fcc50ef36Andrei Popescu
388725ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima    /**
388825ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima     * A UrlData class to abstract how the content will be set to WebView.
388925ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima     * This base class uses loadUrl to show the content.
389025ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima     */
389125ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima    private static class UrlData {
3892068e48b469f5abca53ee3da38f933cf2c25c93b8Grace Kloba        final String mUrl;
3893068e48b469f5abca53ee3da38f933cf2c25c93b8Grace Kloba        final Map<String, String> mHeaders;
389460e095c190496d42327f8ec2ef990c044d15a76fGrace Kloba
389525ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima        UrlData(String url) {
389625ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima            this.mUrl = url;
3897068e48b469f5abca53ee3da38f933cf2c25c93b8Grace Kloba            this.mHeaders = null;
389825ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima        }
389960e095c190496d42327f8ec2ef990c044d15a76fGrace Kloba
3900068e48b469f5abca53ee3da38f933cf2c25c93b8Grace Kloba        UrlData(String url, Map<String, String> headers) {
3901068e48b469f5abca53ee3da38f933cf2c25c93b8Grace Kloba            this.mUrl = url;
3902068e48b469f5abca53ee3da38f933cf2c25c93b8Grace Kloba            this.mHeaders = headers;
390360e095c190496d42327f8ec2ef990c044d15a76fGrace Kloba        }
390460e095c190496d42327f8ec2ef990c044d15a76fGrace Kloba
390525ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima        boolean isEmpty() {
390625ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima            return mUrl == null || mUrl.length() == 0;
390725ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima        }
390825ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima
39097944b7def8b04c3dc0cb8815a8527aba8c91b219Mitsuru Oshima        public void loadIn(WebView webView) {
3910068e48b469f5abca53ee3da38f933cf2c25c93b8Grace Kloba            webView.loadUrl(mUrl, mHeaders);
391125ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima        }
391225ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima    };
391325ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima
39141f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins    /* package */ static final UrlData EMPTY_URL_DATA = new UrlData(null);
39150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project}
3916