BrowserActivity.java revision 3b18ce37c13fce7212948df90a012d7011924a6e
10c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project/*
20c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project * Copyright (C) 2006 The Android Open Source Project
30c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project *
40c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
50c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project * you may not use this file except in compliance with the License.
60c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project * You may obtain a copy of the License at
70c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project *
80c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
90c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project *
100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project * Unless required by applicable law or agreed to in writing, software
110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project * See the License for the specific language governing permissions and
140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project * limitations under the License.
150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project */
160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectpackage com.android.browser;
180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.app.Activity;
200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.app.AlertDialog;
210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.app.ProgressDialog;
220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.app.SearchManager;
230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.content.ActivityNotFoundException;
240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.content.BroadcastReceiver;
250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.content.ComponentName;
2658d56c6b5052faa86083965132cd51b1a9594d0eLeon Scrogginsimport android.content.ContentProvider;
2758d56c6b5052faa86083965132cd51b1a9594d0eLeon Scrogginsimport android.content.ContentProviderClient;
280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.content.ContentResolver;
29b6b7f9ef3b4ed220063f555d8b7c205210a61a04Leon Scrogginsimport android.content.ContentUris;
300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.content.ContentValues;
310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.content.Context;
320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.content.DialogInterface;
330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.content.Intent;
340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.content.IntentFilter;
35b4da0ad0351996f639b50f9f29b123a9b5c24fd0Grace Klobaimport android.content.pm.PackageInfo;
360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.content.pm.PackageManager;
370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.content.pm.ResolveInfo;
380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.content.res.Configuration;
390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.content.res.Resources;
400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.database.Cursor;
4196afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scrogginsimport android.database.DatabaseUtils;
420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.graphics.Bitmap;
43540035dfd1347c78eeec10ec0847e18fcc50ef36Andrei Popescuimport android.graphics.BitmapFactory;
440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.graphics.Canvas;
450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.graphics.Picture;
463bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scrogginsimport android.graphics.PixelFormat;
473bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scrogginsimport android.graphics.Rect;
480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.graphics.drawable.Drawable;
490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.net.ConnectivityManager;
5056199cc25e7ee0455ec2a8099098b66b8554f677Andrei Popescuimport android.net.NetworkInfo;
510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.net.Uri;
520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.net.WebAddress;
530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.net.http.SslCertificate;
540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.net.http.SslError;
550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.os.AsyncTask;
560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.os.Bundle;
570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.os.Debug;
580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.os.Environment;
590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.os.Handler;
600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.os.Message;
610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.os.PowerManager;
620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.os.Process;
630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.os.ServiceManager;
640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.os.SystemClock;
650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.provider.Browser;
665e335a381a0cd66e94117b202c1f34f5cb29c9b8Cary Clarkimport android.provider.ContactsContract;
675e335a381a0cd66e94117b202c1f34f5cb29c9b8Cary Clarkimport android.provider.ContactsContract.Intents.Insert;
680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.provider.Downloads;
690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.provider.MediaStore;
70a1cc3fdce19a336c251297c61cd83ac6cf767cd1Leon Scrogginsimport android.speech.RecognizerResultsIntent;
710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.text.IClipboard;
720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.text.TextUtils;
730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.text.format.DateFormat;
74b94bf27370329abb27e5e33b493d6edb5662b36eLeon Scrogginsimport android.util.AttributeSet;
750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.util.Log;
760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.view.ContextMenu;
770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.view.Gravity;
780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.view.KeyEvent;
790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.view.LayoutInflater;
800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.view.Menu;
810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.view.MenuInflater;
820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.view.MenuItem;
830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.view.View;
840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.view.ViewGroup;
850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.view.Window;
860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.view.WindowManager;
870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.view.ContextMenu.ContextMenuInfo;
880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.view.MenuItem.OnMenuItemClickListener;
890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.webkit.CookieManager;
900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.webkit.CookieSyncManager;
910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.webkit.DownloadListener;
920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.webkit.HttpAuthHandler;
93b4da0ad0351996f639b50f9f29b123a9b5c24fd0Grace Klobaimport android.webkit.PluginManager;
940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.webkit.SslErrorHandler;
950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.webkit.URLUtil;
96cb6cc864e53f7d916622daf3b2cec133b36d6a55Leon Clarkeimport android.webkit.ValueCallback;
970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.webkit.WebChromeClient;
980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.webkit.WebHistoryItem;
990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.webkit.WebIconDatabase;
1000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.webkit.WebView;
1010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.widget.EditText;
1020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.widget.FrameLayout;
1030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.widget.LinearLayout;
1040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.widget.TextView;
1050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.widget.Toast;
106752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintanaimport android.accounts.Account;
107752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintanaimport android.accounts.AccountManager;
108752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintanaimport android.accounts.AccountManagerFuture;
109752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintanaimport android.accounts.AuthenticatorException;
110752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintanaimport android.accounts.OperationCanceledException;
111752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintanaimport android.accounts.AccountManagerCallback;
1120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
1135ee906c089567bca705e18561357510d7b55cb5aDan Egnorimport com.android.common.Patterns;
1145ee906c089567bca705e18561357510d7b55cb5aDan Egnor
115716d4f542daec3588f45cbc5cb3acc825233b8a1Doug Zongkerimport com.google.android.gsf.GoogleLoginServiceConstants;
1165ee906c089567bca705e18561357510d7b55cb5aDan Egnor
117b6b7f9ef3b4ed220063f555d8b7c205210a61a04Leon Scrogginsimport java.io.ByteArrayOutputStream;
1180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport java.io.File;
1194f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdochimport java.io.IOException;
1204f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdochimport java.io.InputStream;
1210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport java.net.MalformedURLException;
1220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport java.net.URI;
1239918943559193e3e047a1c18442e2cdb0fe22b15Dianne Hackbornimport java.net.URISyntaxException;
1240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport java.net.URL;
1250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport java.net.URLEncoder;
1260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport java.text.ParseException;
1270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport java.util.Date;
1280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport java.util.HashMap;
12900f54c589fd38431efd42ea2a551a49e64d595d5Grace Klobaimport java.util.Iterator;
130068e48b469f5abca53ee3da38f933cf2c25c93b8Grace Klobaimport java.util.Map;
1310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport java.util.regex.Matcher;
1320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport java.util.regex.Pattern;
1330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
1340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectpublic class BrowserActivity extends Activity
135752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana    implements View.OnCreateContextMenuListener, DownloadListener,
136752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana        AccountManagerCallback<Account[]> {
1370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
13831a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort    /* Define some aliases to make these debugging flags easier to refer to.
13931a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort     * This file imports android.provider.Browser, so we can't just refer to "Browser.DEBUG".
14031a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort     */
14131a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort    private final static boolean DEBUG = com.android.browser.Browser.DEBUG;
14231a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort    private final static boolean LOGV_ENABLED = com.android.browser.Browser.LOGV_ENABLED;
14331a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort    private final static boolean LOGD_ENABLED = com.android.browser.Browser.LOGD_ENABLED;
14431a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort
145565505b1a2c1d3099496af5910760087602e994aSatish Sampath    // These are single-character shortcuts for searching popular sources.
146565505b1a2c1d3099496af5910760087602e994aSatish Sampath    private static final int SHORTCUT_INVALID = 0;
147565505b1a2c1d3099496af5910760087602e994aSatish Sampath    private static final int SHORTCUT_GOOGLE_SEARCH = 1;
148565505b1a2c1d3099496af5910760087602e994aSatish Sampath    private static final int SHORTCUT_WIKIPEDIA_SEARCH = 2;
149565505b1a2c1d3099496af5910760087602e994aSatish Sampath    private static final int SHORTCUT_DICTIONARY_SEARCH = 3;
150565505b1a2c1d3099496af5910760087602e994aSatish Sampath    private static final int SHORTCUT_GOOGLE_MOBILE_LOCAL_SEARCH = 4;
151565505b1a2c1d3099496af5910760087602e994aSatish Sampath
152752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana    private Account[] mAccountsGoogle;
153752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana    private Account[] mAccountsPreferHosted;
1540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
155752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana    private void startReadOfGoogleAccounts() {
156752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana        mAccountsGoogle = null;
157752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana        mAccountsPreferHosted = null;
1580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
159752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana        AccountManager.get(this).getAccountsByTypeAndFeatures(
160752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana                GoogleLoginServiceConstants.ACCOUNT_TYPE,
161752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana                new String[]{GoogleLoginServiceConstants.FEATURE_LEGACY_HOSTED_OR_GOOGLE},
162752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana                this, null);
163752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana    }
164752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana
165752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana    /** This implements AccountManagerCallback<Account[]> */
166752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana    public void run(AccountManagerFuture<Account[]> accountManagerFuture) {
167752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana        try {
168752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana            if (mAccountsGoogle == null) {
169752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana                mAccountsGoogle = accountManagerFuture.getResult();
170752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana
171752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana                AccountManager.get(this).getAccountsByTypeAndFeatures(
172752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana                        GoogleLoginServiceConstants.ACCOUNT_TYPE,
173752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana                        new String[]{GoogleLoginServiceConstants.FEATURE_LEGACY_GOOGLE},
174752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana                        this, null);
175752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana            } else {
176752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana                mAccountsPreferHosted = accountManagerFuture.getResult();
177752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana                setupHomePage();
1780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
179752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana        } catch (OperationCanceledException e) {
180752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana            setupHomePage();
181752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana        } catch (IOException e) {
182752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana            setupHomePage();
183752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana        } catch (AuthenticatorException e) {
184752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana            setupHomePage();
185752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana        }
186752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana    }
187752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana
188752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana    private void setupHomePage() {
189752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana        // get the default home page
190752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana        String homepage = mSettings.getHomePage();
191752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana
192752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana        if (mAccountsPreferHosted != null && mAccountsGoogle != null) {
193752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana            // three cases:
194752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana            //
195752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana            //   hostedUser == googleUser
196752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana            //      The device has only a google account
197752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana            //
198752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana            //   hostedUser != googleUser
199752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana            //      The device has a hosted account and a google account
200752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana            //
201752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana            //   hostedUser != null, googleUser == null
202752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana            //      The device has only a hosted account (so far)
203752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana            String hostedUser = mAccountsPreferHosted.length == 0
204752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana                    ? null
205752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana                    : mAccountsPreferHosted[0].name;
206752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana            String googleUser = mAccountsGoogle.length == 0 ? null : mAccountsGoogle[0].name;
207752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana
208752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana            // developers might have no accounts at all
209752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana            if (hostedUser == null) return;
210752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana
211752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana            if (googleUser == null || !hostedUser.equals(googleUser)) {
212752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana                String domain = hostedUser.substring(hostedUser.lastIndexOf('@')+1);
213752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana                homepage = homepage.replace("?", "/a/" + domain + "?");
2140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
215752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana        }
2160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
217752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana        mSettings.setHomePage(BrowserActivity.this, homepage);
218752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana        resumeAfterCredentials();
2190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
2200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
221a977124eb29b195127fd161120ebbc58b255fb48Cary Clark    private static class ClearThumbnails extends AsyncTask<File, Void, Void> {
2220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        @Override
2230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public Void doInBackground(File... files) {
2240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (files != null) {
2250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                for (File f : files) {
226d6be1758b38d5b066ff10b6af906aa66c63670cdCary Clark                    if (!f.delete()) {
227d6be1758b38d5b066ff10b6af906aa66c63670cdCary Clark                      Log.e(LOGTAG, f.getPath() + " was not deleted");
228d6be1758b38d5b066ff10b6af906aa66c63670cdCary Clark                    }
2290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
2300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
2310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return null;
2320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
2330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
2340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
2353bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    /**
2363bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     * This layout holds everything you see below the status bar, including the
2373bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     * error console, the custom view container, and the webviews.
2383bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     */
2393bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    private FrameLayout mBrowserFrameLayout;
24081db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins
24122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    @Override
24222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    public void onCreate(Bundle icicle) {
24331a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort        if (LOGV_ENABLED) {
2440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Log.v(LOGTAG, this + " onStart");
2450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
2460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        super.onCreate(icicle);
2470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // test the browser in OpenGL
2480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // requestWindowFeature(Window.FEATURE_OPENGL);
2490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
250d334bf564b72416e77e707d25f8c55cfe1d85709Mike Reed        // enable this to test the browser in 32bit
251d334bf564b72416e77e707d25f8c55cfe1d85709Mike Reed        if (false) {
252d334bf564b72416e77e707d25f8c55cfe1d85709Mike Reed            getWindow().setFormat(PixelFormat.RGBX_8888);
253d334bf564b72416e77e707d25f8c55cfe1d85709Mike Reed            BitmapFactory.setDefaultConfig(Bitmap.Config.ARGB_8888);
254d334bf564b72416e77e707d25f8c55cfe1d85709Mike Reed        }
255d334bf564b72416e77e707d25f8c55cfe1d85709Mike Reed
2560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        setDefaultKeyMode(DEFAULT_KEYS_SEARCH_LOCAL);
2570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
2580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mResolver = getContentResolver();
2590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
2600923d69a8ca45222cabd82a80eaa88da9f132e9aGrace Kloba        // If this was a web search request, pass it on to the default web
2610923d69a8ca45222cabd82a80eaa88da9f132e9aGrace Kloba        // search provider and finish this activity.
2620923d69a8ca45222cabd82a80eaa88da9f132e9aGrace Kloba        if (handleWebSearchIntent(getIntent())) {
2630923d69a8ca45222cabd82a80eaa88da9f132e9aGrace Kloba            finish();
2640923d69a8ca45222cabd82a80eaa88da9f132e9aGrace Kloba            return;
2650923d69a8ca45222cabd82a80eaa88da9f132e9aGrace Kloba        }
2660923d69a8ca45222cabd82a80eaa88da9f132e9aGrace Kloba
2670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mSecLockIcon = Resources.getSystem().getDrawable(
2680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                android.R.drawable.ic_secure);
2690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mMixLockIcon = Resources.getSystem().getDrawable(
2700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                android.R.drawable.ic_partial_secure);
2710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
27281db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins        FrameLayout frameLayout = (FrameLayout) getWindow().getDecorView()
27381db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins                .findViewById(com.android.internal.R.id.content);
2743bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins        mBrowserFrameLayout = (FrameLayout) LayoutInflater.from(this)
2753bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                .inflate(R.layout.custom_screen, null);
2763bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins        mContentView = (FrameLayout) mBrowserFrameLayout.findViewById(
2773bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                R.id.main_content);
2783bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins        mErrorConsoleContainer = (LinearLayout) mBrowserFrameLayout
2793bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                .findViewById(R.id.error_console);
2803bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins        mCustomViewContainer = (FrameLayout) mBrowserFrameLayout
2813bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                .findViewById(R.id.fullscreen_custom_content);
2823bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins        frameLayout.addView(mBrowserFrameLayout, COVER_SCREEN_PARAMS);
28368579393973f745fc65a2781061af9bb8f2d7020Leon Scroggins        mTitleBar = new TitleBar(this);
284fe87bd3a3897e4bad65bb3d284659ae2f4e57570Leon Scroggins        mFakeTitleBar = new TitleBar(this);
2850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
2860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Create the tab control and our initial tab
2870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mTabControl = new TabControl(this);
2880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
2890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Open the icon database and retain all the bookmark urls for favicons
2900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        retainIconsOnStartup();
2910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
2920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Keep a settings instance handy.
2930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mSettings = BrowserSettings.getInstance();
2940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mSettings.setTabControl(mTabControl);
2950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mSettings.loadFromDb(this);
2960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
2970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
2980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "Browser");
2990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
300a34f686112fb4f9fbea00b8c2c47153d34e93e41Grace Kloba        /* enables registration for changes in network status from
301a34f686112fb4f9fbea00b8c2c47153d34e93e41Grace Kloba           http stack */
302a34f686112fb4f9fbea00b8c2c47153d34e93e41Grace Kloba        mNetworkStateChangedFilter = new IntentFilter();
303a34f686112fb4f9fbea00b8c2c47153d34e93e41Grace Kloba        mNetworkStateChangedFilter.addAction(
304a34f686112fb4f9fbea00b8c2c47153d34e93e41Grace Kloba                ConnectivityManager.CONNECTIVITY_ACTION);
305a34f686112fb4f9fbea00b8c2c47153d34e93e41Grace Kloba        mNetworkStateIntentReceiver = new BroadcastReceiver() {
306a34f686112fb4f9fbea00b8c2c47153d34e93e41Grace Kloba                @Override
307a34f686112fb4f9fbea00b8c2c47153d34e93e41Grace Kloba                public void onReceive(Context context, Intent intent) {
308a34f686112fb4f9fbea00b8c2c47153d34e93e41Grace Kloba                    if (intent.getAction().equals(
309a34f686112fb4f9fbea00b8c2c47153d34e93e41Grace Kloba                            ConnectivityManager.CONNECTIVITY_ACTION)) {
3107d899d6f5364a5b20716497a3be5e2f778a2bc0eRobert Greenwalt                        boolean noConnectivity = intent.getBooleanExtra(
3117d899d6f5364a5b20716497a3be5e2f778a2bc0eRobert Greenwalt                                ConnectivityManager.EXTRA_NO_CONNECTIVITY, false);
31256199cc25e7ee0455ec2a8099098b66b8554f677Andrei Popescu                        if (!noConnectivity) {
31356199cc25e7ee0455ec2a8099098b66b8554f677Andrei Popescu                            NetworkInfo info = intent.getParcelableExtra(
31456199cc25e7ee0455ec2a8099098b66b8554f677Andrei Popescu                                    ConnectivityManager.EXTRA_NETWORK_INFO);
31556199cc25e7ee0455ec2a8099098b66b8554f677Andrei Popescu                            String typeName = info.getTypeName();
31656199cc25e7ee0455ec2a8099098b66b8554f677Andrei Popescu                            String subtypeName = info.getSubtypeName();
31756199cc25e7ee0455ec2a8099098b66b8554f677Andrei Popescu                            sendNetworkType(typeName.toLowerCase(),
31856199cc25e7ee0455ec2a8099098b66b8554f677Andrei Popescu                                    (subtypeName != null ? subtypeName.toLowerCase() : ""));
31956199cc25e7ee0455ec2a8099098b66b8554f677Andrei Popescu                        }
3207d899d6f5364a5b20716497a3be5e2f778a2bc0eRobert Greenwalt                        onNetworkToggle(!noConnectivity);
321a34f686112fb4f9fbea00b8c2c47153d34e93e41Grace Kloba                    }
322a34f686112fb4f9fbea00b8c2c47153d34e93e41Grace Kloba                }
323a34f686112fb4f9fbea00b8c2c47153d34e93e41Grace Kloba            };
324a34f686112fb4f9fbea00b8c2c47153d34e93e41Grace Kloba
325615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba        IntentFilter filter = new IntentFilter(Intent.ACTION_PACKAGE_ADDED);
326615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba        filter.addAction(Intent.ACTION_PACKAGE_REMOVED);
327615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba        filter.addDataScheme("package");
328615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba        mPackageInstallationReceiver = new BroadcastReceiver() {
329615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba            @Override
330615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba            public void onReceive(Context context, Intent intent) {
331615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                final String action = intent.getAction();
332615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                final String packageName = intent.getData()
333615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                        .getSchemeSpecificPart();
334615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                final boolean replacing = intent.getBooleanExtra(
335615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                        Intent.EXTRA_REPLACING, false);
336615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                if (Intent.ACTION_PACKAGE_REMOVED.equals(action) && replacing) {
337615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                    // if it is replacing, refreshPlugins() when adding
338615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                    return;
339615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                }
340615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                PackageManager pm = BrowserActivity.this.getPackageManager();
341615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                PackageInfo pkgInfo = null;
342615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                try {
343615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                    pkgInfo = pm.getPackageInfo(packageName,
344615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                            PackageManager.GET_PERMISSIONS);
345615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                } catch (PackageManager.NameNotFoundException e) {
346615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                    return;
347615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                }
348615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                if (pkgInfo != null) {
349615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                    String permissions[] = pkgInfo.requestedPermissions;
350615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                    if (permissions == null) {
351615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                        return;
352615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                    }
353615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                    boolean permissionOk = false;
354615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                    for (String permit : permissions) {
355615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                        if (PluginManager.PLUGIN_PERMISSION.equals(permit)) {
356615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                            permissionOk = true;
357615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                            break;
358615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                        }
359615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                    }
360615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                    if (permissionOk) {
361615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                        PluginManager.getInstance(BrowserActivity.this)
362615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                                .refreshPlugins(
363615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                                        Intent.ACTION_PACKAGE_ADDED
364615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                                                .equals(action));
365615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                    }
366615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                }
367615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba            }
368615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba        };
369615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba        registerReceiver(mPackageInstallationReceiver, filter);
370615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba
3710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (!mTabControl.restoreState(icicle)) {
3720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // clear up the thumbnail directory if we can't restore the state as
3730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // none of the files in the directory are referenced any more.
3740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            new ClearThumbnails().execute(
3750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    mTabControl.getThumbnailDir().listFiles());
376aab3f09b5c2d39b19067e57635614080b2403a46Grace Kloba            // there is no quit on Android. But if we can't restore the state,
377aab3f09b5c2d39b19067e57635614080b2403a46Grace Kloba            // we can treat it as a new Browser, remove the old session cookies.
378aab3f09b5c2d39b19067e57635614080b2403a46Grace Kloba            CookieManager.getInstance().removeSessionCookie();
3790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            final Intent intent = getIntent();
3800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            final Bundle extra = intent.getExtras();
3810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Create an initial tab.
3820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // If the intent is ACTION_VIEW and data is not null, the Browser is
3830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // invoked to view the content by another application. In this case,
3840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // the tab will be close when exit.
38525ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima            UrlData urlData = getUrlDataFromIntent(intent);
38625ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima
38758d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins            String action = intent.getAction();
38822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            final Tab t = mTabControl.createNewTab(
38958d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins                    (Intent.ACTION_VIEW.equals(action) &&
39058d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins                    intent.getData() != null)
391a1cc3fdce19a336c251297c61cd83ac6cf767cd1Leon Scroggins                    || RecognizerResultsIntent.ACTION_VOICE_SEARCH_RESULTS
392a1cc3fdce19a336c251297c61cd83ac6cf767cd1Leon Scroggins                    .equals(action),
39325ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima                    intent.getStringExtra(Browser.EXTRA_APPLICATION_ID), urlData.mUrl);
3940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mTabControl.setCurrentTab(t);
3950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            attachTabToContentView(t);
3960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            WebView webView = t.getWebView();
3970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (extra != null) {
3980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                int scale = extra.getInt(Browser.INITIAL_ZOOM_LEVEL, 0);
3990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (scale > 0 && scale <= 1000) {
4000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    webView.setInitialScale(scale);
4010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
4020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
4030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // If we are not restoring from an icicle, then there is a high
4040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // likely hood this is the first run. So, check to see if the
4050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // homepage needs to be configured and copy any plugins from our
4060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // asset directory to the data partition.
4070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if ((extra == null || !extra.getBoolean("testing"))
4080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    && !mSettings.isLoginInitialized()) {
409752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana                startReadOfGoogleAccounts();
4100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
4110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
41225ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima            if (urlData.isEmpty()) {
413304442375719effd41dbd53ae62de7a8d0cec7d9Leon Scroggins                if (mSettings.isLoginInitialized()) {
414304442375719effd41dbd53ae62de7a8d0cec7d9Leon Scroggins                    webView.loadUrl(mSettings.getHomePage());
415304442375719effd41dbd53ae62de7a8d0cec7d9Leon Scroggins                } else {
416304442375719effd41dbd53ae62de7a8d0cec7d9Leon Scroggins                    waitForCredentials();
417304442375719effd41dbd53ae62de7a8d0cec7d9Leon Scroggins                }
4180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } else {
41958d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins                urlData.loadIn(t);
4200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
4210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
4220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // TabControl.restoreState() will create a new tab even if
4231f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins            // restoring the state fails.
4240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            attachTabToContentView(mTabControl.getCurrentTab());
4250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
426615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba
427b3c02da4553b1a629b16377970fdabae28394c94Feng Qian        // Read JavaScript flags if it exists.
428b3c02da4553b1a629b16377970fdabae28394c94Feng Qian        String jsFlags = mSettings.getJsFlags();
429b3c02da4553b1a629b16377970fdabae28394c94Feng Qian        if (jsFlags.trim().length() != 0) {
430b3c02da4553b1a629b16377970fdabae28394c94Feng Qian            mTabControl.getCurrentWebView().setJsFlags(jsFlags);
431b3c02da4553b1a629b16377970fdabae28394c94Feng Qian        }
4320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
4330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
43458d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    /**
43558d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins     * Feed the previously stored results strings to the BrowserProvider so that
43658d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins     * the SearchDialog will show them instead of the standard searches.
43758d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins     * @param result String to show on the editable line of the SearchDialog.
43858d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins     */
43958d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    /* package */ void showVoiceSearchResults(String result) {
44058d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        ContentProviderClient client = mResolver.acquireContentProviderClient(
44158d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins                Browser.BOOKMARKS_URI);
44258d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        ContentProvider prov = client.getLocalContentProvider();
44358d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        BrowserProvider bp = (BrowserProvider) prov;
44458d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        bp.setQueryResults(mTabControl.getCurrentTab().getVoiceSearchResults());
44558d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        client.release();
44658d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins
44758d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        startSearch(result, false,
44858d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins                createGoogleSearchSourceBundle(GOOGLE_SEARCH_SOURCE_SEARCHKEY),
44958d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins                false);
45058d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    }
45158d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins
4520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    @Override
4530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    protected void onNewIntent(Intent intent) {
45422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        Tab current = mTabControl.getCurrentTab();
4550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // When a tab is closed on exit, the current tab index is set to -1.
4560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Reset before proceed as Browser requires the current tab to be set.
4570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (current == null) {
4580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Try to reset the tab in case the index was incorrect.
4590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            current = mTabControl.getTab(0);
4600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (current == null) {
4610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // No tabs at all so just ignore this intent.
4620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                return;
4630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
4640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mTabControl.setCurrentTab(current);
4650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            attachTabToContentView(current);
4660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            resetTitleAndIcon(current.getWebView());
4670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
4680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final String action = intent.getAction();
4690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final int flags = intent.getFlags();
4700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (Intent.ACTION_MAIN.equals(action) ||
4710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                (flags & Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY) != 0) {
4720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // just resume the browser
4730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
4740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
475a1cc3fdce19a336c251297c61cd83ac6cf767cd1Leon Scroggins        boolean activateVoiceSearch = RecognizerResultsIntent
476a1cc3fdce19a336c251297c61cd83ac6cf767cd1Leon Scroggins                .ACTION_VOICE_SEARCH_RESULTS.equals(action);
4770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (Intent.ACTION_VIEW.equals(action)
4780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                || Intent.ACTION_SEARCH.equals(action)
4790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                || MediaStore.INTENT_ACTION_MEDIA_SEARCH.equals(action)
48058d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins                || Intent.ACTION_WEB_SEARCH.equals(action)
48158d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins                || activateVoiceSearch) {
4823b18ce37c13fce7212948df90a012d7011924a6eLeon Scroggins            if (current.isInVoiceSearchMode()) {
4833b18ce37c13fce7212948df90a012d7011924a6eLeon Scroggins                String title = current.getVoiceDisplayTitle();
4843b18ce37c13fce7212948df90a012d7011924a6eLeon Scroggins                if (title != null && title.equals(intent.getStringExtra(
4853b18ce37c13fce7212948df90a012d7011924a6eLeon Scroggins                        SearchManager.QUERY))) {
4863b18ce37c13fce7212948df90a012d7011924a6eLeon Scroggins                    // The user submitted the same search as the last voice
4873b18ce37c13fce7212948df90a012d7011924a6eLeon Scroggins                    // search, so do nothing.
4883b18ce37c13fce7212948df90a012d7011924a6eLeon Scroggins                    return;
4893b18ce37c13fce7212948df90a012d7011924a6eLeon Scroggins                }
4903b18ce37c13fce7212948df90a012d7011924a6eLeon Scroggins            }
491565505b1a2c1d3099496af5910760087602e994aSatish Sampath            // If this was a search request (e.g. search query directly typed into the address bar),
492565505b1a2c1d3099496af5910760087602e994aSatish Sampath            // pass it on to the default web search provider.
493565505b1a2c1d3099496af5910760087602e994aSatish Sampath            if (handleWebSearchIntent(intent)) {
494565505b1a2c1d3099496af5910760087602e994aSatish Sampath                return;
495565505b1a2c1d3099496af5910760087602e994aSatish Sampath            }
496565505b1a2c1d3099496af5910760087602e994aSatish Sampath
49725ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima            UrlData urlData = getUrlDataFromIntent(intent);
49825ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima            if (urlData.isEmpty()) {
49925ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima                urlData = new UrlData(mSettings.getHomePage());
5000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
50125ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima
502cc63403643786905262f505ab5266d8e80b9924cGrace Kloba            final String appId = intent
503cc63403643786905262f505ab5266d8e80b9924cGrace Kloba                    .getStringExtra(Browser.EXTRA_APPLICATION_ID);
50458d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins            if ((Intent.ACTION_VIEW.equals(action) || activateVoiceSearch)
505cc63403643786905262f505ab5266d8e80b9924cGrace Kloba                    && !getPackageName().equals(appId)
506cc63403643786905262f505ab5266d8e80b9924cGrace Kloba                    && (flags & Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT) != 0) {
50722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                Tab appTab = mTabControl.getTabFromId(appId);
508f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                if (appTab != null) {
509f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    Log.i(LOGTAG, "Reusing tab for " + appId);
510f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    // Dismiss the subwindow if applicable.
511f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    dismissSubWindow(appTab);
512f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    // Since we might kill the WebView, remove it from the
513f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    // content view first.
514f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    removeTabFromContentView(appTab);
515f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    // Recreate the main WebView after destroying the old one.
516f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    // If the WebView has the same original url and is on that
517f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    // page, it can be reused.
518f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    boolean needsLoad =
51925ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima                            mTabControl.recreateWebView(appTab, urlData.mUrl);
520bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch
521f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    if (current != appTab) {
5221f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                        switchToTab(mTabControl.getTabIndex(appTab));
5231f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                        if (needsLoad) {
52458d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins                            urlData.loadIn(appTab);
5251f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                        }
526f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    } else {
5271f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                        // If the tab was the current tab, we have to attach
5281f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                        // it to the view system again.
5291f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                        attachTabToContentView(appTab);
5301f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                        if (needsLoad) {
53158d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins                            urlData.loadIn(appTab);
532f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                        }
533f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    }
534f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    return;
535cd11589fc3930906d4b9b7dd18aa52a9f1eb0c8aPatrick Scott                } else {
536cd11589fc3930906d4b9b7dd18aa52a9f1eb0c8aPatrick Scott                    // No matching application tab, try to find a regular tab
537cd11589fc3930906d4b9b7dd18aa52a9f1eb0c8aPatrick Scott                    // with a matching url.
538cd11589fc3930906d4b9b7dd18aa52a9f1eb0c8aPatrick Scott                    appTab = mTabControl.findUnusedTabWithUrl(urlData.mUrl);
53925515f8bd458a2471d13d876cfb0e18d8ff2a00fLeon Scroggins                    if (appTab != null) {
54025515f8bd458a2471d13d876cfb0e18d8ff2a00fLeon Scroggins                        if (current != appTab) {
54125515f8bd458a2471d13d876cfb0e18d8ff2a00fLeon Scroggins                            switchToTab(mTabControl.getTabIndex(appTab));
54225515f8bd458a2471d13d876cfb0e18d8ff2a00fLeon Scroggins                        }
54325515f8bd458a2471d13d876cfb0e18d8ff2a00fLeon Scroggins                        // Otherwise, we are already viewing the correct tab.
544cd11589fc3930906d4b9b7dd18aa52a9f1eb0c8aPatrick Scott                    } else {
545cd11589fc3930906d4b9b7dd18aa52a9f1eb0c8aPatrick Scott                        // if FLAG_ACTIVITY_BROUGHT_TO_FRONT flag is on, the url
546cd11589fc3930906d4b9b7dd18aa52a9f1eb0c8aPatrick Scott                        // will be opened in a new tab unless we have reached
547cd11589fc3930906d4b9b7dd18aa52a9f1eb0c8aPatrick Scott                        // MAX_TABS. Then the url will be opened in the current
548cd11589fc3930906d4b9b7dd18aa52a9f1eb0c8aPatrick Scott                        // tab. If a new tab is created, it will have "true" for
549cd11589fc3930906d4b9b7dd18aa52a9f1eb0c8aPatrick Scott                        // exit on close.
5501f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                        openTabAndShow(urlData, true, appId);
551cd11589fc3930906d4b9b7dd18aa52a9f1eb0c8aPatrick Scott                    }
552f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                }
5530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } else {
554638d3f45791a31d0b290e180b93bad49576eb6d3Grace Kloba                if (!urlData.isEmpty()
555638d3f45791a31d0b290e180b93bad49576eb6d3Grace Kloba                        && urlData.mUrl.startsWith("about:debug")) {
556638d3f45791a31d0b290e180b93bad49576eb6d3Grace Kloba                    if ("about:debug.dom".equals(urlData.mUrl)) {
557638d3f45791a31d0b290e180b93bad49576eb6d3Grace Kloba                        current.getWebView().dumpDomTree(false);
558638d3f45791a31d0b290e180b93bad49576eb6d3Grace Kloba                    } else if ("about:debug.dom.file".equals(urlData.mUrl)) {
559638d3f45791a31d0b290e180b93bad49576eb6d3Grace Kloba                        current.getWebView().dumpDomTree(true);
560638d3f45791a31d0b290e180b93bad49576eb6d3Grace Kloba                    } else if ("about:debug.render".equals(urlData.mUrl)) {
561638d3f45791a31d0b290e180b93bad49576eb6d3Grace Kloba                        current.getWebView().dumpRenderTree(false);
562638d3f45791a31d0b290e180b93bad49576eb6d3Grace Kloba                    } else if ("about:debug.render.file".equals(urlData.mUrl)) {
563638d3f45791a31d0b290e180b93bad49576eb6d3Grace Kloba                        current.getWebView().dumpRenderTree(true);
564638d3f45791a31d0b290e180b93bad49576eb6d3Grace Kloba                    } else if ("about:debug.display".equals(urlData.mUrl)) {
565638d3f45791a31d0b290e180b93bad49576eb6d3Grace Kloba                        current.getWebView().dumpDisplayTree();
5669b78e1d1e0bd819ae03df5594d4a56519e5d87c7Mike Reed                    } else if (urlData.mUrl.startsWith("about:debug.drag")) {
5679b78e1d1e0bd819ae03df5594d4a56519e5d87c7Mike Reed                        int index = urlData.mUrl.codePointAt(16) - '0';
5689b78e1d1e0bd819ae03df5594d4a56519e5d87c7Mike Reed                        if (index <= 0 || index > 9) {
5699b78e1d1e0bd819ae03df5594d4a56519e5d87c7Mike Reed                            current.getWebView().setDragTracker(null);
5709b78e1d1e0bd819ae03df5594d4a56519e5d87c7Mike Reed                        } else {
5719b78e1d1e0bd819ae03df5594d4a56519e5d87c7Mike Reed                            current.getWebView().setDragTracker(new MeshTracker(index));
5729b78e1d1e0bd819ae03df5594d4a56519e5d87c7Mike Reed                        }
573638d3f45791a31d0b290e180b93bad49576eb6d3Grace Kloba                    } else {
574638d3f45791a31d0b290e180b93bad49576eb6d3Grace Kloba                        mSettings.toggleDebugSettings();
575638d3f45791a31d0b290e180b93bad49576eb6d3Grace Kloba                    }
5760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    return;
5770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
5781f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                // Get rid of the subwindow if it exists
5791f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                dismissSubWindow(current);
58058d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins                urlData.loadIn(current);
5810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
5820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
5830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
5840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
585565505b1a2c1d3099496af5910760087602e994aSatish Sampath    private int parseUrlShortcut(String url) {
586565505b1a2c1d3099496af5910760087602e994aSatish Sampath        if (url == null) return SHORTCUT_INVALID;
587565505b1a2c1d3099496af5910760087602e994aSatish Sampath
588565505b1a2c1d3099496af5910760087602e994aSatish Sampath        // FIXME: quick search, need to be customized by setting
589565505b1a2c1d3099496af5910760087602e994aSatish Sampath        if (url.length() > 2 && url.charAt(1) == ' ') {
590565505b1a2c1d3099496af5910760087602e994aSatish Sampath            switch (url.charAt(0)) {
591565505b1a2c1d3099496af5910760087602e994aSatish Sampath            case 'g': return SHORTCUT_GOOGLE_SEARCH;
592565505b1a2c1d3099496af5910760087602e994aSatish Sampath            case 'w': return SHORTCUT_WIKIPEDIA_SEARCH;
593565505b1a2c1d3099496af5910760087602e994aSatish Sampath            case 'd': return SHORTCUT_DICTIONARY_SEARCH;
594565505b1a2c1d3099496af5910760087602e994aSatish Sampath            case 'l': return SHORTCUT_GOOGLE_MOBILE_LOCAL_SEARCH;
595565505b1a2c1d3099496af5910760087602e994aSatish Sampath            }
596565505b1a2c1d3099496af5910760087602e994aSatish Sampath        }
597565505b1a2c1d3099496af5910760087602e994aSatish Sampath        return SHORTCUT_INVALID;
598565505b1a2c1d3099496af5910760087602e994aSatish Sampath    }
599565505b1a2c1d3099496af5910760087602e994aSatish Sampath
600565505b1a2c1d3099496af5910760087602e994aSatish Sampath    /**
601565505b1a2c1d3099496af5910760087602e994aSatish Sampath     * Launches the default web search activity with the query parameters if the given intent's data
602565505b1a2c1d3099496af5910760087602e994aSatish Sampath     * are identified as plain search terms and not URLs/shortcuts.
603565505b1a2c1d3099496af5910760087602e994aSatish Sampath     * @return true if the intent was handled and web search activity was launched, false if not.
604565505b1a2c1d3099496af5910760087602e994aSatish Sampath     */
605565505b1a2c1d3099496af5910760087602e994aSatish Sampath    private boolean handleWebSearchIntent(Intent intent) {
606565505b1a2c1d3099496af5910760087602e994aSatish Sampath        if (intent == null) return false;
607565505b1a2c1d3099496af5910760087602e994aSatish Sampath
608565505b1a2c1d3099496af5910760087602e994aSatish Sampath        String url = null;
609565505b1a2c1d3099496af5910760087602e994aSatish Sampath        final String action = intent.getAction();
610a1cc3fdce19a336c251297c61cd83ac6cf767cd1Leon Scroggins        if (RecognizerResultsIntent.ACTION_VOICE_SEARCH_RESULTS.equals(
611a1cc3fdce19a336c251297c61cd83ac6cf767cd1Leon Scroggins                action)) {
61258d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins            return false;
61358d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        }
614565505b1a2c1d3099496af5910760087602e994aSatish Sampath        if (Intent.ACTION_VIEW.equals(action)) {
6151e70505659dd9bf0f7e03bce787ba880f9b7a8aaGrace Kloba            Uri data = intent.getData();
6161e70505659dd9bf0f7e03bce787ba880f9b7a8aaGrace Kloba            if (data != null) url = data.toString();
617565505b1a2c1d3099496af5910760087602e994aSatish Sampath        } else if (Intent.ACTION_SEARCH.equals(action)
618565505b1a2c1d3099496af5910760087602e994aSatish Sampath                || MediaStore.INTENT_ACTION_MEDIA_SEARCH.equals(action)
619565505b1a2c1d3099496af5910760087602e994aSatish Sampath                || Intent.ACTION_WEB_SEARCH.equals(action)) {
620565505b1a2c1d3099496af5910760087602e994aSatish Sampath            url = intent.getStringExtra(SearchManager.QUERY);
621565505b1a2c1d3099496af5910760087602e994aSatish Sampath        }
6220485170e03e079eb61b9dd52fc2c98da02fa7b2cBjorn Bringert        return handleWebSearchRequest(url, intent.getBundleExtra(SearchManager.APP_DATA),
6230485170e03e079eb61b9dd52fc2c98da02fa7b2cBjorn Bringert                intent.getStringExtra(SearchManager.EXTRA_DATA_KEY));
624565505b1a2c1d3099496af5910760087602e994aSatish Sampath    }
625565505b1a2c1d3099496af5910760087602e994aSatish Sampath
626565505b1a2c1d3099496af5910760087602e994aSatish Sampath    /**
627565505b1a2c1d3099496af5910760087602e994aSatish Sampath     * Launches the default web search activity with the query parameters if the given url string
628565505b1a2c1d3099496af5910760087602e994aSatish Sampath     * was identified as plain search terms and not URL/shortcut.
629565505b1a2c1d3099496af5910760087602e994aSatish Sampath     * @return true if the request was handled and web search activity was launched, false if not.
630565505b1a2c1d3099496af5910760087602e994aSatish Sampath     */
6310485170e03e079eb61b9dd52fc2c98da02fa7b2cBjorn Bringert    private boolean handleWebSearchRequest(String inUrl, Bundle appData, String extraData) {
632565505b1a2c1d3099496af5910760087602e994aSatish Sampath        if (inUrl == null) return false;
633565505b1a2c1d3099496af5910760087602e994aSatish Sampath
634565505b1a2c1d3099496af5910760087602e994aSatish Sampath        // In general, we shouldn't modify URL from Intent.
635565505b1a2c1d3099496af5910760087602e994aSatish Sampath        // But currently, we get the user-typed URL from search box as well.
636565505b1a2c1d3099496af5910760087602e994aSatish Sampath        String url = fixUrl(inUrl).trim();
637565505b1a2c1d3099496af5910760087602e994aSatish Sampath
638565505b1a2c1d3099496af5910760087602e994aSatish Sampath        // URLs and site specific search shortcuts are handled by the regular flow of control, so
639565505b1a2c1d3099496af5910760087602e994aSatish Sampath        // return early.
6405ee906c089567bca705e18561357510d7b55cb5aDan Egnor        if (Patterns.WEB_URL.matcher(url).matches()
641bc5b9f358a2b75bf3a104b9f5cd477ad2f6f740fSatish Sampath                || ACCEPTED_URI_SCHEMA.matcher(url).matches()
642565505b1a2c1d3099496af5910760087602e994aSatish Sampath                || parseUrlShortcut(url) != SHORTCUT_INVALID) {
643565505b1a2c1d3099496af5910760087602e994aSatish Sampath            return false;
644565505b1a2c1d3099496af5910760087602e994aSatish Sampath        }
645565505b1a2c1d3099496af5910760087602e994aSatish Sampath
646565505b1a2c1d3099496af5910760087602e994aSatish Sampath        Browser.updateVisitedHistory(mResolver, url, false);
647565505b1a2c1d3099496af5910760087602e994aSatish Sampath        Browser.addSearchUrl(mResolver, url);
648565505b1a2c1d3099496af5910760087602e994aSatish Sampath
649565505b1a2c1d3099496af5910760087602e994aSatish Sampath        Intent intent = new Intent(Intent.ACTION_WEB_SEARCH);
650565505b1a2c1d3099496af5910760087602e994aSatish Sampath        intent.addCategory(Intent.CATEGORY_DEFAULT);
651565505b1a2c1d3099496af5910760087602e994aSatish Sampath        intent.putExtra(SearchManager.QUERY, url);
65215e9f2dc92cf1621f95071b3c740f46079aa0f3bSatish Sampath        if (appData != null) {
65315e9f2dc92cf1621f95071b3c740f46079aa0f3bSatish Sampath            intent.putExtra(SearchManager.APP_DATA, appData);
65415e9f2dc92cf1621f95071b3c740f46079aa0f3bSatish Sampath        }
6550485170e03e079eb61b9dd52fc2c98da02fa7b2cBjorn Bringert        if (extraData != null) {
6560485170e03e079eb61b9dd52fc2c98da02fa7b2cBjorn Bringert            intent.putExtra(SearchManager.EXTRA_DATA_KEY, extraData);
6570485170e03e079eb61b9dd52fc2c98da02fa7b2cBjorn Bringert        }
658cc63403643786905262f505ab5266d8e80b9924cGrace Kloba        intent.putExtra(Browser.EXTRA_APPLICATION_ID, getPackageName());
659565505b1a2c1d3099496af5910760087602e994aSatish Sampath        startActivity(intent);
660565505b1a2c1d3099496af5910760087602e994aSatish Sampath
661565505b1a2c1d3099496af5910760087602e994aSatish Sampath        return true;
662565505b1a2c1d3099496af5910760087602e994aSatish Sampath    }
663565505b1a2c1d3099496af5910760087602e994aSatish Sampath
66425ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima    private UrlData getUrlDataFromIntent(Intent intent) {
66558d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        String url = "";
666068e48b469f5abca53ee3da38f933cf2c25c93b8Grace Kloba        Map<String, String> headers = null;
6670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (intent != null) {
6680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            final String action = intent.getAction();
6690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (Intent.ACTION_VIEW.equals(action)) {
6700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                url = smartUrlFilter(intent.getData());
6710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (url != null && url.startsWith("content:")) {
6720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    /* Append mimetype so webview knows how to display */
6730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    String mimeType = intent.resolveType(getContentResolver());
6740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    if (mimeType != null) {
6750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        url += "?" + mimeType;
6760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
6770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
678068e48b469f5abca53ee3da38f933cf2c25c93b8Grace Kloba                if (url != null && url.startsWith("http")) {
67900f54c589fd38431efd42ea2a551a49e64d595d5Grace Kloba                    final Bundle pairs = intent
68000f54c589fd38431efd42ea2a551a49e64d595d5Grace Kloba                            .getBundleExtra(Browser.EXTRA_HEADERS);
6812d508edbf54ea74cd4e89be8b622b1cbd587464aGrace Kloba                    if (pairs != null && !pairs.isEmpty()) {
68200f54c589fd38431efd42ea2a551a49e64d595d5Grace Kloba                        Iterator<String> iter = pairs.keySet().iterator();
683068e48b469f5abca53ee3da38f933cf2c25c93b8Grace Kloba                        headers = new HashMap<String, String>();
68400f54c589fd38431efd42ea2a551a49e64d595d5Grace Kloba                        while (iter.hasNext()) {
68500f54c589fd38431efd42ea2a551a49e64d595d5Grace Kloba                            String key = iter.next();
68600f54c589fd38431efd42ea2a551a49e64d595d5Grace Kloba                            headers.put(key, pairs.getString(key));
687068e48b469f5abca53ee3da38f933cf2c25c93b8Grace Kloba                        }
688068e48b469f5abca53ee3da38f933cf2c25c93b8Grace Kloba                    }
68925ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima                }
6900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } else if (Intent.ACTION_SEARCH.equals(action)
6910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    || MediaStore.INTENT_ACTION_MEDIA_SEARCH.equals(action)
6920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    || Intent.ACTION_WEB_SEARCH.equals(action)) {
6930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                url = intent.getStringExtra(SearchManager.QUERY);
6940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (url != null) {
6950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    mLastEnteredUrl = url;
696b446443e47c334bc3aaae98b67c8dca347da3032Leon Scroggins                    Browser.updateVisitedHistory(mResolver, url, false);
6970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // In general, we shouldn't modify URL from Intent.
6980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // But currently, we get the user-typed URL from search box as well.
6990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    url = fixUrl(url);
7000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    url = smartUrlFilter(url);
7010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    String searchSource = "&source=android-" + GOOGLE_SEARCH_SOURCE_SUGGEST + "&";
7020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    if (url.contains(searchSource)) {
7030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        String source = null;
7040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        final Bundle appData = intent.getBundleExtra(SearchManager.APP_DATA);
7050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        if (appData != null) {
7060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            source = appData.getString(SearchManager.SOURCE);
7070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }
7080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        if (TextUtils.isEmpty(source)) {
7090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            source = GOOGLE_SEARCH_SOURCE_UNKNOWN;
7100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }
7110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        url = url.replace(searchSource, "&source=android-"+source+"&");
7120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
7130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
7140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
7150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
71658d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        return new UrlData(url, headers, intent);
7170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
71858d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    /* package */ void showVoiceTitleBar(String title) {
71958d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        mTitleBar.setInVoiceMode(true);
72058d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        mFakeTitleBar.setInVoiceMode(true);
7210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
72258d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        mTitleBar.setDisplayTitle(title);
72358d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        mFakeTitleBar.setDisplayTitle(title);
72458d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    }
72558d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    /* package */ void revertVoiceTitleBar() {
72658d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        mTitleBar.setInVoiceMode(false);
72758d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        mFakeTitleBar.setInVoiceMode(false);
72858d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins
72958d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        mTitleBar.setDisplayTitle(mTitle);
73058d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        mFakeTitleBar.setDisplayTitle(mTitle);
73158d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    }
7320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /* package */ static String fixUrl(String inUrl) {
733652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark        // FIXME: Converting the url to lower case
734652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark        // duplicates functionality in smartUrlFilter().
735652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark        // However, changing all current callers of fixUrl to
736652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark        // call smartUrlFilter in addition may have unwanted
737652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark        // consequences, and is deferred for now.
738652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark        int colon = inUrl.indexOf(':');
739652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark        boolean allLower = true;
740652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark        for (int index = 0; index < colon; index++) {
741652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark            char ch = inUrl.charAt(index);
742652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark            if (!Character.isLetter(ch)) {
743652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark                break;
744652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark            }
745652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark            allLower &= Character.isLowerCase(ch);
746652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark            if (index == colon - 1 && !allLower) {
747652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark                inUrl = inUrl.substring(0, colon).toLowerCase()
748652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark                        + inUrl.substring(colon);
749652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark            }
750652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark        }
7510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (inUrl.startsWith("http://") || inUrl.startsWith("https://"))
7520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return inUrl;
7530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (inUrl.startsWith("http:") ||
7540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                inUrl.startsWith("https:")) {
7550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (inUrl.startsWith("http:/") || inUrl.startsWith("https:/")) {
7560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                inUrl = inUrl.replaceFirst("/", "//");
7570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } else inUrl = inUrl.replaceFirst(":", "://");
7580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
7590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return inUrl;
7600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
7610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
76222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    @Override
76322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    protected void onResume() {
7640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        super.onResume();
76531a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort        if (LOGV_ENABLED) {
7660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Log.v(LOGTAG, "BrowserActivity.onResume: this=" + this);
7670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
7680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
7690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (!mActivityInPause) {
7700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Log.e(LOGTAG, "BrowserActivity is already resumed.");
7710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
7720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
7730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
7747bfa63b55644fbf2da1fe6a24b3be0267529202cMike Reed        mTabControl.resumeCurrentTab();
7750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mActivityInPause = false;
7767bfa63b55644fbf2da1fe6a24b3be0267529202cMike Reed        resumeWebViewTimers();
7770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
7780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mWakeLock.isHeld()) {
7790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mHandler.removeMessages(RELEASE_WAKELOCK);
7800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mWakeLock.release();
7810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
7820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
7830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mCredsDlg != null) {
7840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (!mHandler.hasMessages(CANCEL_CREDS_REQUEST)) {
7850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project             // In case credential request never comes back
7860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mHandler.sendEmptyMessageDelayed(CANCEL_CREDS_REQUEST, 6000);
7870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
7880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
7890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
7900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        registerReceiver(mNetworkStateIntentReceiver,
7910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                         mNetworkStateChangedFilter);
7920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebView.enablePlatformNotifications();
7930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
7940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
7953bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    /**
7963bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     * Since the actual title bar is embedded in the WebView, and removing it
797fe87bd3a3897e4bad65bb3d284659ae2f4e57570Leon Scroggins     * would change its appearance, use a different TitleBar to show overlayed
798fe87bd3a3897e4bad65bb3d284659ae2f4e57570Leon Scroggins     * at the top of the screen, when the menu is open or the page is loading.
7993bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     */
8003bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    private TitleBar mFakeTitleBar;
8013bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins
8023bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    /**
803d8fd2fcf4eb037fd65ae923c6dbeff6c6ecb4d4fLeon Scroggins     * Holder for the fake title bar.  It will have a foreground shadow, as well
804d8fd2fcf4eb037fd65ae923c6dbeff6c6ecb4d4fLeon Scroggins     * as a white background, so the fake title bar looks like the real one.
805d8fd2fcf4eb037fd65ae923c6dbeff6c6ecb4d4fLeon Scroggins     */
806d8fd2fcf4eb037fd65ae923c6dbeff6c6ecb4d4fLeon Scroggins    private ViewGroup mFakeTitleBarHolder;
807d8fd2fcf4eb037fd65ae923c6dbeff6c6ecb4d4fLeon Scroggins
808d8fd2fcf4eb037fd65ae923c6dbeff6c6ecb4d4fLeon Scroggins    /**
809d8fd2fcf4eb037fd65ae923c6dbeff6c6ecb4d4fLeon Scroggins     * Layout parameters for the fake title bar within mFakeTitleBarHolder
810d8fd2fcf4eb037fd65ae923c6dbeff6c6ecb4d4fLeon Scroggins     */
811d8fd2fcf4eb037fd65ae923c6dbeff6c6ecb4d4fLeon Scroggins    private FrameLayout.LayoutParams mFakeTitleBarParams
812d8fd2fcf4eb037fd65ae923c6dbeff6c6ecb4d4fLeon Scroggins            = new FrameLayout.LayoutParams(
81315b8ec6b226f4d57307716e1f495e10a91f8cbf4Romain Guy            ViewGroup.LayoutParams.MATCH_PARENT,
814d8fd2fcf4eb037fd65ae923c6dbeff6c6ecb4d4fLeon Scroggins            ViewGroup.LayoutParams.WRAP_CONTENT);
815d8fd2fcf4eb037fd65ae923c6dbeff6c6ecb4d4fLeon Scroggins    /**
8163bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     * Keeps track of whether the options menu is open.  This is important in
8173bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     * determining whether to show or hide the title bar overlay.
8183bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     */
8193bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    private boolean mOptionsMenuOpen;
8203bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins
8213bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    /**
8223bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     * Only meaningful when mOptionsMenuOpen is true.  This variable keeps track
8233bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     * of whether the configuration has changed.  The first onMenuOpened call
8243bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     * after a configuration change is simply a reopening of the same menu
8253bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     * (i.e. mIconView did not change).
8263bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     */
8273bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    private boolean mConfigChanged;
8283bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins
8293bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    /**
8303bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     * Whether or not the options menu is in its smaller, icon menu form.  When
8313bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     * true, we want the title bar overlay to be up.  When false, we do not.
8323bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     * Only meaningful if mOptionsMenuOpen is true.
8333bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     */
8343bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    private boolean mIconView;
8353bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins
836a81a764063d2f849fba0cbc3039f86e67c2960ddLeon Scroggins    @Override
837a81a764063d2f849fba0cbc3039f86e67c2960ddLeon Scroggins    public boolean onMenuOpened(int featureId, Menu menu) {
8383bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins        if (Window.FEATURE_OPTIONS_PANEL == featureId) {
8393bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins            if (mOptionsMenuOpen) {
8403bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                if (mConfigChanged) {
8413bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                    // We do not need to make any changes to the state of the
8423bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                    // title bar, since the only thing that happened was a
8433bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                    // change in orientation
8443bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                    mConfigChanged = false;
8453bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                } else {
8463bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                    if (mIconView) {
8473bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                        // Switching the menu to expanded view, so hide the
8483bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                        // title bar.
8493bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                        hideFakeTitleBar();
8503bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                        mIconView = false;
8513bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                    } else {
8523bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                        // Switching the menu back to icon view, so show the
8533bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                        // title bar once again.
8543bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                        showFakeTitleBar();
8553bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                        mIconView = true;
8563bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                    }
8573bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                }
8583bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins            } else {
8593bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                // The options menu is closed, so open it, and show the title
8603bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                showFakeTitleBar();
8613bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                mOptionsMenuOpen = true;
8623bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                mConfigChanged = false;
8633bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                mIconView = true;
8643bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins            }
8653bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins        }
866a81a764063d2f849fba0cbc3039f86e67c2960ddLeon Scroggins        return true;
867a81a764063d2f849fba0cbc3039f86e67c2960ddLeon Scroggins    }
868a81a764063d2f849fba0cbc3039f86e67c2960ddLeon Scroggins
869b94bf27370329abb27e5e33b493d6edb5662b36eLeon Scroggins    /**
870b94bf27370329abb27e5e33b493d6edb5662b36eLeon Scroggins     * Special class used exclusively for the shadow drawn underneath the fake
871b94bf27370329abb27e5e33b493d6edb5662b36eLeon Scroggins     * title bar.  The shadow does not need to be drawn if the WebView
872b94bf27370329abb27e5e33b493d6edb5662b36eLeon Scroggins     * underneath is scrolled to the top, because it will draw directly on top
873b94bf27370329abb27e5e33b493d6edb5662b36eLeon Scroggins     * of the embedded shadow.
874b94bf27370329abb27e5e33b493d6edb5662b36eLeon Scroggins     */
875b94bf27370329abb27e5e33b493d6edb5662b36eLeon Scroggins    private static class Shadow extends View {
876b94bf27370329abb27e5e33b493d6edb5662b36eLeon Scroggins        private WebView mWebView;
877b94bf27370329abb27e5e33b493d6edb5662b36eLeon Scroggins
878b94bf27370329abb27e5e33b493d6edb5662b36eLeon Scroggins        public Shadow(Context context, AttributeSet attrs) {
879b94bf27370329abb27e5e33b493d6edb5662b36eLeon Scroggins            super(context, attrs);
880b94bf27370329abb27e5e33b493d6edb5662b36eLeon Scroggins        }
881b94bf27370329abb27e5e33b493d6edb5662b36eLeon Scroggins
882b94bf27370329abb27e5e33b493d6edb5662b36eLeon Scroggins        public void setWebView(WebView view) {
883b94bf27370329abb27e5e33b493d6edb5662b36eLeon Scroggins            mWebView = view;
884b94bf27370329abb27e5e33b493d6edb5662b36eLeon Scroggins        }
885b94bf27370329abb27e5e33b493d6edb5662b36eLeon Scroggins
886b94bf27370329abb27e5e33b493d6edb5662b36eLeon Scroggins        @Override
887b94bf27370329abb27e5e33b493d6edb5662b36eLeon Scroggins        public void draw(Canvas canvas) {
888b94bf27370329abb27e5e33b493d6edb5662b36eLeon Scroggins            // In general onDraw is the method to override, but we care about
889b94bf27370329abb27e5e33b493d6edb5662b36eLeon Scroggins            // whether or not the background gets drawn, which happens in draw()
890b94bf27370329abb27e5e33b493d6edb5662b36eLeon Scroggins            if (mWebView == null || mWebView.getScrollY() > getHeight()) {
891b94bf27370329abb27e5e33b493d6edb5662b36eLeon Scroggins                super.draw(canvas);
892b94bf27370329abb27e5e33b493d6edb5662b36eLeon Scroggins            }
893b94bf27370329abb27e5e33b493d6edb5662b36eLeon Scroggins            // Need to invalidate so that if the scroll position changes, we
894b94bf27370329abb27e5e33b493d6edb5662b36eLeon Scroggins            // still draw as appropriate.
895b94bf27370329abb27e5e33b493d6edb5662b36eLeon Scroggins            invalidate();
896b94bf27370329abb27e5e33b493d6edb5662b36eLeon Scroggins        }
897b94bf27370329abb27e5e33b493d6edb5662b36eLeon Scroggins    }
898b94bf27370329abb27e5e33b493d6edb5662b36eLeon Scroggins
8993bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    private void showFakeTitleBar() {
900f8de8ecc321fe5b45846adc38d174d5bc2208f20Patrick Scott        final View decor = getWindow().peekDecorView();
901fe87bd3a3897e4bad65bb3d284659ae2f4e57570Leon Scroggins        if (mFakeTitleBar.getParent() == null && mActiveTabsPage == null
902f8de8ecc321fe5b45846adc38d174d5bc2208f20Patrick Scott                && !mActivityInPause && decor != null
903f8de8ecc321fe5b45846adc38d174d5bc2208f20Patrick Scott                && decor.getWindowToken() != null) {
904a04645545690d9f637ccae4d043a5a1b8478a832Cary Clark            Rect visRect = new Rect();
905a04645545690d9f637ccae4d043a5a1b8478a832Cary Clark            if (!mBrowserFrameLayout.getGlobalVisibleRect(visRect)) {
906a04645545690d9f637ccae4d043a5a1b8478a832Cary Clark                if (LOGD_ENABLED) {
907a04645545690d9f637ccae4d043a5a1b8478a832Cary Clark                    Log.d(LOGTAG, "showFakeTitleBar visRect failed");
908a04645545690d9f637ccae4d043a5a1b8478a832Cary Clark                }
909a04645545690d9f637ccae4d043a5a1b8478a832Cary Clark                return;
910a04645545690d9f637ccae4d043a5a1b8478a832Cary Clark            }
9113bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins
9123bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins            WindowManager manager
9133bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                    = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
9143bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins
9153bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins            // Add the title bar to the window manager so it can receive touches
9163bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins            // while the menu is up
9173bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins            WindowManager.LayoutParams params
9183bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                    = new WindowManager.LayoutParams(
91915b8ec6b226f4d57307716e1f495e10a91f8cbf4Romain Guy                    ViewGroup.LayoutParams.MATCH_PARENT,
9203bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                    ViewGroup.LayoutParams.WRAP_CONTENT,
9213bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                    WindowManager.LayoutParams.TYPE_APPLICATION_SUB_PANEL,
9223bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                    WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
923685498685d8424f48d77d26d8d5790da34645f44Leon Scroggins                    PixelFormat.TRANSLUCENT);
9243bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins            params.gravity = Gravity.TOP;
925a27ff19e24cb1c9fef5624dbc4554548349b5b31Leon Scroggins            WebView mainView = mTabControl.getCurrentWebView();
926685498685d8424f48d77d26d8d5790da34645f44Leon Scroggins            boolean atTop = mainView != null && mainView.getScrollY() == 0;
92783932c74ba031eb2f581f1557c1a90f4b5bbb423Leon Scroggins            params.windowAnimations = atTop ? 0 : R.style.TitleBar;
9283bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins            // XXX : Without providing an offset, the fake title bar will be
9293bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins            // placed underneath the status bar.  Use the global visible rect
9303bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins            // of mBrowserFrameLayout to determine the bottom of the status bar
931a04645545690d9f637ccae4d043a5a1b8478a832Cary Clark            params.y = visRect.top;
932685498685d8424f48d77d26d8d5790da34645f44Leon Scroggins            // Add a holder for the title bar.  It also holds a shadow to show
933685498685d8424f48d77d26d8d5790da34645f44Leon Scroggins            // below the title bar.
934d8fd2fcf4eb037fd65ae923c6dbeff6c6ecb4d4fLeon Scroggins            if (mFakeTitleBarHolder == null) {
935d8fd2fcf4eb037fd65ae923c6dbeff6c6ecb4d4fLeon Scroggins                mFakeTitleBarHolder = (ViewGroup) LayoutInflater.from(this)
936d8fd2fcf4eb037fd65ae923c6dbeff6c6ecb4d4fLeon Scroggins                    .inflate(R.layout.title_bar_bg, null);
937d8fd2fcf4eb037fd65ae923c6dbeff6c6ecb4d4fLeon Scroggins            }
938b94bf27370329abb27e5e33b493d6edb5662b36eLeon Scroggins            Shadow shadow = (Shadow) mFakeTitleBarHolder.findViewById(
939b94bf27370329abb27e5e33b493d6edb5662b36eLeon Scroggins                    R.id.shadow);
940b94bf27370329abb27e5e33b493d6edb5662b36eLeon Scroggins            shadow.setWebView(mainView);
941685498685d8424f48d77d26d8d5790da34645f44Leon Scroggins            mFakeTitleBarHolder.addView(mFakeTitleBar, 0, mFakeTitleBarParams);
942d8fd2fcf4eb037fd65ae923c6dbeff6c6ecb4d4fLeon Scroggins            manager.addView(mFakeTitleBarHolder, params);
9433bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins        }
9443bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    }
9453bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins
9463bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    @Override
9473bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    public void onOptionsMenuClosed(Menu menu) {
9483bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins        mOptionsMenuOpen = false;
949a27ff19e24cb1c9fef5624dbc4554548349b5b31Leon Scroggins        if (!mInLoad) {
950a27ff19e24cb1c9fef5624dbc4554548349b5b31Leon Scroggins            hideFakeTitleBar();
951a27ff19e24cb1c9fef5624dbc4554548349b5b31Leon Scroggins        } else if (!mIconView) {
952a27ff19e24cb1c9fef5624dbc4554548349b5b31Leon Scroggins            // The page is currently loading, and we are in expanded mode, so
953a27ff19e24cb1c9fef5624dbc4554548349b5b31Leon Scroggins            // we were not showing the menu.  Show it once again.  It will be
954a27ff19e24cb1c9fef5624dbc4554548349b5b31Leon Scroggins            // removed when the page finishes.
955a27ff19e24cb1c9fef5624dbc4554548349b5b31Leon Scroggins            showFakeTitleBar();
956a27ff19e24cb1c9fef5624dbc4554548349b5b31Leon Scroggins        }
9573bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    }
95822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
9593bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    private void hideFakeTitleBar() {
960fe87bd3a3897e4bad65bb3d284659ae2f4e57570Leon Scroggins        if (mFakeTitleBar.getParent() == null) return;
96120329570ba9409637298da90b83f25801d7a3d55Leon Scroggins        WindowManager.LayoutParams params = (WindowManager.LayoutParams)
96220329570ba9409637298da90b83f25801d7a3d55Leon Scroggins                mFakeTitleBarHolder.getLayoutParams();
96320329570ba9409637298da90b83f25801d7a3d55Leon Scroggins        WebView mainView = mTabControl.getCurrentWebView();
96420329570ba9409637298da90b83f25801d7a3d55Leon Scroggins        // Although we decided whether or not to animate based on the current
96520329570ba9409637298da90b83f25801d7a3d55Leon Scroggins        // scroll position, the scroll position may have changed since the
96620329570ba9409637298da90b83f25801d7a3d55Leon Scroggins        // fake title bar was displayed.  Make sure it has the appropriate
96720329570ba9409637298da90b83f25801d7a3d55Leon Scroggins        // animation/lack thereof before removing.
96820329570ba9409637298da90b83f25801d7a3d55Leon Scroggins        params.windowAnimations = mainView != null && mainView.getScrollY() == 0
96983932c74ba031eb2f581f1557c1a90f4b5bbb423Leon Scroggins                ? 0 : R.style.TitleBar;
9703bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins        WindowManager manager
9713bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                    = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
97220329570ba9409637298da90b83f25801d7a3d55Leon Scroggins        manager.updateViewLayout(mFakeTitleBarHolder, params);
973d8fd2fcf4eb037fd65ae923c6dbeff6c6ecb4d4fLeon Scroggins        mFakeTitleBarHolder.removeView(mFakeTitleBar);
974d8fd2fcf4eb037fd65ae923c6dbeff6c6ecb4d4fLeon Scroggins        manager.removeView(mFakeTitleBarHolder);
9753bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    }
9763bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins
9770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
978c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins     * Special method for the fake title bar to call when displaying its context
979c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins     * menu, since it is in its own Window, and its parent does not show a
980c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins     * context menu.
981c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins     */
982c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins    /* package */ void showTitleBarContextMenu() {
98365f4a3ce9e5c4a5227bbcbb995e5e15f1f85d3d7Cary Clark        if (null == mTitleBar.getParent()) {
98465f4a3ce9e5c4a5227bbcbb995e5e15f1f85d3d7Cary Clark            return;
98565f4a3ce9e5c4a5227bbcbb995e5e15f1f85d3d7Cary Clark        }
986c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins        openContextMenu(mTitleBar);
987c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins    }
988c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins
989b2b19f501ee05448ca81bddaaca70e9b2f51cb54Leon Scroggins    @Override
990b2b19f501ee05448ca81bddaaca70e9b2f51cb54Leon Scroggins    public void onContextMenuClosed(Menu menu) {
991b2b19f501ee05448ca81bddaaca70e9b2f51cb54Leon Scroggins        super.onContextMenuClosed(menu);
992b2b19f501ee05448ca81bddaaca70e9b2f51cb54Leon Scroggins        if (mInLoad) {
993b2b19f501ee05448ca81bddaaca70e9b2f51cb54Leon Scroggins            showFakeTitleBar();
994b2b19f501ee05448ca81bddaaca70e9b2f51cb54Leon Scroggins        }
995b2b19f501ee05448ca81bddaaca70e9b2f51cb54Leon Scroggins    }
996b2b19f501ee05448ca81bddaaca70e9b2f51cb54Leon Scroggins
997c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins    /**
9980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *  onSaveInstanceState(Bundle map)
9990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *  onSaveInstanceState is called right before onStop(). The map contains
10000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *  the saved state.
10010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
100222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    @Override
100322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    protected void onSaveInstanceState(Bundle outState) {
100431a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort        if (LOGV_ENABLED) {
10050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Log.v(LOGTAG, "BrowserActivity.onSaveInstanceState: this=" + this);
10060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
10070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // the default implementation requires each view to have an id. As the
10080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // browser handles the state itself and it doesn't use id for the views,
10090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // don't call the default implementation. Otherwise it will trigger the
10100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // warning like this, "couldn't save which view has focus because the
10110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // focused view XXX has no id".
10120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
10130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Save all the tabs
10140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mTabControl.saveState(outState);
10150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
10160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
101722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    @Override
101822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    protected void onPause() {
10190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        super.onPause();
10200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
10210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mActivityInPause) {
10220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Log.e(LOGTAG, "BrowserActivity is already paused.");
10230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
10240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
10250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
10267bfa63b55644fbf2da1fe6a24b3be0267529202cMike Reed        mTabControl.pauseCurrentTab();
10270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mActivityInPause = true;
10287bfa63b55644fbf2da1fe6a24b3be0267529202cMike Reed        if (mTabControl.getCurrentIndex() >= 0 && !pauseWebViewTimers()) {
10290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mWakeLock.acquire();
10300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mHandler.sendMessageDelayed(mHandler
10310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    .obtainMessage(RELEASE_WAKELOCK), WAKELOCK_TIMEOUT);
10320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
10330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
10340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Clear the credentials toast if it is up
10350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mCredsDlg != null && mCredsDlg.isShowing()) {
10360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mCredsDlg.dismiss();
10370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
10380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mCredsDlg = null;
10390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
1040a2ab6a7dc0f7023c1d7ebb1cbad397c5dc3d6453Leon Scroggins        // FIXME: This removes the active tabs page and resets the menu to
1041a2ab6a7dc0f7023c1d7ebb1cbad397c5dc3d6453Leon Scroggins        // MAIN_MENU.  A better solution might be to do this work in onNewIntent
1042a2ab6a7dc0f7023c1d7ebb1cbad397c5dc3d6453Leon Scroggins        // but then we would need to save it in onSaveInstanceState and restore
1043a2ab6a7dc0f7023c1d7ebb1cbad397c5dc3d6453Leon Scroggins        // it in onCreate/onRestoreInstanceState
1044a2ab6a7dc0f7023c1d7ebb1cbad397c5dc3d6453Leon Scroggins        if (mActiveTabsPage != null) {
1045a2ab6a7dc0f7023c1d7ebb1cbad397c5dc3d6453Leon Scroggins            removeActiveTabPage(true);
1046a2ab6a7dc0f7023c1d7ebb1cbad397c5dc3d6453Leon Scroggins        }
1047a2ab6a7dc0f7023c1d7ebb1cbad397c5dc3d6453Leon Scroggins
10480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        cancelStopToast();
10490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
10500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // unregister network state listener
10510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        unregisterReceiver(mNetworkStateIntentReceiver);
10520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebView.disablePlatformNotifications();
10530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
10540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
105522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    @Override
105622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    protected void onDestroy() {
105731a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort        if (LOGV_ENABLED) {
10580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Log.v(LOGTAG, "BrowserActivity.onDestroy: this=" + this);
10590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
10600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        super.onDestroy();
10610923d69a8ca45222cabd82a80eaa88da9f132e9aGrace Kloba
10628d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins        if (mUploadMessage != null) {
10638d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins            mUploadMessage.onReceiveValue(null);
10648d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins            mUploadMessage = null;
10658d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins        }
10668d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins
10670923d69a8ca45222cabd82a80eaa88da9f132e9aGrace Kloba        if (mTabControl == null) return;
10680923d69a8ca45222cabd82a80eaa88da9f132e9aGrace Kloba
10691fc98a322e9df6b0e797c26de6b2cb23d69ad5d3Grace Kloba        // Remove the fake title bar if it is there
10701fc98a322e9df6b0e797c26de6b2cb23d69ad5d3Grace Kloba        hideFakeTitleBar();
10711fc98a322e9df6b0e797c26de6b2cb23d69ad5d3Grace Kloba
10720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Remove the current tab and sub window
107322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        Tab t = mTabControl.getCurrentTab();
1074fb5e77fac7b8b311fe72827183f8988f5ee92a5fPatrick Scott        if (t != null) {
1075fb5e77fac7b8b311fe72827183f8988f5ee92a5fPatrick Scott            dismissSubWindow(t);
1076fb5e77fac7b8b311fe72827183f8988f5ee92a5fPatrick Scott            removeTabFromContentView(t);
1077fb5e77fac7b8b311fe72827183f8988f5ee92a5fPatrick Scott        }
10780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Destroy all the tabs
10790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mTabControl.destroy();
10800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebIconDatabase.getInstance().close();
10810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
1082b4da0ad0351996f639b50f9f29b123a9b5c24fd0Grace Kloba        unregisterReceiver(mPackageInstallationReceiver);
10830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
10840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
10850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    @Override
10860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public void onConfigurationChanged(Configuration newConfig) {
10873bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins        mConfigChanged = true;
10880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        super.onConfigurationChanged(newConfig);
10890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
10900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mPageInfoDialog != null) {
10910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mPageInfoDialog.dismiss();
10920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            showPageInfo(
10930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mPageInfoView,
1094c7b92f811dfa3572578ddc6714c98a03936d9ce5Leon Scroggins                mPageInfoFromShowSSLCertificateOnError);
10950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
10960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mSSLCertificateDialog != null) {
10970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mSSLCertificateDialog.dismiss();
10980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            showSSLCertificate(
10990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mSSLCertificateView);
11000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
11010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mSSLCertificateOnErrorDialog != null) {
11020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mSSLCertificateOnErrorDialog.dismiss();
11030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            showSSLCertificateOnError(
11040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mSSLCertificateOnErrorView,
11050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mSSLCertificateOnErrorHandler,
11060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mSSLCertificateOnErrorError);
11070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
11080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mHttpAuthenticationDialog != null) {
11090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            String title = ((TextView) mHttpAuthenticationDialog
11100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    .findViewById(com.android.internal.R.id.alertTitle)).getText()
11110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    .toString();
11120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            String name = ((TextView) mHttpAuthenticationDialog
11130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    .findViewById(R.id.username_edit)).getText().toString();
11140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            String password = ((TextView) mHttpAuthenticationDialog
11150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    .findViewById(R.id.password_edit)).getText().toString();
11160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            int focusId = mHttpAuthenticationDialog.getCurrentFocus()
11170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    .getId();
11180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mHttpAuthenticationDialog.dismiss();
11190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            showHttpAuthentication(mHttpAuthHandler, null, null, title,
11200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    name, password, focusId);
11210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
11220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
11230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
112422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    @Override
112522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    public void onLowMemory() {
11260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        super.onLowMemory();
11270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mTabControl.freeMemory();
11280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
11290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
11307bfa63b55644fbf2da1fe6a24b3be0267529202cMike Reed    private boolean resumeWebViewTimers() {
113122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        Tab tab = mTabControl.getCurrentTab();
113222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        boolean inLoad = tab.inLoad();
113322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if ((!mActivityInPause && !inLoad) || (mActivityInPause && inLoad)) {
11340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            CookieSyncManager.getInstance().startSync();
113522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            WebView w = tab.getWebView();
11360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (w != null) {
11370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                w.resumeTimers();
11380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
11390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return true;
11400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
11410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return false;
11420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
11430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
11440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
11457bfa63b55644fbf2da1fe6a24b3be0267529202cMike Reed    private boolean pauseWebViewTimers() {
114622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        Tab tab = mTabControl.getCurrentTab();
114722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        boolean inLoad = tab.inLoad();
114822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mActivityInPause && !inLoad) {
11490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            CookieSyncManager.getInstance().stopSync();
11500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            WebView w = mTabControl.getCurrentWebView();
11510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (w != null) {
11520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                w.pauseTimers();
11530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
11540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return true;
11550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
11560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return false;
11570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
11580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
11590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
11601f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins    // FIXME: Do we want to call this when loading google for the first time?
11610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /*
11620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * This function is called when we are launching for the first time. We
11630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * are waiting for the login credentials before loading Google home
11640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * pages. This way the user will be logged in straight away.
11650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
11660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void waitForCredentials() {
11670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Show a toast
11680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mCredsDlg = new ProgressDialog(this);
11690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mCredsDlg.setIndeterminate(true);
11700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mCredsDlg.setMessage(getText(R.string.retrieving_creds_dlg_msg));
11710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // If the user cancels the operation, then cancel the Google
11720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Credentials request.
11730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mCredsDlg.setCancelMessage(mHandler.obtainMessage(CANCEL_CREDS_REQUEST));
11740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mCredsDlg.show();
11750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
11760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // We set a timeout for the retrieval of credentials in onResume()
11770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // as that is when we have freed up some CPU time to get
11780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // the login credentials.
11790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
11800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
11810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /*
11820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * If we have received the credentials or we have timed out and we are
11830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * showing the credentials dialog, then it is time to move on.
11840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
11850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void resumeAfterCredentials() {
11860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mCredsDlg == null) {
11870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
11880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
11890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
11900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Clear the toast
11910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mCredsDlg.isShowing()) {
11920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mCredsDlg.dismiss();
11930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
11940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mCredsDlg = null;
11950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
11960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Clear any pending timeout
11970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mHandler.removeMessages(CANCEL_CREDS_REQUEST);
11980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
11990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Load the page
12000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebView w = mTabControl.getCurrentWebView();
12010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (w != null) {
12020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            w.loadUrl(mSettings.getHomePage());
12030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
12040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
12050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Update the settings, need to do this last as it can take a moment
12060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // to persist the settings. In the mean time we could be loading
12070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // content.
12080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mSettings.setLoginInitialized(this);
12090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
12100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
12110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Open the icon database and retain all the icons for visited sites.
12120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void retainIconsOnStartup() {
12130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final WebIconDatabase db = WebIconDatabase.getInstance();
12140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        db.open(getDir("icons", 0).getPath());
12150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        try {
12160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Cursor c = Browser.getAllBookmarks(mResolver);
12170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (!c.moveToFirst()) {
12180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                c.deactivate();
12190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                return;
12200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
12210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            int urlIndex = c.getColumnIndex(Browser.BookmarkColumns.URL);
12220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            do {
12230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                String url = c.getString(urlIndex);
12240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                db.retainIconForPageUrl(url);
12250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } while (c.moveToNext());
12260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            c.deactivate();
12270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } catch (IllegalStateException e) {
12280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Log.e(LOGTAG, "retainIconsOnStartup", e);
12290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
12300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
12310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
12320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Helper method for getting the top window.
12330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    WebView getTopWindow() {
12340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return mTabControl.getCurrentTopWebView();
12350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
12360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
123722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    TabControl getTabControl() {
123822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return mTabControl;
123922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
124022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
12410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    @Override
12420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public boolean onCreateOptionsMenu(Menu menu) {
12430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        super.onCreateOptionsMenu(menu);
12440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
12450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        MenuInflater inflater = getMenuInflater();
12460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        inflater.inflate(R.menu.browser, menu);
12470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mMenu = menu;
12480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        updateInLoadMenuItems();
12490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return true;
12500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
12510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
12520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
12530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * As the menu can be open when loading state changes
12540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * we must manually update the state of the stop/reload menu
12550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * item
12560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
12570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void updateInLoadMenuItems() {
12580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mMenu == null) {
12590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
12600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
12610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        MenuItem src = mInLoad ?
12620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mMenu.findItem(R.id.stop_menu_id):
12630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    mMenu.findItem(R.id.reload_menu_id);
12640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        MenuItem dest = mMenu.findItem(R.id.stop_reload_menu_id);
12650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        dest.setIcon(src.getIcon());
12660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        dest.setTitle(src.getTitle());
12670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
12680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
12690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    @Override
12700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public boolean onContextItemSelected(MenuItem item) {
12710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // chording is not an issue with context menus, but we use the same
12720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // options selector, so set mCanChord to true so we can access them.
12730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mCanChord = true;
12740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        int id = item.getItemId();
127596afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins        boolean result = true;
12760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        switch (id) {
1277c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins            // For the context menu from the title bar
1278c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins            case R.id.title_bar_copy_page_url:
127996afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                Tab currentTab = mTabControl.getCurrentTab();
128096afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                if (null == currentTab) {
128196afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                    result = false;
128296afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                    break;
1283c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins                }
128496afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                WebView mainView = currentTab.getWebView();
128596afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                if (null == mainView) {
128696afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                    result = false;
128796afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                    break;
1288c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins                }
128996afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                copy(mainView.getUrl());
1290c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins                break;
12910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // -- Browser context menu
12920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.open_context_menu_id:
12930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.open_newtab_context_menu_id:
12940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.bookmark_context_menu_id:
12950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.save_link_context_menu_id:
12960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.share_link_context_menu_id:
12970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.copy_link_context_menu_id:
1298c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins                final WebView webView = getTopWindow();
1299c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins                if (null == webView) {
130096afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                    result = false;
130196afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                    break;
1302c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins                }
1303c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins                final HashMap hrefMap = new HashMap();
1304c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins                hrefMap.put("webview", webView);
1305c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins                final Message msg = mHandler.obtainMessage(
1306c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins                        FOCUS_NODE_HREF, id, 0, hrefMap);
13070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                webView.requestFocusNodeHref(msg);
13080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
13090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
13100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            default:
13110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // For other context menus
131296afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                result = onOptionsItemSelected(item);
13130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
13140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mCanChord = false;
131596afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins        return result;
13160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
13170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
13180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private Bundle createGoogleSearchSourceBundle(String source) {
13190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        Bundle bundle = new Bundle();
13200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        bundle.putString(SearchManager.SOURCE, source);
13210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return bundle;
13220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
13230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
13240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
13254e5f58704099c37186d4825c3d55ea5b0527867fThe Android Open Source Project     * Overriding this to insert a local information bundle
13260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
13270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    @Override
13280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public boolean onSearchRequested() {
132968579393973f745fc65a2781061af9bb8f2d7020Leon Scroggins        if (mOptionsMenuOpen) closeOptionsMenu();
13305bbe98025a2c606a35c91b826760020890daadb1Leon Scroggins        String url = (getTopWindow() == null) ? null : getTopWindow().getUrl();
133183f473462fcd7869031a423c02b957c6e938a2f6Grace Kloba        startSearch(mSettings.getHomePage().equals(url) ? null : url, true,
13324e5f58704099c37186d4825c3d55ea5b0527867fThe Android Open Source Project                createGoogleSearchSourceBundle(GOOGLE_SEARCH_SOURCE_SEARCHKEY), false);
13330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return true;
13340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
13350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
13360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    @Override
13370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public void startSearch(String initialQuery, boolean selectInitialQuery,
13380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Bundle appSearchData, boolean globalSearch) {
13390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (appSearchData == null) {
13400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            appSearchData = createGoogleSearchSourceBundle(GOOGLE_SEARCH_SOURCE_TYPE);
13410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
13420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        super.startSearch(initialQuery, selectInitialQuery, appSearchData, globalSearch);
13430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
13440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
13451f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins    /**
13461f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins     * Switch tabs.  Called by the TitleBarSet when sliding the title bar
13471f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins     * results in changing tabs.
1348160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins     * @param index Index of the tab to change to, as defined by
1349160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins     *              mTabControl.getTabIndex(Tab t).
1350160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins     * @return boolean True if we successfully switched to a different tab.  If
1351160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins     *                 the indexth tab is null, or if that tab is the same as
1352160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins     *                 the current one, return false.
13531f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins     */
1354160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins    /* package */ boolean switchToTab(int index) {
135522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        Tab tab = mTabControl.getTab(index);
135622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        Tab currentTab = mTabControl.getCurrentTab();
13571f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins        if (tab == null || tab == currentTab) {
1358160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins            return false;
13591f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins        }
13601f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins        if (currentTab != null) {
13611f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins            // currentTab may be null if it was just removed.  In that case,
13621f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins            // we do not need to remove it
13631f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins            removeTabFromContentView(currentTab);
13641f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins        }
13651f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins        mTabControl.setCurrentTab(tab);
13661f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins        attachTabToContentView(tab);
1367eb6eef4c45df2d65c3e70660493a147a2be405e3Grace Kloba        resetTitleIconAndProgress();
1368eb6eef4c45df2d65c3e70660493a147a2be405e3Grace Kloba        updateLockIconToLatest();
1369160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins        return true;
13701f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins    }
13711f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins
137222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /* package */ Tab openTabToHomePage() {
13730a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins        return openTabAndShow(mSettings.getHomePage(), false, null);
13740a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins    }
13750a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins
13761f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins    /* package */ void closeCurrentWindow() {
137722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        final Tab current = mTabControl.getCurrentTab();
1378160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins        if (mTabControl.getTabCount() == 1) {
1379304442375719effd41dbd53ae62de7a8d0cec7d9Leon Scroggins            // This is the last tab.  Open a new one, with the home
1380304442375719effd41dbd53ae62de7a8d0cec7d9Leon Scroggins            // page and close the current one.
138122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            openTabToHomePage();
1382160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins            closeTab(current);
1383160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins            return;
1384160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins        }
138522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        final Tab parent = current.getParentTab();
13861f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins        int indexToShow = -1;
13871f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins        if (parent != null) {
13881f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins            indexToShow = mTabControl.getTabIndex(parent);
13891f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins        } else {
1390160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins            final int currentIndex = mTabControl.getCurrentIndex();
1391160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins            // Try to move to the tab to the right
1392160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins            indexToShow = currentIndex + 1;
1393160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins            if (indexToShow > mTabControl.getTabCount() - 1) {
1394160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins                // Try to move to the tab to the left
1395160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins                indexToShow = currentIndex - 1;
13961f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins            }
13971f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins        }
1398160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins        if (switchToTab(indexToShow)) {
1399160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins            // Close window
1400160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins            closeTab(current);
1401160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins        }
14021f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins    }
14031f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins
14040a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins    private ActiveTabsPage mActiveTabsPage;
14050a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins
14060a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins    /**
14070a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins     * Remove the active tabs page.
14080a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins     * @param needToAttach If true, the active tabs page did not attach a tab
14090a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins     *                     to the content view, so we need to do that here.
14100a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins     */
14110a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins    /* package */ void removeActiveTabPage(boolean needToAttach) {
14120a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins        mContentView.removeView(mActiveTabsPage);
14130a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins        mActiveTabsPage = null;
14140a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins        mMenuState = R.id.MAIN_MENU;
14150a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins        if (needToAttach) {
14160a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins            attachTabToContentView(mTabControl.getCurrentTab());
14170a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins        }
14180a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins        getTopWindow().requestFocus();
14190a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins    }
14200a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins
14210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    @Override
14220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public boolean onOptionsItemSelected(MenuItem item) {
14230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (!mCanChord) {
14240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // The user has already fired a shortcut with this hold down of the
14250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // menu key.
14260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return false;
14270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
14281f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins        if (null == getTopWindow()) {
14290d7ae0ed82e21d472cde8cf92b5657d8ee8ca0d8Leon Scroggins            return false;
14300d7ae0ed82e21d472cde8cf92b5657d8ee8ca0d8Leon Scroggins        }
14316ee9c498b8cf648f1507281ed5a1834ba3390907Grace Kloba        if (mMenuIsDown) {
14326ee9c498b8cf648f1507281ed5a1834ba3390907Grace Kloba            // The shortcut action consumes the MENU. Even if it is still down,
14336ee9c498b8cf648f1507281ed5a1834ba3390907Grace Kloba            // it won't trigger the next shortcut action. In the case of the
14346ee9c498b8cf648f1507281ed5a1834ba3390907Grace Kloba            // shortcut action triggering a new activity, like Bookmarks, we
14356ee9c498b8cf648f1507281ed5a1834ba3390907Grace Kloba            // won't get onKeyUp for MENU. So it is important to reset it here.
14366ee9c498b8cf648f1507281ed5a1834ba3390907Grace Kloba            mMenuIsDown = false;
14376ee9c498b8cf648f1507281ed5a1834ba3390907Grace Kloba        }
14380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        switch (item.getItemId()) {
14390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // -- Main menu
1440a81a764063d2f849fba0cbc3039f86e67c2960ddLeon Scroggins            case R.id.new_tab_menu_id:
14410a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins                openTabToHomePage();
1442a81a764063d2f849fba0cbc3039f86e67c2960ddLeon Scroggins                break;
1443a81a764063d2f849fba0cbc3039f86e67c2960ddLeon Scroggins
144464b80f3efd95d7b5192731e995ccde79c4c6c11fLeon Scroggins            case R.id.goto_menu_id:
1445b3a5bedeede968b53363a6c517f92bc2484bb42dLeon Scroggins                onSearchRequested();
1446b3a5bedeede968b53363a6c517f92bc2484bb42dLeon Scroggins                break;
1447b3a5bedeede968b53363a6c517f92bc2484bb42dLeon Scroggins
1448b3a5bedeede968b53363a6c517f92bc2484bb42dLeon Scroggins            case R.id.bookmarks_menu_id:
1449304442375719effd41dbd53ae62de7a8d0cec7d9Leon Scroggins                bookmarksOrHistoryPicker(false);
14500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
14510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
14520a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins            case R.id.active_tabs_menu_id:
14530a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins                mActiveTabsPage = new ActiveTabsPage(this, mTabControl);
14540a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins                removeTabFromContentView(mTabControl.getCurrentTab());
145543de61666cfc98a3acc41c7161a1a8b0bdb2b72bLeon Scroggins                hideFakeTitleBar();
14560a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins                mContentView.addView(mActiveTabsPage, COVER_SCREEN_PARAMS);
14570a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins                mActiveTabsPage.requestFocus();
14580a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins                mMenuState = EMPTY_MENU;
14590a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins                break;
14600a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins
14611f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins            case R.id.add_bookmark_menu_id:
14621f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                Intent i = new Intent(BrowserActivity.this,
14631f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                        AddBookmarkPage.class);
14641f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                WebView w = getTopWindow();
14651f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                i.putExtra("url", w.getUrl());
14661f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                i.putExtra("title", w.getTitle());
146783cdb2c40f2dbcbdf522a2af0ec8224c7195c6c1Grace Kloba                i.putExtra("touch_icon_url", w.getTouchIconUrl());
1468dcc2b6f08dd5677bc6ba761a9ba6f1c655113051Ben Murdoch                i.putExtra("thumbnail", createScreenshot(w));
14691f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                startActivity(i);
14700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
14710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
14720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.stop_reload_menu_id:
14730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (mInLoad) {
14740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    stopLoading();
14750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                } else {
14760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    getTopWindow().reload();
14770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
14780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
14790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
14800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.back_menu_id:
14810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                getTopWindow().goBack();
14820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
14830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
14840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.forward_menu_id:
14850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                getTopWindow().goForward();
14860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
14870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
14880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.close_menu_id:
14890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // Close the subwindow if it exists.
14900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (mTabControl.getCurrentSubWindow() != null) {
14910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    dismissSubWindow(mTabControl.getCurrentTab());
14920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    break;
14930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
14941f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                closeCurrentWindow();
14950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
14960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
14970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.homepage_menu_id:
149822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                Tab current = mTabControl.getCurrentTab();
14990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (current != null) {
15000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    dismissSubWindow(current);
15010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    current.getWebView().loadUrl(mSettings.getHomePage());
15020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
15030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
15040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
15050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.preferences_menu_id:
15060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                Intent intent = new Intent(this,
15070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        BrowserPreferencesPage.class);
1508d530494de9c182af4aff97ddd46343b32594da51Leon Scroggins                intent.putExtra(BrowserPreferencesPage.CURRENT_PAGE,
1509d530494de9c182af4aff97ddd46343b32594da51Leon Scroggins                        getTopWindow().getUrl());
15100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                startActivityForResult(intent, PREFERENCES_PAGE);
15110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
15120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
15130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.find_menu_id:
15140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (null == mFindDialog) {
15150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    mFindDialog = new FindDialog(this);
15160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
15170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mFindDialog.setWebView(getTopWindow());
15180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mFindDialog.show();
15190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mMenuState = EMPTY_MENU;
15200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
15210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
15220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.select_text_id:
15230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                getTopWindow().emulateShiftHeld();
15240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
15250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.page_info_menu_id:
15260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                showPageInfo(mTabControl.getCurrentTab(), false);
15270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
15280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
15290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.classic_history_menu_id:
1530304442375719effd41dbd53ae62de7a8d0cec7d9Leon Scroggins                bookmarksOrHistoryPicker(true);
15310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
15320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
153396afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins            case R.id.title_bar_share_page_url:
15340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.share_page_menu_id:
153596afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                Tab currentTab = mTabControl.getCurrentTab();
153696afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                if (null == currentTab) {
153796afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                    mCanChord = false;
153896afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                    return false;
153996afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                }
154096afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                currentTab.populatePickerData();
154196afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                sharePage(this, currentTab.getTitle(),
154296afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                        currentTab.getUrl(), currentTab.getFavicon(),
154396afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                        createScreenshot(currentTab.getWebView()));
15440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
15450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
15460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.dump_nav_menu_id:
15470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                getTopWindow().debugDump();
15480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
15490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
15507a8b88b0e0f20544df5ee34b798398603261b733Andrei Popescu            case R.id.dump_counters_menu_id:
15517a8b88b0e0f20544df5ee34b798398603261b733Andrei Popescu                getTopWindow().dumpV8Counters();
15527a8b88b0e0f20544df5ee34b798398603261b733Andrei Popescu                break;
15537a8b88b0e0f20544df5ee34b798398603261b733Andrei Popescu
15540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.zoom_in_menu_id:
15550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                getTopWindow().zoomIn();
15560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
15570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
15580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.zoom_out_menu_id:
15590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                getTopWindow().zoomOut();
15600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
15610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
15620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.view_downloads_menu_id:
15630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                viewDownloads(null);
15640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
15650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
15660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.window_one_menu_id:
15670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.window_two_menu_id:
15680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.window_three_menu_id:
15690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.window_four_menu_id:
15700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.window_five_menu_id:
15710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.window_six_menu_id:
15720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.window_seven_menu_id:
15730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.window_eight_menu_id:
15740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                {
15750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    int menuid = item.getItemId();
15760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    for (int id = 0; id < WINDOW_SHORTCUT_ID_ARRAY.length; id++) {
15770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        if (WINDOW_SHORTCUT_ID_ARRAY[id] == menuid) {
157822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            Tab desiredTab = mTabControl.getTab(id);
15790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            if (desiredTab != null &&
15800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    desiredTab != mTabControl.getCurrentTab()) {
15811f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                                switchToTab(id);
15820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            }
15830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            break;
15840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }
15850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
15860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
15870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
15880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
15890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            default:
15900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (!super.onOptionsItemSelected(item)) {
15910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    return false;
15920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
15930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // Otherwise fall through.
15940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
15950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mCanChord = false;
15960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return true;
15970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
15980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
15990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public void closeFind() {
16000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mMenuState = R.id.MAIN_MENU;
16010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
16020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
160322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    @Override
160422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    public boolean onPrepareOptionsMenu(Menu menu) {
16050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // This happens when the user begins to hold down the menu key, so
16060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // allow them to chord to get a shortcut.
16070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mCanChord = true;
16080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Note: setVisible will decide whether an item is visible; while
16090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // setEnabled() will decide whether an item is enabled, which also means
16100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // whether the matching shortcut key will function.
16110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        super.onPrepareOptionsMenu(menu);
16120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        switch (mMenuState) {
16130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case EMPTY_MENU:
16140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (mCurrentMenuState != mMenuState) {
16150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    menu.setGroupVisible(R.id.MAIN_MENU, false);
16160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    menu.setGroupEnabled(R.id.MAIN_MENU, false);
16170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    menu.setGroupEnabled(R.id.MAIN_SHORTCUT_MENU, false);
16180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
16190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
16200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            default:
16210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (mCurrentMenuState != mMenuState) {
16220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    menu.setGroupVisible(R.id.MAIN_MENU, true);
16230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    menu.setGroupEnabled(R.id.MAIN_MENU, true);
16240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    menu.setGroupEnabled(R.id.MAIN_SHORTCUT_MENU, true);
16250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
16260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                final WebView w = getTopWindow();
16270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                boolean canGoBack = false;
16280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                boolean canGoForward = false;
16290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                boolean isHome = false;
16300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (w != null) {
16310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    canGoBack = w.canGoBack();
16320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    canGoForward = w.canGoForward();
16330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    isHome = mSettings.getHomePage().equals(w.getUrl());
16340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
16350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                final MenuItem back = menu.findItem(R.id.back_menu_id);
16360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                back.setEnabled(canGoBack);
16370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
16380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                final MenuItem home = menu.findItem(R.id.homepage_menu_id);
16390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                home.setEnabled(!isHome);
16400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
16410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.forward_menu_id)
16420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        .setEnabled(canGoForward);
16430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
1644a81a764063d2f849fba0cbc3039f86e67c2960ddLeon Scroggins                menu.findItem(R.id.new_tab_menu_id).setEnabled(
164522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        mTabControl.canCreateNewTab());
1646a81a764063d2f849fba0cbc3039f86e67c2960ddLeon Scroggins
16470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // decide whether to show the share link option
16480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                PackageManager pm = getPackageManager();
16490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                Intent send = new Intent(Intent.ACTION_SEND);
16500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                send.setType("text/plain");
16510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                ResolveInfo ri = pm.resolveActivity(send, PackageManager.MATCH_DEFAULT_ONLY);
16520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.share_page_menu_id).setVisible(ri != null);
16530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
16540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                boolean isNavDump = mSettings.isNavDump();
16550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                final MenuItem nav = menu.findItem(R.id.dump_nav_menu_id);
16560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                nav.setVisible(isNavDump);
16570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                nav.setEnabled(isNavDump);
16587a8b88b0e0f20544df5ee34b798398603261b733Andrei Popescu
16597a8b88b0e0f20544df5ee34b798398603261b733Andrei Popescu                boolean showDebugSettings = mSettings.showDebugSettings();
16607a8b88b0e0f20544df5ee34b798398603261b733Andrei Popescu                final MenuItem counter = menu.findItem(R.id.dump_counters_menu_id);
16617a8b88b0e0f20544df5ee34b798398603261b733Andrei Popescu                counter.setVisible(showDebugSettings);
16627a8b88b0e0f20544df5ee34b798398603261b733Andrei Popescu                counter.setEnabled(showDebugSettings);
16637a8b88b0e0f20544df5ee34b798398603261b733Andrei Popescu
16640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
16650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
16660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mCurrentMenuState = mMenuState;
16670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return true;
16680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
16690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
16700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    @Override
16710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public void onCreateContextMenu(ContextMenu menu, View v,
16720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ContextMenuInfo menuInfo) {
16730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebView webview = (WebView) v;
16740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebView.HitTestResult result = webview.getHitTestResult();
16750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (result == null) {
16760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
16770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
16780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
16790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        int type = result.getType();
16800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (type == WebView.HitTestResult.UNKNOWN_TYPE) {
16810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Log.w(LOGTAG,
16820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    "We should not show context menu when nothing is touched");
16830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
16840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
16850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (type == WebView.HitTestResult.EDIT_TEXT_TYPE) {
16860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // let TextView handles context menu
16870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
16880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
16890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
16900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Note, http://b/issue?id=1106666 is requesting that
16910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // an inflated menu can be used again. This is not available
16920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // yet, so inflate each time (yuk!)
16930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        MenuInflater inflater = getMenuInflater();
16940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        inflater.inflate(R.menu.browsercontext, menu);
16950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
16960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Show the correct menu group
16970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String extra = result.getExtra();
16980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        menu.setGroupVisible(R.id.PHONE_MENU,
16990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                type == WebView.HitTestResult.PHONE_TYPE);
17000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        menu.setGroupVisible(R.id.EMAIL_MENU,
17010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                type == WebView.HitTestResult.EMAIL_TYPE);
17020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        menu.setGroupVisible(R.id.GEO_MENU,
17030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                type == WebView.HitTestResult.GEO_TYPE);
17040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        menu.setGroupVisible(R.id.IMAGE_MENU,
17050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                type == WebView.HitTestResult.IMAGE_TYPE
17060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                || type == WebView.HitTestResult.SRC_IMAGE_ANCHOR_TYPE);
17070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        menu.setGroupVisible(R.id.ANCHOR_MENU,
17080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                type == WebView.HitTestResult.SRC_ANCHOR_TYPE
17090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                || type == WebView.HitTestResult.SRC_IMAGE_ANCHOR_TYPE);
17100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
17110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Setup custom handling depending on the type
17120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        switch (type) {
17130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case WebView.HitTestResult.PHONE_TYPE:
17140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.setHeaderTitle(Uri.decode(extra));
17150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.dial_context_menu_id).setIntent(
17160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new Intent(Intent.ACTION_VIEW, Uri
17170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                .parse(WebView.SCHEME_TEL + extra)));
17180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                Intent addIntent = new Intent(Intent.ACTION_INSERT_OR_EDIT);
17190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                addIntent.putExtra(Insert.PHONE, Uri.decode(extra));
17205e335a381a0cd66e94117b202c1f34f5cb29c9b8Cary Clark                addIntent.setType(ContactsContract.Contacts.CONTENT_ITEM_TYPE);
17210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.add_contact_context_menu_id).setIntent(
17220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        addIntent);
17230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.copy_phone_context_menu_id).setOnMenuItemClickListener(
17240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new Copy(extra));
17250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
17260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
17270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case WebView.HitTestResult.EMAIL_TYPE:
17280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.setHeaderTitle(extra);
17290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.email_context_menu_id).setIntent(
17300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new Intent(Intent.ACTION_VIEW, Uri
17310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                .parse(WebView.SCHEME_MAILTO + extra)));
17320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.copy_mail_context_menu_id).setOnMenuItemClickListener(
17330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new Copy(extra));
17340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
17350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
17360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case WebView.HitTestResult.GEO_TYPE:
17370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.setHeaderTitle(extra);
17380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.map_context_menu_id).setIntent(
17390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new Intent(Intent.ACTION_VIEW, Uri
17400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                .parse(WebView.SCHEME_GEO
17410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        + URLEncoder.encode(extra))));
17420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.copy_geo_context_menu_id).setOnMenuItemClickListener(
17430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new Copy(extra));
17440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
17450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
17460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case WebView.HitTestResult.SRC_ANCHOR_TYPE:
17470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case WebView.HitTestResult.SRC_IMAGE_ANCHOR_TYPE:
17480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                TextView titleView = (TextView) LayoutInflater.from(this)
17490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        .inflate(android.R.layout.browser_link_context_header,
17500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        null);
17510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                titleView.setText(extra);
17520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.setHeaderView(titleView);
17530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // decide whether to show the open link in new tab option
17540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.open_newtab_context_menu_id).setVisible(
175522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        mTabControl.canCreateNewTab());
1756de353621650d17a412b6ffe2cbf0366db5f11c40Ben Murdoch                menu.findItem(R.id.bookmark_context_menu_id).setVisible(
1757de353621650d17a412b6ffe2cbf0366db5f11c40Ben Murdoch                        Bookmarks.urlHasAcceptableScheme(extra));
17580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                PackageManager pm = getPackageManager();
17590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                Intent send = new Intent(Intent.ACTION_SEND);
17600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                send.setType("text/plain");
17610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                ResolveInfo ri = pm.resolveActivity(send, PackageManager.MATCH_DEFAULT_ONLY);
17620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.share_link_context_menu_id).setVisible(ri != null);
17630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (type == WebView.HitTestResult.SRC_ANCHOR_TYPE) {
17640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    break;
17650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
17660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // otherwise fall through to handle image part
17670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case WebView.HitTestResult.IMAGE_TYPE:
17680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (type == WebView.HitTestResult.IMAGE_TYPE) {
17690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    menu.setHeaderTitle(extra);
17700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
17710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.view_image_context_menu_id).setIntent(
17720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new Intent(Intent.ACTION_VIEW, Uri.parse(extra)));
17730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.download_context_menu_id).
17740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        setOnMenuItemClickListener(new Download(extra));
17754f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                menu.findItem(R.id.set_wallpaper_context_menu_id).
17764f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                        setOnMenuItemClickListener(new SetAsWallpaper(extra));
17770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
17780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
17790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            default:
17800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                Log.w(LOGTAG, "We should not get here.");
17810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
17820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
1783b2b19f501ee05448ca81bddaaca70e9b2f51cb54Leon Scroggins        hideFakeTitleBar();
17840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
17850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
17860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Attach the given tab to the content view.
1787c928c30a51eee84b40cb7045842c288c1cfafff0Grace Kloba    // this should only be called for the current tab.
178822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private void attachTabToContentView(Tab t) {
17892bc69918d97a767a02132090e58718077381ba1aSteve Block        // Attach the container that contains the main WebView and any other UI
17902bc69918d97a767a02132090e58718077381ba1aSteve Block        // associated with the tab.
1791d0119535d0c490e087be114ae8fd1639bb1945dcPatrick Scott        t.attachTabToContentView(mContentView);
1792bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch
1793bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch        if (mShouldShowErrorConsole) {
179422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            ErrorConsoleView errorConsole = t.getErrorConsole(true);
1795bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch            if (errorConsole.numberOfErrors() == 0) {
1796bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch                errorConsole.showConsole(ErrorConsoleView.SHOW_NONE);
1797bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch            } else {
1798bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch                errorConsole.showConsole(ErrorConsoleView.SHOW_MINIMIZED);
1799bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch            }
1800bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch
1801bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch            mErrorConsoleContainer.addView(errorConsole,
180215b8ec6b226f4d57307716e1f495e10a91f8cbf4Romain Guy                    new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
1803bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch                                                  ViewGroup.LayoutParams.WRAP_CONTENT));
1804bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch        }
1805bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch
180639ab28eba0c8c837ac80851ec0dd2af336aa3f85Leon Scroggins        WebView view = t.getWebView();
180755a5bc2a8f3c9a0721eeaa5a45241e00d5da95efLeon Scroggins        view.setEmbeddedTitleBar(mTitleBar);
180858d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        if (t.isInVoiceSearchMode()) {
180958d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins            showVoiceTitleBar(t.getVoiceDisplayTitle());
181058d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        } else {
181158d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins            revertVoiceTitleBar();
181258d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        }
18130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Request focus on the top window.
18140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        t.getTopWindow().requestFocus();
18150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
18160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
18170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Attach a sub window to the main WebView of the given tab.
181822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void attachSubWindow(Tab t) {
1819d0119535d0c490e087be114ae8fd1639bb1945dcPatrick Scott        t.attachSubWindow(mContentView);
1820d0119535d0c490e087be114ae8fd1639bb1945dcPatrick Scott        getTopWindow().requestFocus();
18210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
18220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
18230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Remove the given tab from the content view.
182422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private void removeTabFromContentView(Tab t) {
18252bc69918d97a767a02132090e58718077381ba1aSteve Block        // Remove the container that contains the main WebView.
1826d0119535d0c490e087be114ae8fd1639bb1945dcPatrick Scott        t.removeTabFromContentView(mContentView);
1827bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch
182822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        ErrorConsoleView errorConsole = t.getErrorConsole(false);
182922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (errorConsole != null) {
183022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mErrorConsoleContainer.removeView(errorConsole);
1831bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch        }
1832bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch
183339ab28eba0c8c837ac80851ec0dd2af336aa3f85Leon Scroggins        WebView view = t.getWebView();
1834bb85b9016201d45ea939d7cb7edd0ba6616a111cLeon Scroggins        if (view != null) {
1835bb85b9016201d45ea939d7cb7edd0ba6616a111cLeon Scroggins            view.setEmbeddedTitleBar(null);
1836bb85b9016201d45ea939d7cb7edd0ba6616a111cLeon Scroggins        }
18370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
18380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
18390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Remove the sub window if it exists. Also called by TabControl when the
18400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // user clicks the 'X' to dismiss a sub window.
184122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /* package */ void dismissSubWindow(Tab t) {
1842d0119535d0c490e087be114ae8fd1639bb1945dcPatrick Scott        t.removeSubWindow(mContentView);
184322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // dismiss the subwindow. This will destroy the WebView.
184422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        t.dismissSubWindow();
1845d0119535d0c490e087be114ae8fd1639bb1945dcPatrick Scott        getTopWindow().requestFocus();
18460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
18470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
18481f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins    // A wrapper function of {@link #openTabAndShow(UrlData, boolean, String)}
184925ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima    // that accepts url as string.
185022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private Tab openTabAndShow(String url, boolean closeOnExit, String appId) {
18511f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins        return openTabAndShow(new UrlData(url), closeOnExit, appId);
18520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
18530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
18540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // This method does a ton of stuff. It will attempt to create a new tab
18550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // if we haven't reached MAX_TABS. Otherwise it uses the current tab. If
18561f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins    // url isn't null, it will load the given url.
185722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /* package */Tab openTabAndShow(UrlData urlData, boolean closeOnExit,
185822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            String appId) {
185922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        final Tab currentTab = mTabControl.getCurrentTab();
186022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mTabControl.canCreateNewTab()) {
186122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            final Tab tab = mTabControl.createNewTab(closeOnExit, appId,
186222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    urlData.mUrl);
18631f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins            WebView webview = tab.getWebView();
18640a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins            // If the last tab was removed from the active tabs page, currentTab
18650a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins            // will be null.
18660a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins            if (currentTab != null) {
18670a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins                removeTabFromContentView(currentTab);
18680a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins            }
18698bbd69f50abd537bfe7eb314b3a3e20241ac22bdPatrick Scott            // We must set the new tab as the current tab to reflect the old
18708bbd69f50abd537bfe7eb314b3a3e20241ac22bdPatrick Scott            // animation behavior.
18718bbd69f50abd537bfe7eb314b3a3e20241ac22bdPatrick Scott            mTabControl.setCurrentTab(tab);
1872eb6eef4c45df2d65c3e70660493a147a2be405e3Grace Kloba            attachTabToContentView(tab);
1873160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins            if (!urlData.isEmpty()) {
187458d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins                urlData.loadIn(tab);
18750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
18761f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins            return tab;
187764b80f3efd95d7b5192731e995ccde79c4c6c11fLeon Scroggins        } else {
18781f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins            // Get rid of the subwindow if it exists
18791f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins            dismissSubWindow(currentTab);
18801f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins            if (!urlData.isEmpty()) {
18811f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                // Load the given url.
188258d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins                urlData.loadIn(currentTab);
18830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
188458d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins            return currentTab;
18850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
18860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
18870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
188822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private Tab openTab(String url) {
18890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mSettings.openInBackground()) {
189022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            Tab t = mTabControl.createNewTab();
18910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (t != null) {
18921f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                WebView view = t.getWebView();
18931f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                view.loadUrl(url);
18940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
1895c9181841c7ed6b9f7dfc953eab8dc7ba1047022cGrace Kloba            return t;
18960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
18971f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins            return openTabAndShow(url, false, null);
18980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
18990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
19000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
19010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private class Copy implements OnMenuItemClickListener {
19020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        private CharSequence mText;
19030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
19040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public boolean onMenuItemClick(MenuItem item) {
19050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            copy(mText);
19060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return true;
19070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
19080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
19090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public Copy(CharSequence toCopy) {
19100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mText = toCopy;
19110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
19120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
19130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
19140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private class Download implements OnMenuItemClickListener {
19150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        private String mText;
19160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
19170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public boolean onMenuItemClick(MenuItem item) {
19180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            onDownloadStartNoStream(mText, null, null, null, -1);
19190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return true;
19200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
19210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
19220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public Download(String toDownload) {
19230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mText = toDownload;
19240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
19250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
19260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
19274f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch    private class SetAsWallpaper extends Thread implements
19284f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch            OnMenuItemClickListener, DialogInterface.OnCancelListener {
19294f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch        private URL mUrl;
19304f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch        private ProgressDialog mWallpaperProgress;
19314f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch        private boolean mCanceled = false;
19324f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch
19334f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch        public SetAsWallpaper(String url) {
19344f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch            try {
19354f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                mUrl = new URL(url);
19364f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch            } catch (MalformedURLException e) {
19374f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                mUrl = null;
19384f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch            }
19394f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch        }
19404f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch
19414f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch        public void onCancel(DialogInterface dialog) {
19424f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch            mCanceled = true;
19434f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch        }
19444f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch
19454f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch        public boolean onMenuItemClick(MenuItem item) {
19464f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch            if (mUrl != null) {
19474f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                // The user may have tried to set a image with a large file size as their
19484f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                // background so it may take a few moments to perform the operation. Display
19494f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                // a progress spinner while it is working.
19504f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                mWallpaperProgress = new ProgressDialog(BrowserActivity.this);
19514f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                mWallpaperProgress.setIndeterminate(true);
19524f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                mWallpaperProgress.setMessage(getText(R.string.progress_dialog_setting_wallpaper));
19534f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                mWallpaperProgress.setCancelable(true);
19544f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                mWallpaperProgress.setOnCancelListener(this);
19554f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                mWallpaperProgress.show();
19564f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                start();
19574f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch            }
19584f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch            return true;
19594f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch        }
19604f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch
19614f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch        public void run() {
19624f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch            Drawable oldWallpaper = BrowserActivity.this.getWallpaper();
19634f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch            try {
19644f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                // TODO: This will cause the resource to be downloaded again, when we
19654f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                // should in most cases be able to grab it from the cache. To fix this
19664f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                // we should query WebCore to see if we can access a cached version and
19674f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                // instead open an input stream on that. This pattern could also be used
19684f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                // in the download manager where the same problem exists.
19694f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                InputStream inputstream = mUrl.openStream();
19704f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                if (inputstream != null) {
19714f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                    setWallpaper(inputstream);
19724f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                }
19734f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch            } catch (IOException e) {
19744f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                Log.e(LOGTAG, "Unable to set new wallpaper");
19754f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                // Act as though the user canceled the operation so we try to
19764f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                // restore the old wallpaper.
19774f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                mCanceled = true;
19784f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch            }
19794f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch
19804f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch            if (mCanceled) {
19814f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                // Restore the old wallpaper if the user cancelled whilst we were setting
19824f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                // the new wallpaper.
19834f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                int width = oldWallpaper.getIntrinsicWidth();
19844f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                int height = oldWallpaper.getIntrinsicHeight();
19854f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                Bitmap bm = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);
19864f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                Canvas canvas = new Canvas(bm);
19874f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                oldWallpaper.setBounds(0, 0, width, height);
19884f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                oldWallpaper.draw(canvas);
19894f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                try {
19904f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                    setWallpaper(bm);
19914f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                } catch (IOException e) {
19924f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                    Log.e(LOGTAG, "Unable to restore old wallpaper.");
19934f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                }
19944f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                mCanceled = false;
19954f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch            }
19964f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch
19974f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch            if (mWallpaperProgress.isShowing()) {
19984f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                mWallpaperProgress.dismiss();
19994f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch            }
20004f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch        }
20014f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch    }
20024f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch
20030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void copy(CharSequence text) {
20040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        try {
20050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            IClipboard clip = IClipboard.Stub.asInterface(ServiceManager.getService("clipboard"));
20060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (clip != null) {
20070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                clip.setClipboardText(text);
20080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
20090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } catch (android.os.RemoteException e) {
20100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Log.e(LOGTAG, "Copy failed", e);
20110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
20120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
20130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
20140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
20150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Resets the browser title-view to whatever it must be
20160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * (for example, if we had a loading error)
20170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * When we have a new page, we call resetTitle, when we
20180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * have to reset the titlebar to whatever it used to be
20190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * (for example, if the user chose to stop loading), we
20200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * call resetTitleAndRevertLockIcon.
20210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
20220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /* package */ void resetTitleAndRevertLockIcon() {
202322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mTabControl.getCurrentTab().revertLockIcon();
202422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        updateLockIconToLatest();
20250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        resetTitleIconAndProgress();
20260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
20270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
20280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
20290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Reset the title, favicon, and progress.
20300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
20310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void resetTitleIconAndProgress() {
20320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebView current = mTabControl.getCurrentWebView();
20330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (current == null) {
20340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
20350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
20360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        resetTitleAndIcon(current);
20370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        int progress = current.getProgress();
203822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        current.getWebChromeClient().onProgressChanged(current, progress);
20390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
20400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
20410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Reset the title and the icon based on the given item.
20420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void resetTitleAndIcon(WebView view) {
20430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebHistoryItem item = view.copyBackForwardList().getCurrentItem();
20440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (item != null) {
204568579393973f745fc65a2781061af9bb8f2d7020Leon Scroggins            setUrlTitle(item.getUrl(), item.getTitle());
20460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            setFavicon(item.getFavicon());
20470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
204868579393973f745fc65a2781061af9bb8f2d7020Leon Scroggins            setUrlTitle(null, null);
20490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            setFavicon(null);
20500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
20510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
20520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
20530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
20540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Sets a title composed of the URL and the title string.
20550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param url The URL of the site being loaded.
20560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param title The title of the site being loaded.
20570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
205822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void setUrlTitle(String url, String title) {
20590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mUrl = url;
20600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mTitle = title;
20610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
206258d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        // If we are in voice search mode, the title has already been set.
206358d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        if (mTabControl.getCurrentTab().isInVoiceSearchMode()) return;
206458d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        mTitleBar.setDisplayTitle(url);
206558d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        mFakeTitleBar.setDisplayTitle(url);
20660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
20670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
20680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
20690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param url The URL to build a title version of the URL from.
20700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @return The title version of the URL or null if fails.
20710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * The title version of the URL can be either the URL hostname,
20720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * or the hostname with an "https://" prefix (for secure URLs),
20730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * or an empty string if, for example, the URL in question is a
20740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * file:// URL with no hostname.
20750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
207632e14a6deccfa75490b3032bb4ddd5ae90f89de8Leon Scroggins    /* package */ static String buildTitleUrl(String url) {
20770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String titleUrl = null;
20780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
20790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (url != null) {
20800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            try {
20810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // parse the url string
20820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                URL urlObj = new URL(url);
20830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (urlObj != null) {
20840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    titleUrl = "";
20850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
20860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    String protocol = urlObj.getProtocol();
20870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    String host = urlObj.getHost();
20880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
20890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    if (host != null && 0 < host.length()) {
20900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        titleUrl = host;
20910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        if (protocol != null) {
20920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            // if a secure site, add an "https://" prefix!
20930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            if (protocol.equalsIgnoreCase("https")) {
20940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                titleUrl = protocol + "://" + host;
20950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            }
20960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }
20970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
20980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
20990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } catch (MalformedURLException e) {}
21000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
21010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
21020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return titleUrl;
21030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
21040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
21050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Set the favicon in the title bar.
210622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void setFavicon(Bitmap icon) {
210768579393973f745fc65a2781061af9bb8f2d7020Leon Scroggins        mTitleBar.setFavicon(icon);
2108fe87bd3a3897e4bad65bb3d284659ae2f4e57570Leon Scroggins        mFakeTitleBar.setFavicon(icon);
21090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
21100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
21110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
21120a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins     * Close the tab, remove its associated title bar, and adjust mTabControl's
21130a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins     * current tab to a valid value.
21141f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins     */
211522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /* package */ void closeTab(Tab t) {
21160a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins        int currentIndex = mTabControl.getCurrentIndex();
21170a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins        int removeIndex = mTabControl.getTabIndex(t);
21181f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins        mTabControl.removeTab(t);
21190a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins        if (currentIndex >= removeIndex && currentIndex != 0) {
21200a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins            currentIndex--;
21210a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins        }
21220a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins        mTabControl.setCurrentTab(mTabControl.getTab(currentIndex));
2123a5bf1deca120315a2643ea5b010f94d853461b15Andrei Popescu        resetTitleIconAndProgress();
21240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
21250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
21260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void goBackOnePageOrQuit() {
212722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        Tab current = mTabControl.getCurrentTab();
21280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (current == null) {
21290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            /*
21300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project             * Instead of finishing the activity, simply push this to the back
21310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project             * of the stack and let ActivityManager to choose the foreground
21320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project             * activity. As BrowserActivity is singleTask, it will be always the
21330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project             * root of the task. So we can use either true or false for
21340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project             * moveTaskToBack().
21350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project             */
21360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            moveTaskToBack(true);
213700d85e74921459b34e70eb93368245b4c0a9bf5fGrace Kloba            return;
21380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
21390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebView w = current.getWebView();
21400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (w.canGoBack()) {
21410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            w.goBack();
21420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
21430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Check to see if we are closing a window that was created by
21440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // another window. If so, we switch back to that window.
214522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            Tab parent = current.getParentTab();
21460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (parent != null) {
21471f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                switchToTab(mTabControl.getTabIndex(parent));
21481f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                // Now we close the other tab
21491f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                closeTab(current);
21500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } else {
21510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (current.closeOnExit()) {
215222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    // force the tab's inLoad() to be false as we are going to
215322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    // either finish the activity or remove the tab. This will
215422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    // ensure pauseWebViewTimers() taking action.
215522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    mTabControl.getCurrentTab().clearInLoad();
21560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    if (mTabControl.getTabCount() == 1) {
21570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        finish();
21580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        return;
21590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
21607bfa63b55644fbf2da1fe6a24b3be0267529202cMike Reed                    // call pauseWebViewTimers() now, we won't be able to call
21617bfa63b55644fbf2da1fe6a24b3be0267529202cMike Reed                    // it in onPause() as the WebView won't be valid.
2162ec1b5ad8d8283b1fbbc5d7fa1cd50ef95b9e594dGrace Kloba                    // Temporarily change mActivityInPause to be true as
2163ec1b5ad8d8283b1fbbc5d7fa1cd50ef95b9e594dGrace Kloba                    // pauseWebViewTimers() will do nothing if mActivityInPause
2164ec1b5ad8d8283b1fbbc5d7fa1cd50ef95b9e594dGrace Kloba                    // is false.
2165918e1d78b2db6ef21c71a07868572d9cda498476Grace Kloba                    boolean savedState = mActivityInPause;
2166918e1d78b2db6ef21c71a07868572d9cda498476Grace Kloba                    if (savedState) {
2167ec1b5ad8d8283b1fbbc5d7fa1cd50ef95b9e594dGrace Kloba                        Log.e(LOGTAG, "BrowserActivity is already paused "
2168ec1b5ad8d8283b1fbbc5d7fa1cd50ef95b9e594dGrace Kloba                                + "while handing goBackOnePageOrQuit.");
2169918e1d78b2db6ef21c71a07868572d9cda498476Grace Kloba                    }
2170918e1d78b2db6ef21c71a07868572d9cda498476Grace Kloba                    mActivityInPause = true;
21717bfa63b55644fbf2da1fe6a24b3be0267529202cMike Reed                    pauseWebViewTimers();
2172918e1d78b2db6ef21c71a07868572d9cda498476Grace Kloba                    mActivityInPause = savedState;
21730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    removeTabFromContentView(current);
21740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    mTabControl.removeTab(current);
21750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
21760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                /*
21770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                 * Instead of finishing the activity, simply push this to the back
21780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                 * of the stack and let ActivityManager to choose the foreground
21790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                 * activity. As BrowserActivity is singleTask, it will be always the
21800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                 * root of the task. So we can use either true or false for
21810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                 * moveTaskToBack().
21820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                 */
21830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                moveTaskToBack(true);
21840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
21850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
21860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
21870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
218822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    boolean isMenuDown() {
218922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return mMenuIsDown;
219022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
219122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
21925942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba    @Override
21935942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba    public boolean onKeyDown(int keyCode, KeyEvent event) {
2194f65b50ddd2f7ed1205002d74082fff1ac2336d5cLeon Scroggins        // Even if MENU is already held down, we need to call to super to open
2195f65b50ddd2f7ed1205002d74082fff1ac2336d5cLeon Scroggins        // the IME on long press.
2196f65b50ddd2f7ed1205002d74082fff1ac2336d5cLeon Scroggins        if (KeyEvent.KEYCODE_MENU == keyCode) {
2197f65b50ddd2f7ed1205002d74082fff1ac2336d5cLeon Scroggins            mMenuIsDown = true;
2198f65b50ddd2f7ed1205002d74082fff1ac2336d5cLeon Scroggins            return super.onKeyDown(keyCode, event);
2199f65b50ddd2f7ed1205002d74082fff1ac2336d5cLeon Scroggins        }
22005942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba        // The default key mode is DEFAULT_KEYS_SEARCH_LOCAL. As the MENU is
22015942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba        // still down, we don't want to trigger the search. Pretend to consume
22025942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba        // the key and do nothing.
22035942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba        if (mMenuIsDown) return true;
22045942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba
22055942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba        switch(keyCode) {
22065942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba            case KeyEvent.KEYCODE_SPACE:
2207da0fe556a00773ce2af25eb6dcc5442bd08c7addGrace Kloba                // WebView/WebTextView handle the keys in the KeyDown. As
2208da0fe556a00773ce2af25eb6dcc5442bd08c7addGrace Kloba                // the Activity's shortcut keys are only handled when WebView
2209da0fe556a00773ce2af25eb6dcc5442bd08c7addGrace Kloba                // doesn't, have to do it in onKeyDown instead of onKeyUp.
2210da0fe556a00773ce2af25eb6dcc5442bd08c7addGrace Kloba                if (event.isShiftPressed()) {
2211da0fe556a00773ce2af25eb6dcc5442bd08c7addGrace Kloba                    getTopWindow().pageUp(false);
2212da0fe556a00773ce2af25eb6dcc5442bd08c7addGrace Kloba                } else {
2213da0fe556a00773ce2af25eb6dcc5442bd08c7addGrace Kloba                    getTopWindow().pageDown(false);
2214da0fe556a00773ce2af25eb6dcc5442bd08c7addGrace Kloba                }
22155942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                return true;
22165942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba            case KeyEvent.KEYCODE_BACK:
22175942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                if (event.getRepeatCount() == 0) {
22185942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                    event.startTracking();
22195942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                    return true;
22205942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                } else if (mCustomView == null && mActiveTabsPage == null
22215942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                        && event.isLongPress()) {
22225942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                    bookmarksOrHistoryPicker(true);
22235942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                    return true;
22240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
22255942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                break;
22260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
22275942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba        return super.onKeyDown(keyCode, event);
22280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
22290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
22305942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba    @Override
22315942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba    public boolean onKeyUp(int keyCode, KeyEvent event) {
22325942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba        switch(keyCode) {
22335942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba            case KeyEvent.KEYCODE_MENU:
22345942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                mMenuIsDown = false;
22355942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                break;
22365942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba            case KeyEvent.KEYCODE_BACK:
22375942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                if (event.isTracking() && !event.isCanceled()) {
22385942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                    if (mCustomView != null) {
22395942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                        // if a custom view is showing, hide it
224022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        mTabControl.getCurrentWebView().getWebChromeClient()
224122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                .onHideCustomView();
22425942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                    } else if (mActiveTabsPage != null) {
22435942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                        // if tab page is showing, hide it
22445942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                        removeActiveTabPage(true);
22450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    } else {
22465942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                        WebView subwindow = mTabControl.getCurrentSubWindow();
22475942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                        if (subwindow != null) {
22485942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                            if (subwindow.canGoBack()) {
22495942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                                subwindow.goBack();
22505942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                            } else {
22515942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                                dismissSubWindow(mTabControl.getCurrentTab());
22525942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                            }
22535942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                        } else {
22545942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                            goBackOnePageOrQuit();
22555942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                        }
22560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
22575942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                    return true;
22585942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                }
22595942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                break;
22600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
22615942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba        return super.onKeyUp(keyCode, event);
22620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
22630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
226468579393973f745fc65a2781061af9bb8f2d7020Leon Scroggins    /* package */ void stopLoading() {
2265b7cc8b439dc595dc48e1c2183b35d23ad72dfbe5Ben Murdoch        mDidStopLoad = true;
22660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        resetTitleAndRevertLockIcon();
22670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebView w = getTopWindow();
22680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        w.stopLoading();
226922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // FIXME: before refactor, it is using mWebViewClient. So I keep the
227022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // same logic here. But for subwindow case, should we call into the main
227122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // WebView's onPageFinished as we never call its onPageStarted and if
227222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // the page finishes itself, we don't call onPageFinished.
227322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mTabControl.getCurrentWebView().getWebViewClient().onPageFinished(w,
227422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                w.getUrl());
22750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
22760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        cancelStopToast();
22770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mStopToast = Toast
22780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .makeText(this, R.string.stopping, Toast.LENGTH_SHORT);
22790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mStopToast.show();
22800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
22810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
228222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    boolean didUserStopLoading() {
228322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return mDidStopLoad;
228422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
228522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
22860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void cancelStopToast() {
22870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mStopToast != null) {
22880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mStopToast.cancel();
22890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mStopToast = null;
22900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
22910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
22920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
229322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // called by a UI or non-UI thread to post the message
229422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    public void postMessage(int what, int arg1, int arg2, Object obj,
229522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            long delayMillis) {
229622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mHandler.sendMessageDelayed(mHandler.obtainMessage(what, arg1, arg2,
229722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                obj), delayMillis);
229822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
229922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
230022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // called by a UI or non-UI thread to remove the message
230122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void removeMessages(int what, Object object) {
230222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mHandler.removeMessages(what, object);
23030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
23040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
23050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // public message ids
23060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public final static int LOAD_URL                = 1001;
23070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public final static int STOP_LOAD               = 1002;
23080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
23090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Message Ids
23100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private static final int FOCUS_NODE_HREF         = 102;
23110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private static final int CANCEL_CREDS_REQUEST    = 103;
231292c18a52ca7a79c114028b5ba22c3dfe443bd1a4Grace Kloba    private static final int RELEASE_WAKELOCK        = 107;
23130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
231422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    static final int UPDATE_BOOKMARK_THUMBNAIL       = 108;
23152694e23a55d5ca526fc29534a80a200e2c58698bBen Murdoch
23160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Private handler for handling javascript and saving passwords
23170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private Handler mHandler = new Handler() {
23180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
23190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public void handleMessage(Message msg) {
23200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            switch (msg.what) {
23210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                case FOCUS_NODE_HREF:
23222694e23a55d5ca526fc29534a80a200e2c58698bBen Murdoch                {
23230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    String url = (String) msg.getData().get("url");
232490d088caeee718f89755ee9c25249ba6da15ab97Ben Murdoch                    String title = (String) msg.getData().get("title");
23250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    if (url == null || url.length() == 0) {
23260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        break;
23270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
23280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    HashMap focusNodeMap = (HashMap) msg.obj;
23290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    WebView view = (WebView) focusNodeMap.get("webview");
23300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // Only apply the action if the top window did not change.
23310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    if (getTopWindow() != view) {
23320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        break;
23330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
23340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    switch (msg.arg1) {
23350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        case R.id.open_context_menu_id:
23360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        case R.id.view_image_context_menu_id:
23370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            loadURL(getTopWindow(), url);
23380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            break;
23390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        case R.id.open_newtab_context_menu_id:
234022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            final Tab parent = mTabControl.getCurrentTab();
234122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            final Tab newTab = openTab(url);
2342c9181841c7ed6b9f7dfc953eab8dc7ba1047022cGrace Kloba                            if (newTab != parent) {
2343c9181841c7ed6b9f7dfc953eab8dc7ba1047022cGrace Kloba                                parent.addChildTab(newTab);
2344c9181841c7ed6b9f7dfc953eab8dc7ba1047022cGrace Kloba                            }
23450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            break;
23460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        case R.id.bookmark_context_menu_id:
23470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            Intent intent = new Intent(BrowserActivity.this,
23480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    AddBookmarkPage.class);
23490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            intent.putExtra("url", url);
235090d088caeee718f89755ee9c25249ba6da15ab97Ben Murdoch                            intent.putExtra("title", title);
23510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            startActivity(intent);
23520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            break;
23530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        case R.id.share_link_context_menu_id:
235496afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                            // See if this site has been visited before
235596afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                            StringBuilder sb = new StringBuilder(
235696afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                                    Browser.BookmarkColumns.URL + " = ");
235796afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                            DatabaseUtils.appendEscapedSQLString(sb, url);
235896afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                            Cursor c = mResolver.query(Browser.BOOKMARKS_URI,
235996afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                                    Browser.HISTORY_PROJECTION,
236096afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                                    sb.toString(),
236196afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                                    null,
236296afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                                    null);
236396afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                            if (c.moveToFirst()) {
236496afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                                // The site has been visited before, so grab the
236596afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                                // info from the database.
236696afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                                Bitmap favicon = null;
236796afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                                Bitmap thumbnail = null;
236896afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                                String linkTitle = c.getString(Browser.
236996afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                                        HISTORY_PROJECTION_TITLE_INDEX);
237096afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                                byte[] data = c.getBlob(Browser.
237196afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                                        HISTORY_PROJECTION_FAVICON_INDEX);
237296afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                                if (data != null) {
237396afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                                    favicon = BitmapFactory.decodeByteArray(
237496afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                                            data, 0, data.length);
237596afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                                }
237696afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                                data = c.getBlob(Browser.
237796afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                                        HISTORY_PROJECTION_THUMBNAIL_INDEX);
237896afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                                if (data != null) {
237996afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                                    thumbnail = BitmapFactory.decodeByteArray(
238096afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                                            data, 0, data.length);
238196afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                                }
238296afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                                sharePage(BrowserActivity.this,
238396afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                                        linkTitle, url, favicon, thumbnail);
238496afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                            } else {
238596afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                                Browser.sendString(BrowserActivity.this, url,
238696afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                                        getString(
238796afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                                        R.string.choosertitle_sharevia));
238896afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                            }
23890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            break;
23900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        case R.id.copy_link_context_menu_id:
23910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            copy(url);
23920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            break;
23930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        case R.id.save_link_context_menu_id:
23940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        case R.id.download_context_menu_id:
23950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            onDownloadStartNoStream(url, null, null, null, -1);
23960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            break;
23970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
23980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    break;
23992694e23a55d5ca526fc29534a80a200e2c58698bBen Murdoch                }
24000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
24010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                case LOAD_URL:
24020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    loadURL(getTopWindow(), (String) msg.obj);
24030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    break;
24040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
24050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                case STOP_LOAD:
24060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    stopLoading();
24070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    break;
24080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
24090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                case CANCEL_CREDS_REQUEST:
24100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    resumeAfterCredentials();
24110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    break;
24120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
24130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                case RELEASE_WAKELOCK:
24140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    if (mWakeLock.isHeld()) {
24150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        mWakeLock.release();
24165d0e02e646e46b14289168f75c2a8f6ed43cac54Grace Kloba                        // if we reach here, Browser should be still in the
24175d0e02e646e46b14289168f75c2a8f6ed43cac54Grace Kloba                        // background loading after WAKELOCK_TIMEOUT (5-min).
24185d0e02e646e46b14289168f75c2a8f6ed43cac54Grace Kloba                        // To avoid burning the battery, stop loading.
24195d0e02e646e46b14289168f75c2a8f6ed43cac54Grace Kloba                        mTabControl.stopAllLoading();
24200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
24210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    break;
24222694e23a55d5ca526fc29534a80a200e2c58698bBen Murdoch
24232694e23a55d5ca526fc29534a80a200e2c58698bBen Murdoch                case UPDATE_BOOKMARK_THUMBNAIL:
24242694e23a55d5ca526fc29534a80a200e2c58698bBen Murdoch                    WebView view = (WebView) msg.obj;
24252694e23a55d5ca526fc29534a80a200e2c58698bBen Murdoch                    if (view != null) {
24262694e23a55d5ca526fc29534a80a200e2c58698bBen Murdoch                        updateScreenshot(view);
24272694e23a55d5ca526fc29534a80a200e2c58698bBen Murdoch                    }
24282694e23a55d5ca526fc29534a80a200e2c58698bBen Murdoch                    break;
24290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
24300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
24310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    };
24320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
243396afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins    /**
243496afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins     * Share a page, providing the title, url, favicon, and a screenshot.  Uses
243596afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins     * an {@link Intent} to launch the Activity chooser.
243696afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins     * @param c Context used to launch a new Activity.
243796afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins     * @param title Title of the page.  Stored in the Intent with
243896afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins     *          {@link Browser#EXTRA_SHARE_TITLE}
243996afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins     * @param url URL of the page.  Stored in the Intent with
244096afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins     *          {@link Intent#EXTRA_TEXT}
244196afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins     * @param favicon Bitmap of the favicon for the page.  Stored in the Intent
244296afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins     *          with {@link Browser#EXTRA_SHARE_FAVICON}
244396afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins     * @param screenshot Bitmap of a screenshot of the page.  Stored in the
244496afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins     *          Intent with {@link Browser#EXTRA_SHARE_SCREENSHOT}
244596afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins     */
244696afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins    public static final void sharePage(Context c, String title, String url,
244796afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins            Bitmap favicon, Bitmap screenshot) {
244896afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins        Intent send = new Intent(Intent.ACTION_SEND);
244996afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins        send.setType("text/plain");
245096afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins        send.putExtra(Intent.EXTRA_TEXT, url);
245196afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins        send.putExtra(Browser.EXTRA_SHARE_TITLE, title);
245296afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins        send.putExtra(Browser.EXTRA_SHARE_FAVICON, favicon);
245396afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins        send.putExtra(Browser.EXTRA_SHARE_SCREENSHOT, screenshot);
245496afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins        try {
245596afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins            c.startActivity(Intent.createChooser(send, c.getString(
245696afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                    R.string.choosertitle_sharevia)));
245796afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins        } catch(android.content.ActivityNotFoundException ex) {
245896afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins            // if no app handles it, do nothing
245996afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins        }
246096afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins    }
246196afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins
246289c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins    private void updateScreenshot(WebView view) {
246389c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins        // If this is a bookmarked site, add a screenshot to the database.
246489c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins        // FIXME: When should we update?  Every time?
246589c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins        // FIXME: Would like to make sure there is actually something to
246689c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins        // draw, but the API for that (WebViewCore.pictureReady()) is not
246789c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins        // currently accessible here.
2468aac7aa6fcfcb519755987ec126be066323f589c8Ben Murdoch
24693918d4443ff38ef1870e02aa51a8b29f8352bb1aPatrick Scott        ContentResolver cr = getContentResolver();
24703918d4443ff38ef1870e02aa51a8b29f8352bb1aPatrick Scott        final Cursor c = BrowserBookmarksAdapter.queryBookmarksForUrl(
2471aac7aa6fcfcb519755987ec126be066323f589c8Ben Murdoch                cr, view.getOriginalUrl(), view.getUrl(), true);
24723918d4443ff38ef1870e02aa51a8b29f8352bb1aPatrick Scott        if (c != null) {
247389c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins            boolean succeed = c.moveToFirst();
247489c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins            ContentValues values = null;
247589c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins            while (succeed) {
247689c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins                if (values == null) {
247789c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins                    final ByteArrayOutputStream os
247889c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins                            = new ByteArrayOutputStream();
2479dcc2b6f08dd5677bc6ba761a9ba6f1c655113051Ben Murdoch                    Bitmap bm = createScreenshot(view);
24804580057e772b60433272af5cd691825748892693Leon Scroggins                    if (bm == null) {
24814580057e772b60433272af5cd691825748892693Leon Scroggins                        c.close();
24824580057e772b60433272af5cd691825748892693Leon Scroggins                        return;
24834580057e772b60433272af5cd691825748892693Leon Scroggins                    }
248489c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins                    bm.compress(Bitmap.CompressFormat.PNG, 100, os);
248589c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins                    values = new ContentValues();
248689c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins                    values.put(Browser.BookmarkColumns.THUMBNAIL,
248789c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins                            os.toByteArray());
248889c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins                }
248989c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins                cr.update(ContentUris.withAppendedId(Browser.BOOKMARKS_URI,
249089c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins                        c.getInt(0)), values, null, null);
249189c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins                succeed = c.moveToNext();
249289c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins            }
249389c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins            c.close();
249489c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins        }
249589c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins    }
249689c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins
249706ec5f2d8735d1ba17b779deb0f8da032e0a62eaLeon Scroggins    /**
2498f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins     * Values for the size of the thumbnail created when taking a screenshot.
2499f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins     * Lazily initialized.  Instead of using these directly, use
2500f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins     * getDesiredThumbnailWidth() or getDesiredThumbnailHeight().
250106ec5f2d8735d1ba17b779deb0f8da032e0a62eaLeon Scroggins     */
2502f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins    private static int THUMBNAIL_WIDTH = 0;
2503f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins    private static int THUMBNAIL_HEIGHT = 0;
2504f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins
2505f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins    /**
2506f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins     * Return the desired width for thumbnail screenshots, which are stored in
2507f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins     * the database, and used on the bookmarks screen.
2508f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins     * @param context Context for finding out the density of the screen.
2509f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins     * @return int desired width for thumbnail screenshot.
2510f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins     */
2511f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins    /* package */ static int getDesiredThumbnailWidth(Context context) {
2512f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins        if (THUMBNAIL_WIDTH == 0) {
2513f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins            float density = context.getResources().getDisplayMetrics().density;
2514f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins            THUMBNAIL_WIDTH = (int) (90 * density);
2515f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins            THUMBNAIL_HEIGHT = (int) (80 * density);
2516f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins        }
2517f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins        return THUMBNAIL_WIDTH;
2518f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins    }
2519f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins
2520f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins    /**
2521f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins     * Return the desired height for thumbnail screenshots, which are stored in
2522f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins     * the database, and used on the bookmarks screen.
2523f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins     * @param context Context for finding out the density of the screen.
2524f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins     * @return int desired height for thumbnail screenshot.
2525f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins     */
2526f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins    /* package */ static int getDesiredThumbnailHeight(Context context) {
2527f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins        // To ensure that they are both initialized.
2528f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins        getDesiredThumbnailWidth(context);
2529f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins        return THUMBNAIL_HEIGHT;
2530f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins    }
253106ec5f2d8735d1ba17b779deb0f8da032e0a62eaLeon Scroggins
2532dcc2b6f08dd5677bc6ba761a9ba6f1c655113051Ben Murdoch    private Bitmap createScreenshot(WebView view) {
2533dcc2b6f08dd5677bc6ba761a9ba6f1c655113051Ben Murdoch        Picture thumbnail = view.capturePicture();
25344580057e772b60433272af5cd691825748892693Leon Scroggins        if (thumbnail == null) {
25354580057e772b60433272af5cd691825748892693Leon Scroggins            return null;
25364580057e772b60433272af5cd691825748892693Leon Scroggins        }
2537f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins        Bitmap bm = Bitmap.createBitmap(getDesiredThumbnailWidth(this),
2538f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins                getDesiredThumbnailHeight(this), Bitmap.Config.ARGB_4444);
2539dcc2b6f08dd5677bc6ba761a9ba6f1c655113051Ben Murdoch        Canvas canvas = new Canvas(bm);
2540dcc2b6f08dd5677bc6ba761a9ba6f1c655113051Ben Murdoch        // May need to tweak these values to determine what is the
2541dcc2b6f08dd5677bc6ba761a9ba6f1c655113051Ben Murdoch        // best scale factor
25422694e23a55d5ca526fc29534a80a200e2c58698bBen Murdoch        int thumbnailWidth = thumbnail.getWidth();
2543ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch        int thumbnailHeight = thumbnail.getHeight();
2544ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch        float scaleFactorX = 1.0f;
2545ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch        float scaleFactorY = 1.0f;
25462694e23a55d5ca526fc29534a80a200e2c58698bBen Murdoch        if (thumbnailWidth > 0) {
2547ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch            scaleFactorX = (float) getDesiredThumbnailWidth(this) /
25482694e23a55d5ca526fc29534a80a200e2c58698bBen Murdoch                    (float)thumbnailWidth;
2549ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch        } else {
2550ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch            return null;
255106ec5f2d8735d1ba17b779deb0f8da032e0a62eaLeon Scroggins        }
2552ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch
2553ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch        if (view.getWidth() > view.getHeight() &&
2554ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch                thumbnailHeight < view.getHeight() && thumbnailHeight > 0) {
2555ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch            // If the device is in landscape and the page is shorter
2556ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch            // than the height of the view, stretch the thumbnail to fill the
2557ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch            // space.
2558ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch            scaleFactorY = (float) getDesiredThumbnailHeight(this) /
2559ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch                    (float)thumbnailHeight;
2560ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch        } else {
2561ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch            // In the portrait case, this looks nice.
2562ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch            scaleFactorY = scaleFactorX;
2563ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch        }
2564ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch
2565ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch        canvas.scale(scaleFactorX, scaleFactorY);
2566ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch
2567dcc2b6f08dd5677bc6ba761a9ba6f1c655113051Ben Murdoch        thumbnail.draw(canvas);
2568dcc2b6f08dd5677bc6ba761a9ba6f1c655113051Ben Murdoch        return bm;
2569dcc2b6f08dd5677bc6ba761a9ba6f1c655113051Ben Murdoch    }
2570dcc2b6f08dd5677bc6ba761a9ba6f1c655113051Ben Murdoch
25710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // -------------------------------------------------------------------------
257222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // Helper function for WebViewClient.
25730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    //-------------------------------------------------------------------------
25740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
25750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Use in overrideUrlLoading
25760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /* package */ final static String SCHEME_WTAI = "wtai://wp/";
25770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /* package */ final static String SCHEME_WTAI_MC = "wtai://wp/mc;";
25780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /* package */ final static String SCHEME_WTAI_SD = "wtai://wp/sd;";
25790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /* package */ final static String SCHEME_WTAI_AP = "wtai://wp/ap;";
25800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
258122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void onPageStarted(WebView view, String url, Bitmap favicon) {
258222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // when BrowserActivity just starts, onPageStarted may be called before
258322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // onResume as it is triggered from onCreate. Call resumeWebViewTimers
258422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // to start the timer. As we won't switch tabs while an activity is in
258522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // pause state, we can ensure calling resume and pause in pair.
258622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mActivityInPause) resumeWebViewTimers();
258722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
258822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        resetLockIcon(url);
258922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        setUrlTitle(url, null);
259022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        setFavicon(favicon);
25918cf8f682e90f004d4b8028d2f5b74f72c0cf4e19Leon Scroggins        // Keep this initial progress in sync with initialProgressValue (* 100)
25928cf8f682e90f004d4b8028d2f5b74f72c0cf4e19Leon Scroggins        // in ProgressTracker.cpp
25938cf8f682e90f004d4b8028d2f5b74f72c0cf4e19Leon Scroggins        // Show some progress so that the user knows the page is beginning to
25948cf8f682e90f004d4b8028d2f5b74f72c0cf4e19Leon Scroggins        // load
25958cf8f682e90f004d4b8028d2f5b74f72c0cf4e19Leon Scroggins        onProgressChanged(view, 10);
259622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mDidStopLoad = false;
259722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (!mIsNetworkUp) createAndShowNetworkDialog();
25980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
259922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mSettings.isTracing()) {
260022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            String host;
260122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            try {
260222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                WebAddress uri = new WebAddress(url);
260322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                host = uri.mHost;
260422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            } catch (android.net.ParseException ex) {
260522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                host = "browser";
260622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
260722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            host = host.replace('.', '_');
260822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            host += ".trace";
260922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mInTrace = true;
261022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            Debug.startMethodTracing(host, 20 * 1024 * 1024);
261115525d48024d325c8a52766d8ca727191251a8d4Patrick Scott        }
261215525d48024d325c8a52766d8ca727191251a8d4Patrick Scott
261322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Performance probe
261422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (false) {
261522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mStart = SystemClock.uptimeMillis();
261622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mProcessStart = Process.getElapsedCpuTime();
261722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            long[] sysCpu = new long[7];
261822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (Process.readProcFile("/proc/stat", SYSTEM_CPU_FORMAT, null,
261922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    sysCpu, null)) {
262022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                mUserStart = sysCpu[0] + sysCpu[1];
262122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                mSystemStart = sysCpu[2];
262222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                mIdleStart = sysCpu[3];
262322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                mIrqStart = sysCpu[4] + sysCpu[5] + sysCpu[6];
262422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
262522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mUiStart = SystemClock.currentThreadTimeMillis();
26260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
26270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
26280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
262922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void onPageFinished(WebView view, String url) {
263022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Reset the title and icon in case we stopped a provisional load.
263122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        resetTitleAndIcon(view);
263222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Update the lock icon image only once we are done loading
263322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        updateLockIconToLatest();
263422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // pause the WebView timer and release the wake lock if it is finished
263522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // while BrowserActivity is in pause state.
263622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mActivityInPause && pauseWebViewTimers()) {
263722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (mWakeLock.isHeld()) {
263822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                mHandler.removeMessages(RELEASE_WAKELOCK);
263922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                mWakeLock.release();
264022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
264122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
264222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
264322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Performance probe
264422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (false) {
264522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            long[] sysCpu = new long[7];
264622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (Process.readProcFile("/proc/stat", SYSTEM_CPU_FORMAT, null,
264722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    sysCpu, null)) {
264822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                String uiInfo = "UI thread used "
264922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        + (SystemClock.currentThreadTimeMillis() - mUiStart)
265022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        + " ms";
265122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                if (LOGD_ENABLED) {
265222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    Log.d(LOGTAG, uiInfo);
265322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                }
265422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                //The string that gets written to the log
265522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                String performanceString = "It took total "
265622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        + (SystemClock.uptimeMillis() - mStart)
265722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        + " ms clock time to load the page."
265822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        + "\nbrowser process used "
265922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        + (Process.getElapsedCpuTime() - mProcessStart)
266022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        + " ms, user processes used "
266122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        + (sysCpu[0] + sysCpu[1] - mUserStart) * 10
266222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        + " ms, kernel used "
266322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        + (sysCpu[2] - mSystemStart) * 10
266422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        + " ms, idle took " + (sysCpu[3] - mIdleStart) * 10
266522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        + " ms and irq took "
266622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        + (sysCpu[4] + sysCpu[5] + sysCpu[6] - mIrqStart)
266722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        * 10 + " ms, " + uiInfo;
266822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                if (LOGD_ENABLED) {
266922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    Log.d(LOGTAG, performanceString + "\nWebpage: " + url);
26700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
267122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                if (url != null) {
267222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    // strip the url to maintain consistency
267322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    String newUrl = new String(url);
267422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    if (newUrl.startsWith("http://www.")) {
267522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        newUrl = newUrl.substring(11);
267622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    } else if (newUrl.startsWith("http://")) {
267722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        newUrl = newUrl.substring(7);
267822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    } else if (newUrl.startsWith("https://www.")) {
267922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        newUrl = newUrl.substring(12);
268022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    } else if (newUrl.startsWith("https://")) {
268122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        newUrl = newUrl.substring(8);
26820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
268331a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort                    if (LOGD_ENABLED) {
268422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        Log.d(LOGTAG, newUrl + " loaded");
26850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
26860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
26870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
268822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         }
26890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
269022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mInTrace) {
269122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mInTrace = false;
269222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            Debug.stopMethodTracing();
26930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
269422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
26950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
269622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    boolean shouldOverrideUrlLoading(WebView view, String url) {
269722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (url.startsWith(SCHEME_WTAI)) {
269822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // wtai://wp/mc;number
269922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // number=string(phone-number)
270022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (url.startsWith(SCHEME_WTAI_MC)) {
270122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                Intent intent = new Intent(Intent.ACTION_VIEW,
270222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        Uri.parse(WebView.SCHEME_TEL +
270322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        url.substring(SCHEME_WTAI_MC.length())));
270422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                startActivity(intent);
270522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                return true;
27060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
270722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // wtai://wp/sd;dtmf
270822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // dtmf=string(dialstring)
270922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (url.startsWith(SCHEME_WTAI_SD)) {
271022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                // TODO: only send when there is active voice connection
27119918943559193e3e047a1c18442e2cdb0fe22b15Dianne Hackborn                return false;
27129918943559193e3e047a1c18442e2cdb0fe22b15Dianne Hackborn            }
271322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // wtai://wp/ap;number;name
271422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // number=string(phone-number)
271522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // name=string
271622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (url.startsWith(SCHEME_WTAI_AP)) {
271722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                // TODO
27180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                return false;
27190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
27200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
27210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
272222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // The "about:" schemes are internal to the browser; don't want these to
272322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // be dispatched to other apps.
272422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (url.startsWith("about:")) {
272522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            return false;
27260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
27270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
272822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        Intent intent;
272922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // perform generic parsing of the URI to turn it into an Intent.
273022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        try {
273122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            intent = Intent.parseUri(url, Intent.URI_INTENT_SCHEME);
273222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        } catch (URISyntaxException ex) {
273322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            Log.w("Browser", "Bad URI " + url + ": " + ex.getMessage());
273422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            return false;
27350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
27360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
273722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // check whether the intent can be resolved. If not, we will see
273822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // whether we can download it from the Market.
273922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (getPackageManager().resolveActivity(intent, 0) == null) {
274022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            String packagename = intent.getPackage();
274122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (packagename != null) {
274222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                intent = new Intent(Intent.ACTION_VIEW, Uri
274322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        .parse("market://search?q=pname:" + packagename));
274422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                intent.addCategory(Intent.CATEGORY_BROWSABLE);
274522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                startActivity(intent);
274622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                return true;
27470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } else {
27480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                return false;
27490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
27500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
27510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
275222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // sanitize the Intent, ensuring web pages can not bypass browser
275322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // security (only access to BROWSABLE activities).
275422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        intent.addCategory(Intent.CATEGORY_BROWSABLE);
275522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        intent.setComponent(null);
275622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        try {
275722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (startActivityIfNeeded(intent, -1)) {
27580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                return true;
27590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
276022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        } catch (ActivityNotFoundException ex) {
276122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // ignore the error. If no application can handle the URL,
276222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // eg about:blank, assume the browser can handle it.
276322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
27640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
276522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mMenuIsDown) {
276622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            openTab(url);
276722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            closeOptionsMenu();
27680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return true;
27690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
277022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return false;
277122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
27720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
277322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // -------------------------------------------------------------------------
277422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // Helper function for WebChromeClient
277522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // -------------------------------------------------------------------------
27760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
277722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void onProgressChanged(WebView view, int newProgress) {
277822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mTitleBar.setProgress(newProgress);
277922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mFakeTitleBar.setProgress(newProgress);
278022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
278122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (newProgress == 100) {
278222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // onProgressChanged() may continue to be called after the main
278322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // frame has finished loading, as any remaining sub frames continue
278422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // to load. We'll only get called once though with newProgress as
278522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // 100 when everything is loaded. (onPageFinished is called once
278622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // when the main frame completes loading regardless of the state of
278722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // any sub frames so calls to onProgressChanges may continue after
278822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // onPageFinished has executed)
278922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (mInLoad) {
279022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                mInLoad = false;
2791a27ff19e24cb1c9fef5624dbc4554548349b5b31Leon Scroggins                updateInLoadMenuItems();
279222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                // If the options menu is open, leave the title bar
279322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                if (!mOptionsMenuOpen || !mIconView) {
279422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    hideFakeTitleBar();
27950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
27960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
279722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        } else if (!mInLoad) {
279822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // onPageFinished may have already been called but a subframe is
279922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // still loading and updating the progress. Reset mInLoad and update
280022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // the menu items.
280122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mInLoad = true;
280222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            updateInLoadMenuItems();
280322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (!mOptionsMenuOpen || mIconView) {
280422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                // This page has begun to load, so show the title bar
280522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                showFakeTitleBar();
28063918d4443ff38ef1870e02aa51a8b29f8352bb1aPatrick Scott            }
28070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
280822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
2809092dd5d22d7f2ee0efcc68bd6e5a3afd1ea98953Ben Murdoch
281022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void onShowCustomView(View view, WebChromeClient.CustomViewCallback callback) {
28118ff57db0a8dc8eb659fbcdcd4a856208609e6070Derek Sollenberger        // if a view already exists then immediately terminate the new one
28128ff57db0a8dc8eb659fbcdcd4a856208609e6070Derek Sollenberger        if (mCustomView != null) {
28138ff57db0a8dc8eb659fbcdcd4a856208609e6070Derek Sollenberger            callback.onCustomViewHidden();
281422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            return;
28158ff57db0a8dc8eb659fbcdcd4a856208609e6070Derek Sollenberger        }
28162bc69918d97a767a02132090e58718077381ba1aSteve Block
281722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Add the custom view to its container.
281822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mCustomViewContainer.addView(view, COVER_SCREEN_GRAVITY_CENTER);
281922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mCustomView = view;
282022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mCustomViewCallback = callback;
282122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Save the menu state and set it to empty while the custom
282222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // view is showing.
282322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mOldMenuState = mMenuState;
282422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mMenuState = EMPTY_MENU;
282522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Hide the content view.
282622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mContentView.setVisibility(View.GONE);
282722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Finally show the custom view container.
2828163ab74e2f85b53a1a374c49677073fb64d35f28Andrei Popescu        setStatusBarVisibility(false);
282922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mCustomViewContainer.setVisibility(View.VISIBLE);
283022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mCustomViewContainer.bringToFront();
283122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
283222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
283322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void onHideCustomView() {
283422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mCustomView == null)
283522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            return;
28362bc69918d97a767a02132090e58718077381ba1aSteve Block
283722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Hide the custom view.
283822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mCustomView.setVisibility(View.GONE);
283922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Remove the custom view from its container.
284022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mCustomViewContainer.removeView(mCustomView);
284122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mCustomView = null;
284222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Reset the old menu state.
284322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mMenuState = mOldMenuState;
284422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mOldMenuState = EMPTY_MENU;
284522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mCustomViewContainer.setVisibility(View.GONE);
284622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mCustomViewCallback.onCustomViewHidden();
284722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Show the content view.
2848163ab74e2f85b53a1a374c49677073fb64d35f28Andrei Popescu        setStatusBarVisibility(true);
284922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mContentView.setVisibility(View.VISIBLE);
285022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
2851540035dfd1347c78eeec10ec0847e18fcc50ef36Andrei Popescu
285222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    Bitmap getDefaultVideoPoster() {
285322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mDefaultVideoPoster == null) {
285422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mDefaultVideoPoster = BitmapFactory.decodeResource(
285522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    getResources(), R.drawable.default_video_poster);
2856540035dfd1347c78eeec10ec0847e18fcc50ef36Andrei Popescu        }
285722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return mDefaultVideoPoster;
285822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
2859540035dfd1347c78eeec10ec0847e18fcc50ef36Andrei Popescu
286022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    View getVideoLoadingProgressView() {
286122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mVideoProgressView == null) {
286222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            LayoutInflater inflater = LayoutInflater.from(BrowserActivity.this);
286322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mVideoProgressView = inflater.inflate(
286422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    R.layout.video_loading_progress, null);
2865540035dfd1347c78eeec10ec0847e18fcc50ef36Andrei Popescu        }
286622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return mVideoProgressView;
286722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
28680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
28698d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins    /*
28708d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins     * The Object used to inform the WebView of the file to upload.
28718d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins     */
28728d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins    private ValueCallback<Uri> mUploadMessage;
28738d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins
287422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void openFileChooser(ValueCallback<Uri> uploadMsg) {
287522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mUploadMessage != null) return;
287622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mUploadMessage = uploadMsg;
287722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        Intent i = new Intent(Intent.ACTION_GET_CONTENT);
287822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        i.addCategory(Intent.CATEGORY_OPENABLE);
287922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        i.setType("*/*");
288022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        BrowserActivity.this.startActivityForResult(Intent.createChooser(i,
288122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                getString(R.string.choose_upload)), FILE_SELECTED);
288222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
288322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
288422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // -------------------------------------------------------------------------
288522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // Implement functions for DownloadListener
288622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // -------------------------------------------------------------------------
288722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
28880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
28890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Notify the host application a download should be done, or that
28900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * the data should be streamed if a streaming viewer is available.
28910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param url The full url to the content that should be downloaded
28920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param contentDisposition Content-disposition http header, if
28930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *                           present.
28940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param mimetype The mimetype of the content reported by the server
28950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param contentLength The file size reported by the server
28960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
28970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public void onDownloadStart(String url, String userAgent,
28980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            String contentDisposition, String mimetype, long contentLength) {
28990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // if we're dealing wih A/V content that's not explicitly marked
29000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        //     for download, check if it's streamable.
29010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (contentDisposition == null
2902e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                || !contentDisposition.regionMatches(
2903e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                        true, 0, "attachment", 0, 10)) {
29040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // query the package manager to see if there's a registered handler
29050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            //     that matches.
29060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Intent intent = new Intent(Intent.ACTION_VIEW);
29070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            intent.setDataAndType(Uri.parse(url), mimetype);
2908e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott            ResolveInfo info = getPackageManager().resolveActivity(intent,
2909e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                    PackageManager.MATCH_DEFAULT_ONLY);
2910e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott            if (info != null) {
2911e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                ComponentName myName = getComponentName();
2912e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                // If we resolved to ourselves, we don't want to attempt to
2913e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                // load the url only to try and download it again.
2914e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                if (!myName.getPackageName().equals(
2915e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                        info.activityInfo.packageName)
2916e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                        || !myName.getClassName().equals(
2917e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                                info.activityInfo.name)) {
2918e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                    // someone (other than us) knows how to handle this mime
2919e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                    // type with this scheme, don't download.
2920e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                    try {
2921e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                        startActivity(intent);
2922e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                        return;
2923e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                    } catch (ActivityNotFoundException ex) {
2924e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                        if (LOGD_ENABLED) {
2925e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                            Log.d(LOGTAG, "activity not found for " + mimetype
2926e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                                    + " over " + Uri.parse(url).getScheme(),
2927e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                                    ex);
2928e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                        }
2929e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                        // Best behavior is to fall back to a download in this
2930e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                        // case
29310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
29320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
29330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
29340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
29350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        onDownloadStartNoStream(url, userAgent, contentDisposition, mimetype, contentLength);
29360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
29370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
29380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
29390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Notify the host application a download should be done, even if there
29400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * is a streaming viewer available for thise type.
29410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param url The full url to the content that should be downloaded
29420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param contentDisposition Content-disposition http header, if
29430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *                           present.
29440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param mimetype The mimetype of the content reported by the server
29450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param contentLength The file size reported by the server
29460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
29470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /*package */ void onDownloadStartNoStream(String url, String userAgent,
29480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            String contentDisposition, String mimetype, long contentLength) {
29490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
29500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String filename = URLUtil.guessFileName(url,
29510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                contentDisposition, mimetype);
29520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
29530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Check to see if we have an SDCard
29540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String status = Environment.getExternalStorageState();
29550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (!status.equals(Environment.MEDIA_MOUNTED)) {
29560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            int title;
29570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            String msg;
29580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
29590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Check to see if the SDCard is busy, same as the music app
29600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (status.equals(Environment.MEDIA_SHARED)) {
29610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                msg = getString(R.string.download_sdcard_busy_dlg_msg);
29620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                title = R.string.download_sdcard_busy_dlg_title;
29630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } else {
29640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                msg = getString(R.string.download_no_sdcard_dlg_msg, filename);
29650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                title = R.string.download_no_sdcard_dlg_title;
29660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
29670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
29680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            new AlertDialog.Builder(this)
29690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setTitle(title)
29700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setIcon(android.R.drawable.ic_dialog_alert)
29710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setMessage(msg)
29720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setPositiveButton(R.string.ok, null)
29730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .show();
29740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
29750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
29760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
29770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // java.net.URI is a lot stricter than KURL so we have to undo
29780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // KURL's percent-encoding and redo the encoding using java.net.URI.
29790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        URI uri = null;
29800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        try {
29810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Undo the percent-encoding that KURL may have done.
29820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            String newUrl = new String(URLUtil.decode(url.getBytes()));
29830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Parse the url into pieces
29840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            WebAddress w = new WebAddress(newUrl);
29850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            String frag = null;
29860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            String query = null;
29870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            String path = w.mPath;
29880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Break the path into path, query, and fragment
29890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (path.length() > 0) {
29900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // Strip the fragment
29910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                int idx = path.lastIndexOf('#');
29920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (idx != -1) {
29930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    frag = path.substring(idx + 1);
29940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    path = path.substring(0, idx);
29950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
29960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                idx = path.lastIndexOf('?');
29970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (idx != -1) {
29980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    query = path.substring(idx + 1);
29990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    path = path.substring(0, idx);
30000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
30010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
30020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            uri = new URI(w.mScheme, w.mAuthInfo, w.mHost, w.mPort, path,
30030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    query, frag);
30040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } catch (Exception e) {
30050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Log.e(LOGTAG, "Could not parse url for download: " + url, e);
30060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
30070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
30080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
30090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // XXX: Have to use the old url since the cookies were stored using the
30100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // old percent-encoded url.
30110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String cookies = CookieManager.getInstance().getCookie(url);
30120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
30130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        ContentValues values = new ContentValues();
30141e5bad97ca8fb9b12501f4f747941d02f03e1362Jean-Baptiste Queru        values.put(Downloads.Impl.COLUMN_URI, uri.toString());
30151e5bad97ca8fb9b12501f4f747941d02f03e1362Jean-Baptiste Queru        values.put(Downloads.Impl.COLUMN_COOKIE_DATA, cookies);
30161e5bad97ca8fb9b12501f4f747941d02f03e1362Jean-Baptiste Queru        values.put(Downloads.Impl.COLUMN_USER_AGENT, userAgent);
30171e5bad97ca8fb9b12501f4f747941d02f03e1362Jean-Baptiste Queru        values.put(Downloads.Impl.COLUMN_NOTIFICATION_PACKAGE,
30180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                getPackageName());
30191e5bad97ca8fb9b12501f4f747941d02f03e1362Jean-Baptiste Queru        values.put(Downloads.Impl.COLUMN_NOTIFICATION_CLASS,
30200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                BrowserDownloadPage.class.getCanonicalName());
30211e5bad97ca8fb9b12501f4f747941d02f03e1362Jean-Baptiste Queru        values.put(Downloads.Impl.COLUMN_VISIBILITY,
30221e5bad97ca8fb9b12501f4f747941d02f03e1362Jean-Baptiste Queru                Downloads.Impl.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
30231e5bad97ca8fb9b12501f4f747941d02f03e1362Jean-Baptiste Queru        values.put(Downloads.Impl.COLUMN_MIME_TYPE, mimetype);
30241e5bad97ca8fb9b12501f4f747941d02f03e1362Jean-Baptiste Queru        values.put(Downloads.Impl.COLUMN_FILE_NAME_HINT, filename);
30251e5bad97ca8fb9b12501f4f747941d02f03e1362Jean-Baptiste Queru        values.put(Downloads.Impl.COLUMN_DESCRIPTION, uri.getHost());
30260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (contentLength > 0) {
30271e5bad97ca8fb9b12501f4f747941d02f03e1362Jean-Baptiste Queru            values.put(Downloads.Impl.COLUMN_TOTAL_BYTES, contentLength);
30280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
30290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mimetype == null) {
30300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // We must have long pressed on a link or image to download it. We
30310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // are not sure of the mimetype in this case, so do a head request
30320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            new FetchUrlMimeType(this).execute(values);
30330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
30340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            final Uri contentUri =
30351e5bad97ca8fb9b12501f4f747941d02f03e1362Jean-Baptiste Queru                    getContentResolver().insert(Downloads.Impl.CONTENT_URI, values);
30360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
30370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
30380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
30390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
304022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // -------------------------------------------------------------------------
304122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
30420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
30430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Resets the lock icon. This method is called when we start a new load and
30440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * know the url to be loaded.
30450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
30460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void resetLockIcon(String url) {
30470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Save the lock-icon state (we revert to it if the load gets cancelled)
304822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mTabControl.getCurrentTab().resetLockIcon(url);
30490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        updateLockIconImage(LOCK_ICON_UNSECURE);
30500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
30510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
30520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
30533bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     * Update the lock icon to correspond to our latest state.
30543bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     */
305522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private void updateLockIconToLatest() {
305622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        updateLockIconImage(mTabControl.getCurrentTab().getLockIconType());
30573bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    }
30583bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins
30593bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    /**
30600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Updates the lock-icon image in the title-bar.
30610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
30620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void updateLockIconImage(int lockIconType) {
30630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        Drawable d = null;
30640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (lockIconType == LOCK_ICON_SECURE) {
30650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            d = mSecLockIcon;
30660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else if (lockIconType == LOCK_ICON_MIXED) {
30670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            d = mMixLockIcon;
30680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
306968579393973f745fc65a2781061af9bb8f2d7020Leon Scroggins        mTitleBar.setLock(d);
3070fe87bd3a3897e4bad65bb3d284659ae2f4e57570Leon Scroggins        mFakeTitleBar.setLock(d);
30710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
30720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
30730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
30740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Displays a page-info dialog.
30750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param tab The tab to show info about
30760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param fromShowSSLCertificateOnError The flag that indicates whether
30770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * this dialog was opened from the SSL-certificate-on-error dialog or
30780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * not. This is important, since we need to know whether to return to
30790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * the parent dialog or simply dismiss.
30800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
308122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private void showPageInfo(final Tab tab,
30820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                              final boolean fromShowSSLCertificateOnError) {
30830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final LayoutInflater factory = LayoutInflater
30840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .from(this);
30850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
30860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final View pageInfoView = factory.inflate(R.layout.page_info, null);
30870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
30880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final WebView view = tab.getWebView();
30890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
30900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String url = null;
30910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String title = null;
30920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
30930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (view == null) {
30940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            url = tab.getUrl();
30950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            title = tab.getTitle();
30960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else if (view == mTabControl.getCurrentWebView()) {
30970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project             // Use the cached title and url if this is the current WebView
30980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            url = mUrl;
30990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            title = mTitle;
31000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
31010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            url = view.getUrl();
31020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            title = view.getTitle();
31030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
31040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
31050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (url == null) {
31060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            url = "";
31070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
31080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (title == null) {
31090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            title = "";
31100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
31110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
31120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        ((TextView) pageInfoView.findViewById(R.id.address)).setText(url);
31130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        ((TextView) pageInfoView.findViewById(R.id.title)).setText(title);
31140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
31150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mPageInfoView = tab;
3116c7b92f811dfa3572578ddc6714c98a03936d9ce5Leon Scroggins        mPageInfoFromShowSSLCertificateOnError = fromShowSSLCertificateOnError;
31170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
31180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        AlertDialog.Builder alertDialogBuilder =
31190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            new AlertDialog.Builder(this)
31200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            .setTitle(R.string.page_info).setIcon(android.R.drawable.ic_dialog_info)
31210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            .setView(pageInfoView)
31220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            .setPositiveButton(
31230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                R.string.ok,
31240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                new DialogInterface.OnClickListener() {
31250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    public void onClick(DialogInterface dialog,
31260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        int whichButton) {
31270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        mPageInfoDialog = null;
31280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        mPageInfoView = null;
31290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
31300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        // if we came here from the SSL error dialog
31310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        if (fromShowSSLCertificateOnError) {
31320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            // go back to the SSL error dialog
31330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            showSSLCertificateOnError(
31340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorView,
31350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorHandler,
31360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorError);
31370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }
31380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
31390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                })
31400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            .setOnCancelListener(
31410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                new DialogInterface.OnCancelListener() {
31420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    public void onCancel(DialogInterface dialog) {
31430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        mPageInfoDialog = null;
31440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        mPageInfoView = null;
31450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
31460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        // if we came here from the SSL error dialog
31470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        if (fromShowSSLCertificateOnError) {
31480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            // go back to the SSL error dialog
31490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            showSSLCertificateOnError(
31500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorView,
31510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorHandler,
31520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorError);
31530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }
31540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
31550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                });
31560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
31570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // if we have a main top-level page SSL certificate set or a certificate
31580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // error
31590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (fromShowSSLCertificateOnError ||
31600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                (view != null && view.getCertificate() != null)) {
31610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // add a 'View Certificate' button
31620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            alertDialogBuilder.setNeutralButton(
31630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                R.string.view_certificate,
31640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                new DialogInterface.OnClickListener() {
31650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    public void onClick(DialogInterface dialog,
31660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        int whichButton) {
31670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        mPageInfoDialog = null;
31680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        mPageInfoView = null;
31690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
31700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        // if we came here from the SSL error dialog
31710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        if (fromShowSSLCertificateOnError) {
31720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            // go back to the SSL error dialog
31730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            showSSLCertificateOnError(
31740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorView,
31750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorHandler,
31760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorError);
31770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        } else {
31780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            // otherwise, display the top-most certificate from
31790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            // the chain
31800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            if (view.getCertificate() != null) {
31810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                showSSLCertificate(tab);
31820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            }
31830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }
31840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
31850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                });
31860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
31870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
31880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mPageInfoDialog = alertDialogBuilder.show();
31890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
31900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
31910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project       /**
31920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Displays the main top-level page SSL certificate dialog
31930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * (accessible from the Page-Info dialog).
31940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param tab The tab to show certificate for.
31950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
319622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private void showSSLCertificate(final Tab tab) {
31970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final View certificateView =
31980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                inflateCertificateView(tab.getWebView().getCertificate());
31990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (certificateView == null) {
32000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
32010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
32020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
32030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        LayoutInflater factory = LayoutInflater.from(this);
32040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
32050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final LinearLayout placeholder =
32060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                (LinearLayout)certificateView.findViewById(R.id.placeholder);
32070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
32080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        LinearLayout ll = (LinearLayout) factory.inflate(
32090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            R.layout.ssl_success, placeholder);
32100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        ((TextView)ll.findViewById(R.id.success))
32110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            .setText(R.string.ssl_certificate_is_valid);
32120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
32130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mSSLCertificateView = tab;
32140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mSSLCertificateDialog =
32150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            new AlertDialog.Builder(this)
32160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setTitle(R.string.ssl_certificate).setIcon(
32170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    R.drawable.ic_dialog_browser_certificate_secure)
32180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setView(certificateView)
32190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setPositiveButton(R.string.ok,
32200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new DialogInterface.OnClickListener() {
32210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            public void onClick(DialogInterface dialog,
32220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    int whichButton) {
32230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateDialog = null;
32240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateView = null;
32250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
32260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                showPageInfo(tab, false);
32270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            }
32280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        })
32290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setOnCancelListener(
32300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new DialogInterface.OnCancelListener() {
32310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            public void onCancel(DialogInterface dialog) {
32320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateDialog = null;
32330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateView = null;
32340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
32350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                showPageInfo(tab, false);
32360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            }
32370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        })
32380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .show();
32390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
32400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
32410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
32420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Displays the SSL error certificate dialog.
32430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param view The target web-view.
32440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param handler The SSL error handler responsible for cancelling the
32450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * connection that resulted in an SSL error or proceeding per user request.
32460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param error The SSL error object.
32470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
324822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void showSSLCertificateOnError(
32490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final WebView view, final SslErrorHandler handler, final SslError error) {
32500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
32510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final View certificateView =
32520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            inflateCertificateView(error.getCertificate());
32530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (certificateView == null) {
32540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
32550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
32560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
32570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        LayoutInflater factory = LayoutInflater.from(this);
32580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
32590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final LinearLayout placeholder =
32600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                (LinearLayout)certificateView.findViewById(R.id.placeholder);
32610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
32620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (error.hasError(SslError.SSL_UNTRUSTED)) {
32630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            LinearLayout ll = (LinearLayout)factory
32640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .inflate(R.layout.ssl_warning, placeholder);
32650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((TextView)ll.findViewById(R.id.warning))
32660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setText(R.string.ssl_untrusted);
32670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
32680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
32690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (error.hasError(SslError.SSL_IDMISMATCH)) {
32700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            LinearLayout ll = (LinearLayout)factory
32710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .inflate(R.layout.ssl_warning, placeholder);
32720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((TextView)ll.findViewById(R.id.warning))
32730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setText(R.string.ssl_mismatch);
32740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
32750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
32760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (error.hasError(SslError.SSL_EXPIRED)) {
32770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            LinearLayout ll = (LinearLayout)factory
32780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .inflate(R.layout.ssl_warning, placeholder);
32790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((TextView)ll.findViewById(R.id.warning))
32800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setText(R.string.ssl_expired);
32810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
32820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
32830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (error.hasError(SslError.SSL_NOTYETVALID)) {
32840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            LinearLayout ll = (LinearLayout)factory
32850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .inflate(R.layout.ssl_warning, placeholder);
32860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((TextView)ll.findViewById(R.id.warning))
32870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setText(R.string.ssl_not_yet_valid);
32880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
32890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
32900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mSSLCertificateOnErrorHandler = handler;
32910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mSSLCertificateOnErrorView = view;
32920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mSSLCertificateOnErrorError = error;
32930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mSSLCertificateOnErrorDialog =
32940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            new AlertDialog.Builder(this)
32950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setTitle(R.string.ssl_certificate).setIcon(
32960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    R.drawable.ic_dialog_browser_certificate_partially_secure)
32970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setView(certificateView)
32980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setPositiveButton(R.string.ok,
32990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new DialogInterface.OnClickListener() {
33000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            public void onClick(DialogInterface dialog,
33010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    int whichButton) {
33020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorDialog = null;
33030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorView = null;
33040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorHandler = null;
33050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorError = null;
33060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
330722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                view.getWebViewClient().onReceivedSslError(
330822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                                view, handler, error);
33090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            }
33100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        })
33110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                 .setNeutralButton(R.string.page_info_view,
33120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new DialogInterface.OnClickListener() {
33130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            public void onClick(DialogInterface dialog,
33140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    int whichButton) {
33150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorDialog = null;
33160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
33170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                // do not clear the dialog state: we will
33180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                // need to show the dialog again once the
33190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                // user is done exploring the page-info details
33200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
33210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                showPageInfo(mTabControl.getTabFromView(view),
33220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        true);
33230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            }
33240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        })
33250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setOnCancelListener(
33260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new DialogInterface.OnCancelListener() {
33270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            public void onCancel(DialogInterface dialog) {
33280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorDialog = null;
33290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorView = null;
33300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorHandler = null;
33310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorError = null;
33320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
333322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                view.getWebViewClient().onReceivedSslError(
333422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                                view, handler, error);
33350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            }
33360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        })
33370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .show();
33380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
33390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
33400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
33410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Inflates the SSL certificate view (helper method).
33420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param certificate The SSL certificate.
33430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @return The resultant certificate view with issued-to, issued-by,
33440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * issued-on, expires-on, and possibly other fields set.
33450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * If the input certificate is null, returns null.
33460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
33470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private View inflateCertificateView(SslCertificate certificate) {
33480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (certificate == null) {
33490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return null;
33500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
33510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
33520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        LayoutInflater factory = LayoutInflater.from(this);
33530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
33540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        View certificateView = factory.inflate(
33550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            R.layout.ssl_certificate, null);
33560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
33570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // issued to:
33580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        SslCertificate.DName issuedTo = certificate.getIssuedTo();
33590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (issuedTo != null) {
33600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((TextView) certificateView.findViewById(R.id.to_common))
33610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setText(issuedTo.getCName());
33620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((TextView) certificateView.findViewById(R.id.to_org))
33630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setText(issuedTo.getOName());
33640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((TextView) certificateView.findViewById(R.id.to_org_unit))
33650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setText(issuedTo.getUName());
33660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
33670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
33680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // issued by:
33690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        SslCertificate.DName issuedBy = certificate.getIssuedBy();
33700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (issuedBy != null) {
33710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((TextView) certificateView.findViewById(R.id.by_common))
33720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setText(issuedBy.getCName());
33730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((TextView) certificateView.findViewById(R.id.by_org))
33740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setText(issuedBy.getOName());
33750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((TextView) certificateView.findViewById(R.id.by_org_unit))
33760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setText(issuedBy.getUName());
33770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
33780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
33790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // issued on:
33800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String issuedOn = reformatCertificateDate(
33810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            certificate.getValidNotBefore());
33820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        ((TextView) certificateView.findViewById(R.id.issued_on))
33830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            .setText(issuedOn);
33840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
33850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // expires on:
33860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String expiresOn = reformatCertificateDate(
33870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            certificate.getValidNotAfter());
33880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        ((TextView) certificateView.findViewById(R.id.expires_on))
33890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            .setText(expiresOn);
33900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
33910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return certificateView;
33920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
33930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
33940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
33950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Re-formats the certificate date (Date.toString()) string to
33960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * a properly localized date string.
33970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @return Properly localized version of the certificate date string and
33980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * the original certificate date string if fails to localize.
33990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * If the original string is null, returns an empty string "".
34000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
34010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private String reformatCertificateDate(String certificateDate) {
34020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project      String reformattedDate = null;
34030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
34040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project      if (certificateDate != null) {
34050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project          Date date = null;
34060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project          try {
34070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project              date = java.text.DateFormat.getInstance().parse(certificateDate);
34080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project          } catch (ParseException e) {
34090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project              date = null;
34100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project          }
34110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
34120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project          if (date != null) {
34130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project              reformattedDate =
34140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                  DateFormat.getDateFormat(this).format(date);
34150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project          }
34160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project      }
34170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
34180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project      return reformattedDate != null ? reformattedDate :
34190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project          (certificateDate != null ? certificateDate : "");
34200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
34210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
34220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
34230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Displays an http-authentication dialog.
34240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
342522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void showHttpAuthentication(final HttpAuthHandler handler,
34260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            final String host, final String realm, final String title,
34270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            final String name, final String password, int focusId) {
34280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        LayoutInflater factory = LayoutInflater.from(this);
34290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final View v = factory
34300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .inflate(R.layout.http_authentication, null);
34310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (name != null) {
34320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((EditText) v.findViewById(R.id.username_edit)).setText(name);
34330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
34340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (password != null) {
34350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((EditText) v.findViewById(R.id.password_edit)).setText(password);
34360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
34370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
34380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String titleText = title;
34390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (titleText == null) {
34400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            titleText = getText(R.string.sign_in_to).toString().replace(
34410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    "%s1", host).replace("%s2", realm);
34420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
34430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
34440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mHttpAuthHandler = handler;
34450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        AlertDialog dialog = new AlertDialog.Builder(this)
34460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setTitle(titleText)
34470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setIcon(android.R.drawable.ic_dialog_alert)
34480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setView(v)
34490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setPositiveButton(R.string.action,
34500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new DialogInterface.OnClickListener() {
34510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                             public void onClick(DialogInterface dialog,
34520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                     int whichButton) {
34530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                String nm = ((EditText) v
34540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        .findViewById(R.id.username_edit))
34550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        .getText().toString();
34560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                String pw = ((EditText) v
34570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        .findViewById(R.id.password_edit))
34580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        .getText().toString();
34590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                BrowserActivity.this.setHttpAuthUsernamePassword
34600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        (host, realm, nm, pw);
34610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                handler.proceed(nm, pw);
34620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mHttpAuthenticationDialog = null;
34630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mHttpAuthHandler = null;
34640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            }})
34650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setNegativeButton(R.string.cancel,
34660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new DialogInterface.OnClickListener() {
34670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            public void onClick(DialogInterface dialog,
34680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    int whichButton) {
34690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                handler.cancel();
34700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                BrowserActivity.this.resetTitleAndRevertLockIcon();
34710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mHttpAuthenticationDialog = null;
34720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mHttpAuthHandler = null;
34730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            }})
34740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setOnCancelListener(new DialogInterface.OnCancelListener() {
34750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        public void onCancel(DialogInterface dialog) {
34760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            handler.cancel();
34770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            BrowserActivity.this.resetTitleAndRevertLockIcon();
34780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            mHttpAuthenticationDialog = null;
34790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            mHttpAuthHandler = null;
34800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }})
34810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .create();
34820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Make the IME appear when the dialog is displayed if applicable.
34830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        dialog.getWindow().setSoftInputMode(
34840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);
34850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        dialog.show();
34860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (focusId != 0) {
34870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            dialog.findViewById(focusId).requestFocus();
34880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
34890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            v.findViewById(R.id.username_edit).requestFocus();
34900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
34910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mHttpAuthenticationDialog = dialog;
34920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
34930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
34940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public int getProgress() {
34950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebView w = mTabControl.getCurrentWebView();
34960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (w != null) {
34970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return w.getProgress();
34980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
34990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return 100;
35000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
35010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
35020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
35030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
35040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Set HTTP authentication password.
35050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *
35060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param host The host for the password
35070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param realm The realm for the password
35080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param username The username for the password. If it is null, it means
35090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *            password can't be saved.
35100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param password The password
35110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
35120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public void setHttpAuthUsernamePassword(String host, String realm,
35130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                            String username,
35140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                            String password) {
35150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebView w = mTabControl.getCurrentWebView();
35160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (w != null) {
35170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            w.setHttpAuthUsernamePassword(host, realm, username, password);
35180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
35190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
35200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
35210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
35220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * connectivity manager says net has come or gone... inform the user
35230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param up true if net has come up, false if net has gone down
35240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
35250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public void onNetworkToggle(boolean up) {
35260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (up == mIsNetworkUp) {
35270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
35280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else if (up) {
35290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mIsNetworkUp = true;
35300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (mAlertDialog != null) {
35310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mAlertDialog.cancel();
35320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mAlertDialog = null;
35330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
35340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
35350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mIsNetworkUp = false;
3536eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott            if (mInLoad) {
3537eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott                createAndShowNetworkDialog();
3538eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott           }
35390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
35400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebView w = mTabControl.getCurrentWebView();
35410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (w != null) {
35420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            w.setNetworkAvailable(up);
35430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
35440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
35450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
354622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    boolean isNetworkUp() {
354722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return mIsNetworkUp;
354822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
354922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
3550eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott    // This method shows the network dialog alerting the user that the net is
3551eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott    // down. It will only show the dialog if mAlertDialog is null.
3552eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott    private void createAndShowNetworkDialog() {
3553eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott        if (mAlertDialog == null) {
3554eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott            mAlertDialog = new AlertDialog.Builder(this)
3555eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott                    .setTitle(R.string.loadSuspendedTitle)
3556eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott                    .setMessage(R.string.loadSuspended)
3557eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott                    .setPositiveButton(R.string.ok, null)
3558eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott                    .show();
3559eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott        }
3560eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott    }
3561eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott
35620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    @Override
35630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    protected void onActivityResult(int requestCode, int resultCode,
35640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    Intent intent) {
3565bb394f3e134b6e5898ef7ae861b75e95e618688fGrace Kloba        if (getTopWindow() == null) return;
3566bb394f3e134b6e5898ef7ae861b75e95e618688fGrace Kloba
35670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        switch (requestCode) {
35680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case COMBO_PAGE:
35690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (resultCode == RESULT_OK && intent != null) {
35700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    String data = intent.getAction();
35710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    Bundle extras = intent.getExtras();
35720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    if (extras != null && extras.getBoolean("new_window", false)) {
357325d3547e0df084f963e38c6a93c99b02bd619de3Leon Scroggins                        openTab(data);
35740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    } else {
357522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        final Tab currentTab =
35760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mTabControl.getCurrentTab();
35771f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                        dismissSubWindow(currentTab);
35781f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                        if (data != null && data.length() != 0) {
35791f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                            getTopWindow().loadUrl(data);
35800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }
35810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
35820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
3583fde9746ac3055848e110c35f19ec5893c621f766Leon Scroggins                // Deliberately fall through to PREFERENCES_PAGE, since the
3584fde9746ac3055848e110c35f19ec5893c621f766Leon Scroggins                // same extra may be attached to the COMBO_PAGE
3585fde9746ac3055848e110c35f19ec5893c621f766Leon Scroggins            case PREFERENCES_PAGE:
3586fde9746ac3055848e110c35f19ec5893c621f766Leon Scroggins                if (resultCode == RESULT_OK && intent != null) {
3587fde9746ac3055848e110c35f19ec5893c621f766Leon Scroggins                    String action = intent.getStringExtra(Intent.EXTRA_TEXT);
3588fde9746ac3055848e110c35f19ec5893c621f766Leon Scroggins                    if (BrowserSettings.PREF_CLEAR_HISTORY.equals(action)) {
3589fde9746ac3055848e110c35f19ec5893c621f766Leon Scroggins                        mTabControl.removeParentChildRelationShips();
3590fde9746ac3055848e110c35f19ec5893c621f766Leon Scroggins                    }
3591fde9746ac3055848e110c35f19ec5893c621f766Leon Scroggins                }
35920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
35938d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins            // Choose a file from the file picker.
35948d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins            case FILE_SELECTED:
35958d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins                if (null == mUploadMessage) break;
35968d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins                Uri result = intent == null || resultCode != RESULT_OK ? null
35978d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins                        : intent.getData();
35988d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins                mUploadMessage.onReceiveValue(result);
35998d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins                mUploadMessage = null;
36008d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins                break;
36010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            default:
36020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
36030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
3604304442375719effd41dbd53ae62de7a8d0cec7d9Leon Scroggins        getTopWindow().requestFocus();
36050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
36060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
36070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /*
36080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * This method is called as a result of the user selecting the options
3609f08809b2cf7e502fef5965691a7fb6d7cf0322afLeon Scroggins     * menu to see the download window. It shows the download window on top of
3610f08809b2cf7e502fef5965691a7fb6d7cf0322afLeon Scroggins     * the current window.
36110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
3612f08809b2cf7e502fef5965691a7fb6d7cf0322afLeon Scroggins    private void viewDownloads(Uri downloadRecord) {
36130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        Intent intent = new Intent(this,
36140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                BrowserDownloadPage.class);
36150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        intent.setData(downloadRecord);
361622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        startActivityForResult(intent, BrowserActivity.DOWNLOAD_PAGE);
36170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
36180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
36190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
3620160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins    /**
3621160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins     * Open the Go page.
3622160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins     * @param startWithHistory If true, open starting on the history tab.
3623160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins     *                         Otherwise, start with the bookmarks tab.
3624160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins     */
3625304442375719effd41dbd53ae62de7a8d0cec7d9Leon Scroggins    /* package */ void bookmarksOrHistoryPicker(boolean startWithHistory) {
36260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebView current = mTabControl.getCurrentWebView();
36270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (current == null) {
36280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
36290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
36300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        Intent intent = new Intent(this,
36310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                CombinedBookmarkHistoryActivity.class);
36320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String title = current.getTitle();
36330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String url = current.getUrl();
3634dcc2b6f08dd5677bc6ba761a9ba6f1c655113051Ben Murdoch        Bitmap thumbnail = createScreenshot(current);
3635dcc2b6f08dd5677bc6ba761a9ba6f1c655113051Ben Murdoch
36360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Just in case the user opens bookmarks before a page finishes loading
36370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // so the current history item, and therefore the page, is null.
36380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (null == url) {
36390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            url = mLastEnteredUrl;
36400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // This can happen.
36410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (null == url) {
36420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                url = mSettings.getHomePage();
36430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
36440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
36450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // In case the web page has not yet received its associated title.
36460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (title == null) {
36470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            title = url;
36480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
36490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        intent.putExtra("title", title);
36500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        intent.putExtra("url", url);
3651dcc2b6f08dd5677bc6ba761a9ba6f1c655113051Ben Murdoch        intent.putExtra("thumbnail", thumbnail);
3652304442375719effd41dbd53ae62de7a8d0cec7d9Leon Scroggins        // Disable opening in a new window if we have maxed out the windows
365322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        intent.putExtra("disable_new_window", !mTabControl.canCreateNewTab());
36543918d4443ff38ef1870e02aa51a8b29f8352bb1aPatrick Scott        intent.putExtra("touch_icon_url", current.getTouchIconUrl());
36550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (startWithHistory) {
36560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            intent.putExtra(CombinedBookmarkHistoryActivity.STARTING_TAB,
36570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    CombinedBookmarkHistoryActivity.HISTORY_TAB);
36580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
36590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        startActivityForResult(intent, COMBO_PAGE);
36600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
36610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
36620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Called when loading from context menu or LOAD_URL message
36630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void loadURL(WebView view, String url) {
36640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // In case the user enters nothing.
36650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (url != null && url.length() != 0 && view != null) {
36660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            url = smartUrlFilter(url);
366722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (!view.getWebViewClient().shouldOverrideUrlLoading(view, url)) {
36680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                view.loadUrl(url);
36690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
36700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
36710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
36720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
36730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private String smartUrlFilter(Uri inUri) {
36740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (inUri != null) {
36750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return smartUrlFilter(inUri.toString());
36760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
36770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return null;
36780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
36790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
3680b34f87a2e13af13d697130482af01b537ab7c5fdFeng Qian    protected static final Pattern ACCEPTED_URI_SCHEMA = Pattern.compile(
36810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            "(?i)" + // switch on case insensitive matching
36820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            "(" +    // begin group for schema
36830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            "(?:http|https|file):\\/\\/" +
368425ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima            "|(?:inline|data|about|content|javascript):" +
36850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ")" +
36860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            "(.*)" );
36870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
36880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
36890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Attempts to determine whether user input is a URL or search
36900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * terms.  Anything with a space is passed to search.
36910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *
36920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Converts to lowercase any mistakenly uppercased schema (i.e.,
36930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * "Http://" converts to "http://"
36940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *
36950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @return Original or modified URL
36960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *
36970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
36980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    String smartUrlFilter(String url) {
36990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
37000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String inUrl = url.trim();
37010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        boolean hasSpace = inUrl.indexOf(' ') != -1;
37020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
37030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        Matcher matcher = ACCEPTED_URI_SCHEMA.matcher(inUrl);
37040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (matcher.matches()) {
37050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // force scheme to lowercase
37060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            String scheme = matcher.group(1);
37070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            String lcScheme = scheme.toLowerCase();
37080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (!lcScheme.equals(scheme)) {
3709123ecfb21e7ca670e3d04efe58780b3bac54a9a1Mitsuru Oshima                inUrl = lcScheme + matcher.group(2);
3710123ecfb21e7ca670e3d04efe58780b3bac54a9a1Mitsuru Oshima            }
3711123ecfb21e7ca670e3d04efe58780b3bac54a9a1Mitsuru Oshima            if (hasSpace) {
3712123ecfb21e7ca670e3d04efe58780b3bac54a9a1Mitsuru Oshima                inUrl = inUrl.replace(" ", "%20");
37130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
37140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return inUrl;
37150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
37160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (hasSpace) {
3717565505b1a2c1d3099496af5910760087602e994aSatish Sampath            // FIXME: Is this the correct place to add to searches?
3718565505b1a2c1d3099496af5910760087602e994aSatish Sampath            // what if someone else calls this function?
3719565505b1a2c1d3099496af5910760087602e994aSatish Sampath            int shortcut = parseUrlShortcut(inUrl);
3720565505b1a2c1d3099496af5910760087602e994aSatish Sampath            if (shortcut != SHORTCUT_INVALID) {
3721565505b1a2c1d3099496af5910760087602e994aSatish Sampath                Browser.addSearchUrl(mResolver, inUrl);
3722565505b1a2c1d3099496af5910760087602e994aSatish Sampath                String query = inUrl.substring(2);
3723565505b1a2c1d3099496af5910760087602e994aSatish Sampath                switch (shortcut) {
3724565505b1a2c1d3099496af5910760087602e994aSatish Sampath                case SHORTCUT_GOOGLE_SEARCH:
372547fdfdb989ffb79590a39c40792be995de32e521Grace Kloba                    return URLUtil.composeSearchUrl(query, QuickSearch_G, QUERY_PLACE_HOLDER);
3726565505b1a2c1d3099496af5910760087602e994aSatish Sampath                case SHORTCUT_WIKIPEDIA_SEARCH:
3727565505b1a2c1d3099496af5910760087602e994aSatish Sampath                    return URLUtil.composeSearchUrl(query, QuickSearch_W, QUERY_PLACE_HOLDER);
3728565505b1a2c1d3099496af5910760087602e994aSatish Sampath                case SHORTCUT_DICTIONARY_SEARCH:
3729565505b1a2c1d3099496af5910760087602e994aSatish Sampath                    return URLUtil.composeSearchUrl(query, QuickSearch_D, QUERY_PLACE_HOLDER);
3730565505b1a2c1d3099496af5910760087602e994aSatish Sampath                case SHORTCUT_GOOGLE_MOBILE_LOCAL_SEARCH:
37310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // FIXME: we need location in this case
3732565505b1a2c1d3099496af5910760087602e994aSatish Sampath                    return URLUtil.composeSearchUrl(query, QuickSearch_L, QUERY_PLACE_HOLDER);
37330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
37340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
37350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
37365ee906c089567bca705e18561357510d7b55cb5aDan Egnor            if (Patterns.WEB_URL.matcher(inUrl).matches()) {
37370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                return URLUtil.guessUrl(inUrl);
37380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
37390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
37400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
37410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        Browser.addSearchUrl(mResolver, inUrl);
374247fdfdb989ffb79590a39c40792be995de32e521Grace Kloba        return URLUtil.composeSearchUrl(inUrl, QuickSearch_G, QUERY_PLACE_HOLDER);
37430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
37440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
3745bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch    /* package */ void setShouldShowErrorConsole(boolean flag) {
3746bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch        if (flag == mShouldShowErrorConsole) {
3747bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch            // Nothing to do.
3748bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch            return;
3749bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch        }
3750bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch
3751bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch        mShouldShowErrorConsole = flag;
3752bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch
375322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        ErrorConsoleView errorConsole = mTabControl.getCurrentTab()
375422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                .getErrorConsole(true);
3755bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch
3756bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch        if (flag) {
3757bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch            // Setting the show state of the console will cause it's the layout to be inflated.
3758bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch            if (errorConsole.numberOfErrors() > 0) {
3759bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch                errorConsole.showConsole(ErrorConsoleView.SHOW_MINIMIZED);
3760bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch            } else {
3761bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch                errorConsole.showConsole(ErrorConsoleView.SHOW_NONE);
3762bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch            }
3763bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch
3764bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch            // Now we can add it to the main view.
3765bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch            mErrorConsoleContainer.addView(errorConsole,
376615b8ec6b226f4d57307716e1f495e10a91f8cbf4Romain Guy                    new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
3767bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch                                                  ViewGroup.LayoutParams.WRAP_CONTENT));
3768bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch        } else {
3769bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch            mErrorConsoleContainer.removeView(errorConsole);
3770bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch        }
3771bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch
3772bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch    }
3773bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch
377422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    boolean shouldShowErrorConsole() {
377522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return mShouldShowErrorConsole;
377622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
377722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
3778163ab74e2f85b53a1a374c49677073fb64d35f28Andrei Popescu    private void setStatusBarVisibility(boolean visible) {
3779163ab74e2f85b53a1a374c49677073fb64d35f28Andrei Popescu        int flag = visible ? 0 : WindowManager.LayoutParams.FLAG_FULLSCREEN;
3780163ab74e2f85b53a1a374c49677073fb64d35f28Andrei Popescu        getWindow().setFlags(flag, WindowManager.LayoutParams.FLAG_FULLSCREEN);
3781163ab74e2f85b53a1a374c49677073fb64d35f28Andrei Popescu    }
3782163ab74e2f85b53a1a374c49677073fb64d35f28Andrei Popescu
378356199cc25e7ee0455ec2a8099098b66b8554f677Andrei Popescu
378456199cc25e7ee0455ec2a8099098b66b8554f677Andrei Popescu    private void sendNetworkType(String type, String subtype) {
378556199cc25e7ee0455ec2a8099098b66b8554f677Andrei Popescu        WebView w = mTabControl.getCurrentWebView();
378656199cc25e7ee0455ec2a8099098b66b8554f677Andrei Popescu        if (w != null) {
378756199cc25e7ee0455ec2a8099098b66b8554f677Andrei Popescu            w.setNetworkType(type, subtype);
378856199cc25e7ee0455ec2a8099098b66b8554f677Andrei Popescu        }
378956199cc25e7ee0455ec2a8099098b66b8554f677Andrei Popescu    }
379056199cc25e7ee0455ec2a8099098b66b8554f677Andrei Popescu
3791eb6eef4c45df2d65c3e70660493a147a2be405e3Grace Kloba    final static int LOCK_ICON_UNSECURE = 0;
3792eb6eef4c45df2d65c3e70660493a147a2be405e3Grace Kloba    final static int LOCK_ICON_SECURE   = 1;
3793eb6eef4c45df2d65c3e70660493a147a2be405e3Grace Kloba    final static int LOCK_ICON_MIXED    = 2;
37940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
37950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private BrowserSettings mSettings;
37960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private TabControl      mTabControl;
37970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private ContentResolver mResolver;
37980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private FrameLayout     mContentView;
3799adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu    private View            mCustomView;
3800adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu    private FrameLayout     mCustomViewContainer;
3801c9b5556351b59caec77b4eec1ad30652fec6a4d9Andrei Popescu    private WebChromeClient.CustomViewCallback mCustomViewCallback;
38020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
38030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // FIXME, temp address onPrepareMenu performance problem. When we move everything out of
38040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // view, we should rewrite this.
38050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private int mCurrentMenuState = 0;
38060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private int mMenuState = R.id.MAIN_MENU;
3807adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu    private int mOldMenuState = EMPTY_MENU;
38080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private static final int EMPTY_MENU = -1;
38090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private Menu mMenu;
38100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
38110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private FindDialog mFindDialog;
38120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Used to prevent chording to result in firing two shortcuts immediately
38130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // one after another.  Fixes bug 1211714.
38140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    boolean mCanChord;
38150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
38160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private boolean mInLoad;
38170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private boolean mIsNetworkUp;
3818b7cc8b439dc595dc48e1c2183b35d23ad72dfbe5Ben Murdoch    private boolean mDidStopLoad;
38190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
38200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private boolean mActivityInPause = true;
38210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
38220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private boolean mMenuIsDown;
38230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
38240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private static boolean mInTrace;
38250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
38260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Performance probe
38270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private static final int[] SYSTEM_CPU_FORMAT = new int[] {
38280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Process.PROC_SPACE_TERM | Process.PROC_COMBINE,
38290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Process.PROC_SPACE_TERM | Process.PROC_OUT_LONG, // 1: user time
38300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Process.PROC_SPACE_TERM | Process.PROC_OUT_LONG, // 2: nice time
38310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Process.PROC_SPACE_TERM | Process.PROC_OUT_LONG, // 3: sys time
38320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Process.PROC_SPACE_TERM | Process.PROC_OUT_LONG, // 4: idle time
38330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Process.PROC_SPACE_TERM | Process.PROC_OUT_LONG, // 5: iowait time
38340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Process.PROC_SPACE_TERM | Process.PROC_OUT_LONG, // 6: irq time
38350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Process.PROC_SPACE_TERM | Process.PROC_OUT_LONG  // 7: softirq time
38360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    };
38370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
38380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private long mStart;
38390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private long mProcessStart;
38400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private long mUserStart;
38410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private long mSystemStart;
38420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private long mIdleStart;
38430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private long mIrqStart;
38440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
38450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private long mUiStart;
38460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
38470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private Drawable    mMixLockIcon;
38480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private Drawable    mSecLockIcon;
38490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
38500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /* hold a ref so we can auto-cancel if necessary */
38510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private AlertDialog mAlertDialog;
38520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
38530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Wait for credentials before loading google.com
38540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private ProgressDialog mCredsDlg;
38550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
38560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // The up-to-date URL and title (these can be different from those stored
38570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // in WebView, since it takes some time for the information in WebView to
38580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // get updated)
38590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private String mUrl;
38600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private String mTitle;
38610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
38620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // As PageInfo has different style for landscape / portrait, we have
38630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // to re-open it when configuration changed
38640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private AlertDialog mPageInfoDialog;
386522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private Tab mPageInfoView;
38660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // If the Page-Info dialog is launched from the SSL-certificate-on-error
38670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // dialog, we should not just dismiss it, but should get back to the
38680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // SSL-certificate-on-error dialog. This flag is used to store this state
3869c7b92f811dfa3572578ddc6714c98a03936d9ce5Leon Scroggins    private boolean mPageInfoFromShowSSLCertificateOnError;
38700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
38710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // as SSLCertificateOnError has different style for landscape / portrait,
38720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // we have to re-open it when configuration changed
38730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private AlertDialog mSSLCertificateOnErrorDialog;
38740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private WebView mSSLCertificateOnErrorView;
38750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private SslErrorHandler mSSLCertificateOnErrorHandler;
38760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private SslError mSSLCertificateOnErrorError;
38770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
38780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // as SSLCertificate has different style for landscape / portrait, we
38790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // have to re-open it when configuration changed
38800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private AlertDialog mSSLCertificateDialog;
388122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private Tab mSSLCertificateView;
38820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
38830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // as HttpAuthentication has different style for landscape / portrait, we
38840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // have to re-open it when configuration changed
38850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private AlertDialog mHttpAuthenticationDialog;
38860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private HttpAuthHandler mHttpAuthHandler;
38870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
38880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /*package*/ static final FrameLayout.LayoutParams COVER_SCREEN_PARAMS =
38890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                            new FrameLayout.LayoutParams(
389015b8ec6b226f4d57307716e1f495e10a91f8cbf4Romain Guy                                            ViewGroup.LayoutParams.MATCH_PARENT,
389115b8ec6b226f4d57307716e1f495e10a91f8cbf4Romain Guy                                            ViewGroup.LayoutParams.MATCH_PARENT);
3892adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu    /*package*/ static final FrameLayout.LayoutParams COVER_SCREEN_GRAVITY_CENTER =
3893adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu                                            new FrameLayout.LayoutParams(
389415b8ec6b226f4d57307716e1f495e10a91f8cbf4Romain Guy                                            ViewGroup.LayoutParams.MATCH_PARENT,
389515b8ec6b226f4d57307716e1f495e10a91f8cbf4Romain Guy                                            ViewGroup.LayoutParams.MATCH_PARENT,
3896adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu                                            Gravity.CENTER);
389747fdfdb989ffb79590a39c40792be995de32e521Grace Kloba    // Google search
389847fdfdb989ffb79590a39c40792be995de32e521Grace Kloba    final static String QuickSearch_G = "http://www.google.com/m?q=%s";
38990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Wikipedia search
39000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    final static String QuickSearch_W = "http://en.wikipedia.org/w/index.php?search=%s&go=Go";
39010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Dictionary search
39020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    final static String QuickSearch_D = "http://dictionary.reference.com/search?q=%s";
39030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Google Mobile Local search
39040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    final static String QuickSearch_L = "http://www.google.com/m/search?site=local&q=%s&near=mountain+view";
39050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
39060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    final static String QUERY_PLACE_HOLDER = "%s";
39070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
39080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // "source" parameter for Google search through search key
39090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    final static String GOOGLE_SEARCH_SOURCE_SEARCHKEY = "browser-key";
39100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // "source" parameter for Google search through goto menu
39110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    final static String GOOGLE_SEARCH_SOURCE_GOTO = "browser-goto";
39120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // "source" parameter for Google search through simplily type
39130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    final static String GOOGLE_SEARCH_SOURCE_TYPE = "browser-type";
39140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // "source" parameter for Google search suggested by the browser
39150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    final static String GOOGLE_SEARCH_SOURCE_SUGGEST = "browser-suggest";
39160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // "source" parameter for Google search from unknown source
39170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    final static String GOOGLE_SEARCH_SOURCE_UNKNOWN = "unknown";
39180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
39190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private final static String LOGTAG = "browser";
39200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
39210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private String mLastEnteredUrl;
39220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
39230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private PowerManager.WakeLock mWakeLock;
39240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private final static int WAKELOCK_TIMEOUT = 5 * 60 * 1000; // 5 minutes
39250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
39260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private Toast mStopToast;
39270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
392868579393973f745fc65a2781061af9bb8f2d7020Leon Scroggins    private TitleBar mTitleBar;
392981db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins
3930bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch    private LinearLayout mErrorConsoleContainer = null;
3931bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch    private boolean mShouldShowErrorConsole = false;
3932bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch
39330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // As the ids are dynamically created, we can't guarantee that they will
39340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // be in sequence, so this static array maps ids to a window number.
39350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    final static private int[] WINDOW_SHORTCUT_ID_ARRAY =
39360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    { R.id.window_one_menu_id, R.id.window_two_menu_id, R.id.window_three_menu_id,
39370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project      R.id.window_four_menu_id, R.id.window_five_menu_id, R.id.window_six_menu_id,
39380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project      R.id.window_seven_menu_id, R.id.window_eight_menu_id };
39390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
39400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // monitor platform changes
39410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private IntentFilter mNetworkStateChangedFilter;
39420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private BroadcastReceiver mNetworkStateIntentReceiver;
39430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
3944b4da0ad0351996f639b50f9f29b123a9b5c24fd0Grace Kloba    private BroadcastReceiver mPackageInstallationReceiver;
3945b4da0ad0351996f639b50f9f29b123a9b5c24fd0Grace Kloba
39460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // activity requestCode
394778a98e459323f938e97789a6131beddbebb459ceNicolas Roard    final static int COMBO_PAGE                 = 1;
394878a98e459323f938e97789a6131beddbebb459ceNicolas Roard    final static int DOWNLOAD_PAGE              = 2;
394978a98e459323f938e97789a6131beddbebb459ceNicolas Roard    final static int PREFERENCES_PAGE           = 3;
39508d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins    final static int FILE_SELECTED              = 4;
39510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
3952540035dfd1347c78eeec10ec0847e18fcc50ef36Andrei Popescu    // the default <video> poster
3953540035dfd1347c78eeec10ec0847e18fcc50ef36Andrei Popescu    private Bitmap mDefaultVideoPoster;
3954540035dfd1347c78eeec10ec0847e18fcc50ef36Andrei Popescu    // the video progress view
3955540035dfd1347c78eeec10ec0847e18fcc50ef36Andrei Popescu    private View mVideoProgressView;
3956540035dfd1347c78eeec10ec0847e18fcc50ef36Andrei Popescu
395725ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima    /**
395825ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima     * A UrlData class to abstract how the content will be set to WebView.
395925ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima     * This base class uses loadUrl to show the content.
396025ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima     */
396125ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima    private static class UrlData {
3962068e48b469f5abca53ee3da38f933cf2c25c93b8Grace Kloba        final String mUrl;
3963068e48b469f5abca53ee3da38f933cf2c25c93b8Grace Kloba        final Map<String, String> mHeaders;
396458d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        final Intent mVoiceIntent;
396560e095c190496d42327f8ec2ef990c044d15a76fGrace Kloba
396625ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima        UrlData(String url) {
396725ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima            this.mUrl = url;
3968068e48b469f5abca53ee3da38f933cf2c25c93b8Grace Kloba            this.mHeaders = null;
396958d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins            this.mVoiceIntent = null;
397025ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima        }
397160e095c190496d42327f8ec2ef990c044d15a76fGrace Kloba
397258d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        UrlData(String url, Map<String, String> headers, Intent intent) {
3973068e48b469f5abca53ee3da38f933cf2c25c93b8Grace Kloba            this.mUrl = url;
3974068e48b469f5abca53ee3da38f933cf2c25c93b8Grace Kloba            this.mHeaders = headers;
3975a1cc3fdce19a336c251297c61cd83ac6cf767cd1Leon Scroggins            if (RecognizerResultsIntent.ACTION_VOICE_SEARCH_RESULTS
3976a1cc3fdce19a336c251297c61cd83ac6cf767cd1Leon Scroggins                    .equals(intent.getAction())) {
397758d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins                this.mVoiceIntent = intent;
397858d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins            } else {
397958d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins                this.mVoiceIntent = null;
398058d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins            }
398160e095c190496d42327f8ec2ef990c044d15a76fGrace Kloba        }
398260e095c190496d42327f8ec2ef990c044d15a76fGrace Kloba
398325ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima        boolean isEmpty() {
398458d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins            return mVoiceIntent == null && (mUrl == null || mUrl.length() == 0);
398525ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima        }
398625ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima
398758d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        public void loadIn(Tab t) {
398858d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins            if (mVoiceIntent != null) {
398958d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins                t.activateVoiceSearchMode(mVoiceIntent);
399058d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins            } else {
399158d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins                t.getWebView().loadUrl(mUrl, mHeaders);
399258d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins            }
399325ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima        }
399425ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima    };
399525ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima
39961f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins    /* package */ static final UrlData EMPTY_URL_DATA = new UrlData(null);
39970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project}
3998