BrowserActivity.java revision 30995e7cef0a0d5f9c7228d504076e0c158fa8b7
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;
11410d1cca0c208d1f9db23893a8515685e04cfe224Bjorn Bringertimport com.android.common.Search;
1151fe13a5230e319df42b21939a14d127bd9bf3856Leon Scrogginsimport com.android.common.speech.LoggingEvents;
1165ee906c089567bca705e18561357510d7b55cb5aDan Egnor
117716d4f542daec3588f45cbc5cb3acc825233b8a1Doug Zongkerimport com.google.android.gsf.GoogleLoginServiceConstants;
1185ee906c089567bca705e18561357510d7b55cb5aDan Egnor
119b6b7f9ef3b4ed220063f555d8b7c205210a61a04Leon Scrogginsimport java.io.ByteArrayOutputStream;
1200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport java.io.File;
1214f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdochimport java.io.IOException;
1224f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdochimport java.io.InputStream;
1230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport java.net.MalformedURLException;
1240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport java.net.URI;
1259918943559193e3e047a1c18442e2cdb0fe22b15Dianne Hackbornimport java.net.URISyntaxException;
1260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport java.net.URL;
1270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport java.net.URLEncoder;
1280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport java.text.ParseException;
1290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport java.util.Date;
1300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport java.util.HashMap;
13130995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescuimport java.util.HashSet;
13200f54c589fd38431efd42ea2a551a49e64d595d5Grace Klobaimport java.util.Iterator;
13330995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescuimport java.util.List;
134068e48b469f5abca53ee3da38f933cf2c25c93b8Grace Klobaimport java.util.Map;
13530995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescuimport java.util.Set;
1360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport java.util.regex.Matcher;
1370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport java.util.regex.Pattern;
1380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
1390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectpublic class BrowserActivity extends Activity
140752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana    implements View.OnCreateContextMenuListener, DownloadListener,
141752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana        AccountManagerCallback<Account[]> {
1420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
14331a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort    /* Define some aliases to make these debugging flags easier to refer to.
14431a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort     * This file imports android.provider.Browser, so we can't just refer to "Browser.DEBUG".
14531a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort     */
14631a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort    private final static boolean DEBUG = com.android.browser.Browser.DEBUG;
14731a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort    private final static boolean LOGV_ENABLED = com.android.browser.Browser.LOGV_ENABLED;
14831a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort    private final static boolean LOGD_ENABLED = com.android.browser.Browser.LOGD_ENABLED;
14931a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort
150565505b1a2c1d3099496af5910760087602e994aSatish Sampath    // These are single-character shortcuts for searching popular sources.
151565505b1a2c1d3099496af5910760087602e994aSatish Sampath    private static final int SHORTCUT_INVALID = 0;
152565505b1a2c1d3099496af5910760087602e994aSatish Sampath    private static final int SHORTCUT_GOOGLE_SEARCH = 1;
153565505b1a2c1d3099496af5910760087602e994aSatish Sampath    private static final int SHORTCUT_WIKIPEDIA_SEARCH = 2;
154565505b1a2c1d3099496af5910760087602e994aSatish Sampath    private static final int SHORTCUT_DICTIONARY_SEARCH = 3;
155565505b1a2c1d3099496af5910760087602e994aSatish Sampath    private static final int SHORTCUT_GOOGLE_MOBILE_LOCAL_SEARCH = 4;
156565505b1a2c1d3099496af5910760087602e994aSatish Sampath
157752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana    private Account[] mAccountsGoogle;
158752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana    private Account[] mAccountsPreferHosted;
1590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
160752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana    private void startReadOfGoogleAccounts() {
161752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana        mAccountsGoogle = null;
162752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana        mAccountsPreferHosted = null;
1630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
164752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana        AccountManager.get(this).getAccountsByTypeAndFeatures(
165752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana                GoogleLoginServiceConstants.ACCOUNT_TYPE,
166752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana                new String[]{GoogleLoginServiceConstants.FEATURE_LEGACY_HOSTED_OR_GOOGLE},
167752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana                this, null);
168752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana    }
169752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana
170752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana    /** This implements AccountManagerCallback<Account[]> */
171752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana    public void run(AccountManagerFuture<Account[]> accountManagerFuture) {
172752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana        try {
173752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana            if (mAccountsGoogle == null) {
174752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana                mAccountsGoogle = accountManagerFuture.getResult();
175752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana
176752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana                AccountManager.get(this).getAccountsByTypeAndFeatures(
177752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana                        GoogleLoginServiceConstants.ACCOUNT_TYPE,
178752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana                        new String[]{GoogleLoginServiceConstants.FEATURE_LEGACY_GOOGLE},
179752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana                        this, null);
180752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana            } else {
181752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana                mAccountsPreferHosted = accountManagerFuture.getResult();
182752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana                setupHomePage();
1830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
184752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana        } catch (OperationCanceledException e) {
185752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana            setupHomePage();
186752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana        } catch (IOException e) {
187752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana            setupHomePage();
188752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana        } catch (AuthenticatorException e) {
189752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana            setupHomePage();
190752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana        }
191752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana    }
192752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana
193752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana    private void setupHomePage() {
194752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana        // get the default home page
195752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana        String homepage = mSettings.getHomePage();
196752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana
197752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana        if (mAccountsPreferHosted != null && mAccountsGoogle != null) {
198752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana            // three cases:
199752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana            //
200752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana            //   hostedUser == googleUser
201752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana            //      The device has only a google account
202752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana            //
203752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana            //   hostedUser != googleUser
204752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana            //      The device has a hosted account and a google account
205752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana            //
206752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana            //   hostedUser != null, googleUser == null
207752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana            //      The device has only a hosted account (so far)
208752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana            String hostedUser = mAccountsPreferHosted.length == 0
209752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana                    ? null
210752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana                    : mAccountsPreferHosted[0].name;
211752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana            String googleUser = mAccountsGoogle.length == 0 ? null : mAccountsGoogle[0].name;
212752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana
213752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana            // developers might have no accounts at all
214752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana            if (hostedUser == null) return;
215752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana
216752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana            if (googleUser == null || !hostedUser.equals(googleUser)) {
217752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana                String domain = hostedUser.substring(hostedUser.lastIndexOf('@')+1);
218752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana                homepage = homepage.replace("?", "/a/" + domain + "?");
2190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
220752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana        }
2210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
222752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana        mSettings.setHomePage(BrowserActivity.this, homepage);
223752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana        resumeAfterCredentials();
2240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
2250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
226a977124eb29b195127fd161120ebbc58b255fb48Cary Clark    private static class ClearThumbnails extends AsyncTask<File, Void, Void> {
2270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        @Override
2280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public Void doInBackground(File... files) {
2290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (files != null) {
2300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                for (File f : files) {
231d6be1758b38d5b066ff10b6af906aa66c63670cdCary Clark                    if (!f.delete()) {
232d6be1758b38d5b066ff10b6af906aa66c63670cdCary Clark                      Log.e(LOGTAG, f.getPath() + " was not deleted");
233d6be1758b38d5b066ff10b6af906aa66c63670cdCary Clark                    }
2340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
2350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
2360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return null;
2370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
2380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
2390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
2403bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    /**
2413bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     * This layout holds everything you see below the status bar, including the
2423bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     * error console, the custom view container, and the webviews.
2433bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     */
2443bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    private FrameLayout mBrowserFrameLayout;
24581db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins
24622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    @Override
24722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    public void onCreate(Bundle icicle) {
24831a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort        if (LOGV_ENABLED) {
2490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Log.v(LOGTAG, this + " onStart");
2500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
2510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        super.onCreate(icicle);
2520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // test the browser in OpenGL
2530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // requestWindowFeature(Window.FEATURE_OPENGL);
2540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
255d334bf564b72416e77e707d25f8c55cfe1d85709Mike Reed        // enable this to test the browser in 32bit
256d334bf564b72416e77e707d25f8c55cfe1d85709Mike Reed        if (false) {
257d334bf564b72416e77e707d25f8c55cfe1d85709Mike Reed            getWindow().setFormat(PixelFormat.RGBX_8888);
258d334bf564b72416e77e707d25f8c55cfe1d85709Mike Reed            BitmapFactory.setDefaultConfig(Bitmap.Config.ARGB_8888);
259d334bf564b72416e77e707d25f8c55cfe1d85709Mike Reed        }
260d334bf564b72416e77e707d25f8c55cfe1d85709Mike Reed
2610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        setDefaultKeyMode(DEFAULT_KEYS_SEARCH_LOCAL);
2620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
2630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mResolver = getContentResolver();
2640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
2650923d69a8ca45222cabd82a80eaa88da9f132e9aGrace Kloba        // If this was a web search request, pass it on to the default web
2660923d69a8ca45222cabd82a80eaa88da9f132e9aGrace Kloba        // search provider and finish this activity.
2670923d69a8ca45222cabd82a80eaa88da9f132e9aGrace Kloba        if (handleWebSearchIntent(getIntent())) {
2680923d69a8ca45222cabd82a80eaa88da9f132e9aGrace Kloba            finish();
2690923d69a8ca45222cabd82a80eaa88da9f132e9aGrace Kloba            return;
2700923d69a8ca45222cabd82a80eaa88da9f132e9aGrace Kloba        }
2710923d69a8ca45222cabd82a80eaa88da9f132e9aGrace Kloba
2720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mSecLockIcon = Resources.getSystem().getDrawable(
2730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                android.R.drawable.ic_secure);
2740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mMixLockIcon = Resources.getSystem().getDrawable(
2750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                android.R.drawable.ic_partial_secure);
2760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
27781db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins        FrameLayout frameLayout = (FrameLayout) getWindow().getDecorView()
27881db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins                .findViewById(com.android.internal.R.id.content);
2793bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins        mBrowserFrameLayout = (FrameLayout) LayoutInflater.from(this)
2803bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                .inflate(R.layout.custom_screen, null);
2813bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins        mContentView = (FrameLayout) mBrowserFrameLayout.findViewById(
2823bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                R.id.main_content);
2833bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins        mErrorConsoleContainer = (LinearLayout) mBrowserFrameLayout
2843bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                .findViewById(R.id.error_console);
2853bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins        mCustomViewContainer = (FrameLayout) mBrowserFrameLayout
2863bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                .findViewById(R.id.fullscreen_custom_content);
2873bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins        frameLayout.addView(mBrowserFrameLayout, COVER_SCREEN_PARAMS);
28868579393973f745fc65a2781061af9bb8f2d7020Leon Scroggins        mTitleBar = new TitleBar(this);
289fe87bd3a3897e4bad65bb3d284659ae2f4e57570Leon Scroggins        mFakeTitleBar = new TitleBar(this);
2900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
2910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Create the tab control and our initial tab
2920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mTabControl = new TabControl(this);
2930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
2940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Open the icon database and retain all the bookmark urls for favicons
2950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        retainIconsOnStartup();
2960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
2970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Keep a settings instance handy.
2980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mSettings = BrowserSettings.getInstance();
2990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mSettings.setTabControl(mTabControl);
3000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mSettings.loadFromDb(this);
3010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
3020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
3030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "Browser");
3040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
305a34f686112fb4f9fbea00b8c2c47153d34e93e41Grace Kloba        /* enables registration for changes in network status from
306a34f686112fb4f9fbea00b8c2c47153d34e93e41Grace Kloba           http stack */
307a34f686112fb4f9fbea00b8c2c47153d34e93e41Grace Kloba        mNetworkStateChangedFilter = new IntentFilter();
308a34f686112fb4f9fbea00b8c2c47153d34e93e41Grace Kloba        mNetworkStateChangedFilter.addAction(
309a34f686112fb4f9fbea00b8c2c47153d34e93e41Grace Kloba                ConnectivityManager.CONNECTIVITY_ACTION);
310a34f686112fb4f9fbea00b8c2c47153d34e93e41Grace Kloba        mNetworkStateIntentReceiver = new BroadcastReceiver() {
311a34f686112fb4f9fbea00b8c2c47153d34e93e41Grace Kloba                @Override
312a34f686112fb4f9fbea00b8c2c47153d34e93e41Grace Kloba                public void onReceive(Context context, Intent intent) {
313a34f686112fb4f9fbea00b8c2c47153d34e93e41Grace Kloba                    if (intent.getAction().equals(
314a34f686112fb4f9fbea00b8c2c47153d34e93e41Grace Kloba                            ConnectivityManager.CONNECTIVITY_ACTION)) {
3157d899d6f5364a5b20716497a3be5e2f778a2bc0eRobert Greenwalt                        boolean noConnectivity = intent.getBooleanExtra(
3167d899d6f5364a5b20716497a3be5e2f778a2bc0eRobert Greenwalt                                ConnectivityManager.EXTRA_NO_CONNECTIVITY, false);
31756199cc25e7ee0455ec2a8099098b66b8554f677Andrei Popescu                        if (!noConnectivity) {
31856199cc25e7ee0455ec2a8099098b66b8554f677Andrei Popescu                            NetworkInfo info = intent.getParcelableExtra(
31956199cc25e7ee0455ec2a8099098b66b8554f677Andrei Popescu                                    ConnectivityManager.EXTRA_NETWORK_INFO);
32056199cc25e7ee0455ec2a8099098b66b8554f677Andrei Popescu                            String typeName = info.getTypeName();
32156199cc25e7ee0455ec2a8099098b66b8554f677Andrei Popescu                            String subtypeName = info.getSubtypeName();
32256199cc25e7ee0455ec2a8099098b66b8554f677Andrei Popescu                            sendNetworkType(typeName.toLowerCase(),
32356199cc25e7ee0455ec2a8099098b66b8554f677Andrei Popescu                                    (subtypeName != null ? subtypeName.toLowerCase() : ""));
32456199cc25e7ee0455ec2a8099098b66b8554f677Andrei Popescu                        }
3257d899d6f5364a5b20716497a3be5e2f778a2bc0eRobert Greenwalt                        onNetworkToggle(!noConnectivity);
326a34f686112fb4f9fbea00b8c2c47153d34e93e41Grace Kloba                    }
327a34f686112fb4f9fbea00b8c2c47153d34e93e41Grace Kloba                }
328a34f686112fb4f9fbea00b8c2c47153d34e93e41Grace Kloba            };
329a34f686112fb4f9fbea00b8c2c47153d34e93e41Grace Kloba
330615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba        IntentFilter filter = new IntentFilter(Intent.ACTION_PACKAGE_ADDED);
331615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba        filter.addAction(Intent.ACTION_PACKAGE_REMOVED);
332615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba        filter.addDataScheme("package");
333615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba        mPackageInstallationReceiver = new BroadcastReceiver() {
334615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba            @Override
335615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba            public void onReceive(Context context, Intent intent) {
336615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                final String action = intent.getAction();
337615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                final String packageName = intent.getData()
338615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                        .getSchemeSpecificPart();
339615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                final boolean replacing = intent.getBooleanExtra(
340615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                        Intent.EXTRA_REPLACING, false);
341615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                if (Intent.ACTION_PACKAGE_REMOVED.equals(action) && replacing) {
342615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                    // if it is replacing, refreshPlugins() when adding
343615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                    return;
344615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                }
34530995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu
34630995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu                if (sGoogleApps.contains(packageName)) {
34730995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu                    BrowserActivity.this.packageChanged(packageName,
34830995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu                            Intent.ACTION_PACKAGE_ADDED.equals(action));
34930995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu                }
35030995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu
351615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                PackageManager pm = BrowserActivity.this.getPackageManager();
352615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                PackageInfo pkgInfo = null;
353615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                try {
354615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                    pkgInfo = pm.getPackageInfo(packageName,
355615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                            PackageManager.GET_PERMISSIONS);
356615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                } catch (PackageManager.NameNotFoundException e) {
357615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                    return;
358615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                }
359615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                if (pkgInfo != null) {
360615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                    String permissions[] = pkgInfo.requestedPermissions;
361615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                    if (permissions == null) {
362615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                        return;
363615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                    }
364615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                    boolean permissionOk = false;
365615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                    for (String permit : permissions) {
366615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                        if (PluginManager.PLUGIN_PERMISSION.equals(permit)) {
367615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                            permissionOk = true;
368615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                            break;
369615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                        }
370615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                    }
371615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                    if (permissionOk) {
372615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                        PluginManager.getInstance(BrowserActivity.this)
373615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                                .refreshPlugins(
374615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                                        Intent.ACTION_PACKAGE_ADDED
375615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                                                .equals(action));
376615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                    }
377615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                }
378615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba            }
379615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba        };
380615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba        registerReceiver(mPackageInstallationReceiver, filter);
381615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba
3820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (!mTabControl.restoreState(icicle)) {
3830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // clear up the thumbnail directory if we can't restore the state as
3840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // none of the files in the directory are referenced any more.
3850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            new ClearThumbnails().execute(
3860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    mTabControl.getThumbnailDir().listFiles());
387aab3f09b5c2d39b19067e57635614080b2403a46Grace Kloba            // there is no quit on Android. But if we can't restore the state,
388aab3f09b5c2d39b19067e57635614080b2403a46Grace Kloba            // we can treat it as a new Browser, remove the old session cookies.
389aab3f09b5c2d39b19067e57635614080b2403a46Grace Kloba            CookieManager.getInstance().removeSessionCookie();
3900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            final Intent intent = getIntent();
3910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            final Bundle extra = intent.getExtras();
3920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Create an initial tab.
3930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // If the intent is ACTION_VIEW and data is not null, the Browser is
3940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // invoked to view the content by another application. In this case,
3950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // the tab will be close when exit.
39625ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima            UrlData urlData = getUrlDataFromIntent(intent);
39725ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima
39858d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins            String action = intent.getAction();
39922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            final Tab t = mTabControl.createNewTab(
40058d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins                    (Intent.ACTION_VIEW.equals(action) &&
40158d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins                    intent.getData() != null)
402a1cc3fdce19a336c251297c61cd83ac6cf767cd1Leon Scroggins                    || RecognizerResultsIntent.ACTION_VOICE_SEARCH_RESULTS
403a1cc3fdce19a336c251297c61cd83ac6cf767cd1Leon Scroggins                    .equals(action),
40425ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima                    intent.getStringExtra(Browser.EXTRA_APPLICATION_ID), urlData.mUrl);
4050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mTabControl.setCurrentTab(t);
4060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            attachTabToContentView(t);
4070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            WebView webView = t.getWebView();
4080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (extra != null) {
4090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                int scale = extra.getInt(Browser.INITIAL_ZOOM_LEVEL, 0);
4100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (scale > 0 && scale <= 1000) {
4110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    webView.setInitialScale(scale);
4120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
4130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
4140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // If we are not restoring from an icicle, then there is a high
4150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // likely hood this is the first run. So, check to see if the
4160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // homepage needs to be configured and copy any plugins from our
4170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // asset directory to the data partition.
4180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if ((extra == null || !extra.getBoolean("testing"))
4190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    && !mSettings.isLoginInitialized()) {
420752b656ef16af3804572ee91469b1cd6ff2a4b87Fred Quintana                startReadOfGoogleAccounts();
4210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
4220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
42325ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima            if (urlData.isEmpty()) {
424304442375719effd41dbd53ae62de7a8d0cec7d9Leon Scroggins                if (mSettings.isLoginInitialized()) {
425304442375719effd41dbd53ae62de7a8d0cec7d9Leon Scroggins                    webView.loadUrl(mSettings.getHomePage());
426304442375719effd41dbd53ae62de7a8d0cec7d9Leon Scroggins                } else {
427304442375719effd41dbd53ae62de7a8d0cec7d9Leon Scroggins                    waitForCredentials();
428304442375719effd41dbd53ae62de7a8d0cec7d9Leon Scroggins                }
4290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } else {
43058d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins                urlData.loadIn(t);
4310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
4320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
4330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // TabControl.restoreState() will create a new tab even if
4341f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins            // restoring the state fails.
4350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            attachTabToContentView(mTabControl.getCurrentTab());
4360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
437615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba
438b3c02da4553b1a629b16377970fdabae28394c94Feng Qian        // Read JavaScript flags if it exists.
439b3c02da4553b1a629b16377970fdabae28394c94Feng Qian        String jsFlags = mSettings.getJsFlags();
440b3c02da4553b1a629b16377970fdabae28394c94Feng Qian        if (jsFlags.trim().length() != 0) {
441b3c02da4553b1a629b16377970fdabae28394c94Feng Qian            mTabControl.getCurrentWebView().setJsFlags(jsFlags);
442b3c02da4553b1a629b16377970fdabae28394c94Feng Qian        }
44330995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu        // Work out which packages are installed on the system.
44430995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu        getInstalledPackages();
4450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
4460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
44758d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    /**
44858d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins     * Feed the previously stored results strings to the BrowserProvider so that
44958d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins     * the SearchDialog will show them instead of the standard searches.
45058d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins     * @param result String to show on the editable line of the SearchDialog.
45158d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins     */
45258d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    /* package */ void showVoiceSearchResults(String result) {
45358d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        ContentProviderClient client = mResolver.acquireContentProviderClient(
45458d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins                Browser.BOOKMARKS_URI);
45558d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        ContentProvider prov = client.getLocalContentProvider();
45658d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        BrowserProvider bp = (BrowserProvider) prov;
45758d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        bp.setQueryResults(mTabControl.getCurrentTab().getVoiceSearchResults());
45858d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        client.release();
45958d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins
46058d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        startSearch(result, false,
46158d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins                createGoogleSearchSourceBundle(GOOGLE_SEARCH_SOURCE_SEARCHKEY),
46258d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins                false);
46358d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    }
46458d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins
4650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    @Override
4660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    protected void onNewIntent(Intent intent) {
46722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        Tab current = mTabControl.getCurrentTab();
4680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // When a tab is closed on exit, the current tab index is set to -1.
4690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Reset before proceed as Browser requires the current tab to be set.
4700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (current == null) {
4710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Try to reset the tab in case the index was incorrect.
4720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            current = mTabControl.getTab(0);
4730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (current == null) {
4740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // No tabs at all so just ignore this intent.
4750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                return;
4760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
4770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mTabControl.setCurrentTab(current);
4780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            attachTabToContentView(current);
4790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            resetTitleAndIcon(current.getWebView());
4800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
4810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final String action = intent.getAction();
4820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final int flags = intent.getFlags();
4830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (Intent.ACTION_MAIN.equals(action) ||
4840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                (flags & Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY) != 0) {
4850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // just resume the browser
4860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
4870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
488a1cc3fdce19a336c251297c61cd83ac6cf767cd1Leon Scroggins        boolean activateVoiceSearch = RecognizerResultsIntent
489a1cc3fdce19a336c251297c61cd83ac6cf767cd1Leon Scroggins                .ACTION_VOICE_SEARCH_RESULTS.equals(action);
4900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (Intent.ACTION_VIEW.equals(action)
4910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                || Intent.ACTION_SEARCH.equals(action)
4920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                || MediaStore.INTENT_ACTION_MEDIA_SEARCH.equals(action)
49358d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins                || Intent.ACTION_WEB_SEARCH.equals(action)
49458d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins                || activateVoiceSearch) {
4953b18ce37c13fce7212948df90a012d7011924a6eLeon Scroggins            if (current.isInVoiceSearchMode()) {
4963b18ce37c13fce7212948df90a012d7011924a6eLeon Scroggins                String title = current.getVoiceDisplayTitle();
4973b18ce37c13fce7212948df90a012d7011924a6eLeon Scroggins                if (title != null && title.equals(intent.getStringExtra(
4983b18ce37c13fce7212948df90a012d7011924a6eLeon Scroggins                        SearchManager.QUERY))) {
4993b18ce37c13fce7212948df90a012d7011924a6eLeon Scroggins                    // The user submitted the same search as the last voice
5003b18ce37c13fce7212948df90a012d7011924a6eLeon Scroggins                    // search, so do nothing.
5013b18ce37c13fce7212948df90a012d7011924a6eLeon Scroggins                    return;
5023b18ce37c13fce7212948df90a012d7011924a6eLeon Scroggins                }
5031fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins                if (Intent.ACTION_SEARCH.equals(action)
5041fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins                        && current.voiceSearchSourceIsGoogle()) {
5051fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins                    Intent logIntent = new Intent(
5061fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins                            LoggingEvents.ACTION_LOG_EVENT);
5071fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins                    logIntent.putExtra(LoggingEvents.EXTRA_EVENT,
5081fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins                            LoggingEvents.VoiceSearch.QUERY_UPDATED);
5091fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins                    logIntent.putExtra(
5101fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins                            LoggingEvents.VoiceSearch.EXTRA_QUERY_UPDATED_VALUE,
5111fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins                            intent.getDataString());
5121fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins                    sendBroadcast(logIntent);
5131fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins                    // Note, onPageStarted will revert the voice title bar
5141fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins                    // When http://b/issue?id=2379215 is fixed, we should update
5151fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins                    // the title bar here.
5161fe13a5230e319df42b21939a14d127bd9bf3856Leon Scroggins                }
5173b18ce37c13fce7212948df90a012d7011924a6eLeon Scroggins            }
518565505b1a2c1d3099496af5910760087602e994aSatish Sampath            // If this was a search request (e.g. search query directly typed into the address bar),
519565505b1a2c1d3099496af5910760087602e994aSatish Sampath            // pass it on to the default web search provider.
520565505b1a2c1d3099496af5910760087602e994aSatish Sampath            if (handleWebSearchIntent(intent)) {
521565505b1a2c1d3099496af5910760087602e994aSatish Sampath                return;
522565505b1a2c1d3099496af5910760087602e994aSatish Sampath            }
523565505b1a2c1d3099496af5910760087602e994aSatish Sampath
52425ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima            UrlData urlData = getUrlDataFromIntent(intent);
52525ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima            if (urlData.isEmpty()) {
52625ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima                urlData = new UrlData(mSettings.getHomePage());
5270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
52825ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima
529cc63403643786905262f505ab5266d8e80b9924cGrace Kloba            final String appId = intent
530cc63403643786905262f505ab5266d8e80b9924cGrace Kloba                    .getStringExtra(Browser.EXTRA_APPLICATION_ID);
53158d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins            if ((Intent.ACTION_VIEW.equals(action) || activateVoiceSearch)
532cc63403643786905262f505ab5266d8e80b9924cGrace Kloba                    && !getPackageName().equals(appId)
533cc63403643786905262f505ab5266d8e80b9924cGrace Kloba                    && (flags & Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT) != 0) {
53422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                Tab appTab = mTabControl.getTabFromId(appId);
535f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                if (appTab != null) {
536f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    Log.i(LOGTAG, "Reusing tab for " + appId);
537f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    // Dismiss the subwindow if applicable.
538f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    dismissSubWindow(appTab);
539f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    // Since we might kill the WebView, remove it from the
540f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    // content view first.
541f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    removeTabFromContentView(appTab);
542f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    // Recreate the main WebView after destroying the old one.
543f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    // If the WebView has the same original url and is on that
544f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    // page, it can be reused.
545f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    boolean needsLoad =
54625ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima                            mTabControl.recreateWebView(appTab, urlData.mUrl);
547bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch
548f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    if (current != appTab) {
5491f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                        switchToTab(mTabControl.getTabIndex(appTab));
5501f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                        if (needsLoad) {
55158d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins                            urlData.loadIn(appTab);
5521f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                        }
553f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    } else {
5541f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                        // If the tab was the current tab, we have to attach
5551f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                        // it to the view system again.
5561f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                        attachTabToContentView(appTab);
5571f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                        if (needsLoad) {
55858d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins                            urlData.loadIn(appTab);
559f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                        }
560f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    }
561f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    return;
562cd11589fc3930906d4b9b7dd18aa52a9f1eb0c8aPatrick Scott                } else {
563cd11589fc3930906d4b9b7dd18aa52a9f1eb0c8aPatrick Scott                    // No matching application tab, try to find a regular tab
564cd11589fc3930906d4b9b7dd18aa52a9f1eb0c8aPatrick Scott                    // with a matching url.
565cd11589fc3930906d4b9b7dd18aa52a9f1eb0c8aPatrick Scott                    appTab = mTabControl.findUnusedTabWithUrl(urlData.mUrl);
56625515f8bd458a2471d13d876cfb0e18d8ff2a00fLeon Scroggins                    if (appTab != null) {
56725515f8bd458a2471d13d876cfb0e18d8ff2a00fLeon Scroggins                        if (current != appTab) {
56825515f8bd458a2471d13d876cfb0e18d8ff2a00fLeon Scroggins                            switchToTab(mTabControl.getTabIndex(appTab));
56925515f8bd458a2471d13d876cfb0e18d8ff2a00fLeon Scroggins                        }
57025515f8bd458a2471d13d876cfb0e18d8ff2a00fLeon Scroggins                        // Otherwise, we are already viewing the correct tab.
571cd11589fc3930906d4b9b7dd18aa52a9f1eb0c8aPatrick Scott                    } else {
572cd11589fc3930906d4b9b7dd18aa52a9f1eb0c8aPatrick Scott                        // if FLAG_ACTIVITY_BROUGHT_TO_FRONT flag is on, the url
573cd11589fc3930906d4b9b7dd18aa52a9f1eb0c8aPatrick Scott                        // will be opened in a new tab unless we have reached
574cd11589fc3930906d4b9b7dd18aa52a9f1eb0c8aPatrick Scott                        // MAX_TABS. Then the url will be opened in the current
575cd11589fc3930906d4b9b7dd18aa52a9f1eb0c8aPatrick Scott                        // tab. If a new tab is created, it will have "true" for
576cd11589fc3930906d4b9b7dd18aa52a9f1eb0c8aPatrick Scott                        // exit on close.
5771f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                        openTabAndShow(urlData, true, appId);
578cd11589fc3930906d4b9b7dd18aa52a9f1eb0c8aPatrick Scott                    }
579f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                }
5800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } else {
581638d3f45791a31d0b290e180b93bad49576eb6d3Grace Kloba                if (!urlData.isEmpty()
582638d3f45791a31d0b290e180b93bad49576eb6d3Grace Kloba                        && urlData.mUrl.startsWith("about:debug")) {
583638d3f45791a31d0b290e180b93bad49576eb6d3Grace Kloba                    if ("about:debug.dom".equals(urlData.mUrl)) {
584638d3f45791a31d0b290e180b93bad49576eb6d3Grace Kloba                        current.getWebView().dumpDomTree(false);
585638d3f45791a31d0b290e180b93bad49576eb6d3Grace Kloba                    } else if ("about:debug.dom.file".equals(urlData.mUrl)) {
586638d3f45791a31d0b290e180b93bad49576eb6d3Grace Kloba                        current.getWebView().dumpDomTree(true);
587638d3f45791a31d0b290e180b93bad49576eb6d3Grace Kloba                    } else if ("about:debug.render".equals(urlData.mUrl)) {
588638d3f45791a31d0b290e180b93bad49576eb6d3Grace Kloba                        current.getWebView().dumpRenderTree(false);
589638d3f45791a31d0b290e180b93bad49576eb6d3Grace Kloba                    } else if ("about:debug.render.file".equals(urlData.mUrl)) {
590638d3f45791a31d0b290e180b93bad49576eb6d3Grace Kloba                        current.getWebView().dumpRenderTree(true);
591638d3f45791a31d0b290e180b93bad49576eb6d3Grace Kloba                    } else if ("about:debug.display".equals(urlData.mUrl)) {
592638d3f45791a31d0b290e180b93bad49576eb6d3Grace Kloba                        current.getWebView().dumpDisplayTree();
5939b78e1d1e0bd819ae03df5594d4a56519e5d87c7Mike Reed                    } else if (urlData.mUrl.startsWith("about:debug.drag")) {
5949b78e1d1e0bd819ae03df5594d4a56519e5d87c7Mike Reed                        int index = urlData.mUrl.codePointAt(16) - '0';
5959b78e1d1e0bd819ae03df5594d4a56519e5d87c7Mike Reed                        if (index <= 0 || index > 9) {
5969b78e1d1e0bd819ae03df5594d4a56519e5d87c7Mike Reed                            current.getWebView().setDragTracker(null);
5979b78e1d1e0bd819ae03df5594d4a56519e5d87c7Mike Reed                        } else {
5989b78e1d1e0bd819ae03df5594d4a56519e5d87c7Mike Reed                            current.getWebView().setDragTracker(new MeshTracker(index));
5999b78e1d1e0bd819ae03df5594d4a56519e5d87c7Mike Reed                        }
600638d3f45791a31d0b290e180b93bad49576eb6d3Grace Kloba                    } else {
601638d3f45791a31d0b290e180b93bad49576eb6d3Grace Kloba                        mSettings.toggleDebugSettings();
602638d3f45791a31d0b290e180b93bad49576eb6d3Grace Kloba                    }
6030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    return;
6040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
6051f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                // Get rid of the subwindow if it exists
6061f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                dismissSubWindow(current);
60758d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins                urlData.loadIn(current);
6080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
6090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
6100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
6110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
612565505b1a2c1d3099496af5910760087602e994aSatish Sampath    private int parseUrlShortcut(String url) {
613565505b1a2c1d3099496af5910760087602e994aSatish Sampath        if (url == null) return SHORTCUT_INVALID;
614565505b1a2c1d3099496af5910760087602e994aSatish Sampath
615565505b1a2c1d3099496af5910760087602e994aSatish Sampath        // FIXME: quick search, need to be customized by setting
616565505b1a2c1d3099496af5910760087602e994aSatish Sampath        if (url.length() > 2 && url.charAt(1) == ' ') {
617565505b1a2c1d3099496af5910760087602e994aSatish Sampath            switch (url.charAt(0)) {
618565505b1a2c1d3099496af5910760087602e994aSatish Sampath            case 'g': return SHORTCUT_GOOGLE_SEARCH;
619565505b1a2c1d3099496af5910760087602e994aSatish Sampath            case 'w': return SHORTCUT_WIKIPEDIA_SEARCH;
620565505b1a2c1d3099496af5910760087602e994aSatish Sampath            case 'd': return SHORTCUT_DICTIONARY_SEARCH;
621565505b1a2c1d3099496af5910760087602e994aSatish Sampath            case 'l': return SHORTCUT_GOOGLE_MOBILE_LOCAL_SEARCH;
622565505b1a2c1d3099496af5910760087602e994aSatish Sampath            }
623565505b1a2c1d3099496af5910760087602e994aSatish Sampath        }
624565505b1a2c1d3099496af5910760087602e994aSatish Sampath        return SHORTCUT_INVALID;
625565505b1a2c1d3099496af5910760087602e994aSatish Sampath    }
626565505b1a2c1d3099496af5910760087602e994aSatish Sampath
627565505b1a2c1d3099496af5910760087602e994aSatish Sampath    /**
628565505b1a2c1d3099496af5910760087602e994aSatish Sampath     * Launches the default web search activity with the query parameters if the given intent's data
629565505b1a2c1d3099496af5910760087602e994aSatish Sampath     * are identified as plain search terms and not URLs/shortcuts.
630565505b1a2c1d3099496af5910760087602e994aSatish Sampath     * @return true if the intent was handled and web search activity was launched, false if not.
631565505b1a2c1d3099496af5910760087602e994aSatish Sampath     */
632565505b1a2c1d3099496af5910760087602e994aSatish Sampath    private boolean handleWebSearchIntent(Intent intent) {
633565505b1a2c1d3099496af5910760087602e994aSatish Sampath        if (intent == null) return false;
634565505b1a2c1d3099496af5910760087602e994aSatish Sampath
635565505b1a2c1d3099496af5910760087602e994aSatish Sampath        String url = null;
636565505b1a2c1d3099496af5910760087602e994aSatish Sampath        final String action = intent.getAction();
637a1cc3fdce19a336c251297c61cd83ac6cf767cd1Leon Scroggins        if (RecognizerResultsIntent.ACTION_VOICE_SEARCH_RESULTS.equals(
638a1cc3fdce19a336c251297c61cd83ac6cf767cd1Leon Scroggins                action)) {
63958d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins            return false;
64058d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        }
641565505b1a2c1d3099496af5910760087602e994aSatish Sampath        if (Intent.ACTION_VIEW.equals(action)) {
6421e70505659dd9bf0f7e03bce787ba880f9b7a8aaGrace Kloba            Uri data = intent.getData();
6431e70505659dd9bf0f7e03bce787ba880f9b7a8aaGrace Kloba            if (data != null) url = data.toString();
644565505b1a2c1d3099496af5910760087602e994aSatish Sampath        } else if (Intent.ACTION_SEARCH.equals(action)
645565505b1a2c1d3099496af5910760087602e994aSatish Sampath                || MediaStore.INTENT_ACTION_MEDIA_SEARCH.equals(action)
646565505b1a2c1d3099496af5910760087602e994aSatish Sampath                || Intent.ACTION_WEB_SEARCH.equals(action)) {
647565505b1a2c1d3099496af5910760087602e994aSatish Sampath            url = intent.getStringExtra(SearchManager.QUERY);
648565505b1a2c1d3099496af5910760087602e994aSatish Sampath        }
6490485170e03e079eb61b9dd52fc2c98da02fa7b2cBjorn Bringert        return handleWebSearchRequest(url, intent.getBundleExtra(SearchManager.APP_DATA),
6500485170e03e079eb61b9dd52fc2c98da02fa7b2cBjorn Bringert                intent.getStringExtra(SearchManager.EXTRA_DATA_KEY));
651565505b1a2c1d3099496af5910760087602e994aSatish Sampath    }
652565505b1a2c1d3099496af5910760087602e994aSatish Sampath
653565505b1a2c1d3099496af5910760087602e994aSatish Sampath    /**
654565505b1a2c1d3099496af5910760087602e994aSatish Sampath     * Launches the default web search activity with the query parameters if the given url string
655565505b1a2c1d3099496af5910760087602e994aSatish Sampath     * was identified as plain search terms and not URL/shortcut.
656565505b1a2c1d3099496af5910760087602e994aSatish Sampath     * @return true if the request was handled and web search activity was launched, false if not.
657565505b1a2c1d3099496af5910760087602e994aSatish Sampath     */
6580485170e03e079eb61b9dd52fc2c98da02fa7b2cBjorn Bringert    private boolean handleWebSearchRequest(String inUrl, Bundle appData, String extraData) {
659565505b1a2c1d3099496af5910760087602e994aSatish Sampath        if (inUrl == null) return false;
660565505b1a2c1d3099496af5910760087602e994aSatish Sampath
661565505b1a2c1d3099496af5910760087602e994aSatish Sampath        // In general, we shouldn't modify URL from Intent.
662565505b1a2c1d3099496af5910760087602e994aSatish Sampath        // But currently, we get the user-typed URL from search box as well.
663565505b1a2c1d3099496af5910760087602e994aSatish Sampath        String url = fixUrl(inUrl).trim();
664565505b1a2c1d3099496af5910760087602e994aSatish Sampath
665565505b1a2c1d3099496af5910760087602e994aSatish Sampath        // URLs and site specific search shortcuts are handled by the regular flow of control, so
666565505b1a2c1d3099496af5910760087602e994aSatish Sampath        // return early.
6675ee906c089567bca705e18561357510d7b55cb5aDan Egnor        if (Patterns.WEB_URL.matcher(url).matches()
668bc5b9f358a2b75bf3a104b9f5cd477ad2f6f740fSatish Sampath                || ACCEPTED_URI_SCHEMA.matcher(url).matches()
669565505b1a2c1d3099496af5910760087602e994aSatish Sampath                || parseUrlShortcut(url) != SHORTCUT_INVALID) {
670565505b1a2c1d3099496af5910760087602e994aSatish Sampath            return false;
671565505b1a2c1d3099496af5910760087602e994aSatish Sampath        }
672565505b1a2c1d3099496af5910760087602e994aSatish Sampath
673565505b1a2c1d3099496af5910760087602e994aSatish Sampath        Browser.updateVisitedHistory(mResolver, url, false);
674565505b1a2c1d3099496af5910760087602e994aSatish Sampath        Browser.addSearchUrl(mResolver, url);
675565505b1a2c1d3099496af5910760087602e994aSatish Sampath
676565505b1a2c1d3099496af5910760087602e994aSatish Sampath        Intent intent = new Intent(Intent.ACTION_WEB_SEARCH);
677565505b1a2c1d3099496af5910760087602e994aSatish Sampath        intent.addCategory(Intent.CATEGORY_DEFAULT);
678565505b1a2c1d3099496af5910760087602e994aSatish Sampath        intent.putExtra(SearchManager.QUERY, url);
67915e9f2dc92cf1621f95071b3c740f46079aa0f3bSatish Sampath        if (appData != null) {
68015e9f2dc92cf1621f95071b3c740f46079aa0f3bSatish Sampath            intent.putExtra(SearchManager.APP_DATA, appData);
68115e9f2dc92cf1621f95071b3c740f46079aa0f3bSatish Sampath        }
6820485170e03e079eb61b9dd52fc2c98da02fa7b2cBjorn Bringert        if (extraData != null) {
6830485170e03e079eb61b9dd52fc2c98da02fa7b2cBjorn Bringert            intent.putExtra(SearchManager.EXTRA_DATA_KEY, extraData);
6840485170e03e079eb61b9dd52fc2c98da02fa7b2cBjorn Bringert        }
685cc63403643786905262f505ab5266d8e80b9924cGrace Kloba        intent.putExtra(Browser.EXTRA_APPLICATION_ID, getPackageName());
686565505b1a2c1d3099496af5910760087602e994aSatish Sampath        startActivity(intent);
687565505b1a2c1d3099496af5910760087602e994aSatish Sampath
688565505b1a2c1d3099496af5910760087602e994aSatish Sampath        return true;
689565505b1a2c1d3099496af5910760087602e994aSatish Sampath    }
690565505b1a2c1d3099496af5910760087602e994aSatish Sampath
69125ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima    private UrlData getUrlDataFromIntent(Intent intent) {
69258d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        String url = "";
693068e48b469f5abca53ee3da38f933cf2c25c93b8Grace Kloba        Map<String, String> headers = null;
6940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (intent != null) {
6950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            final String action = intent.getAction();
6960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (Intent.ACTION_VIEW.equals(action)) {
6970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                url = smartUrlFilter(intent.getData());
6980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (url != null && url.startsWith("content:")) {
6990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    /* Append mimetype so webview knows how to display */
7000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    String mimeType = intent.resolveType(getContentResolver());
7010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    if (mimeType != null) {
7020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        url += "?" + mimeType;
7030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
7040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
705068e48b469f5abca53ee3da38f933cf2c25c93b8Grace Kloba                if (url != null && url.startsWith("http")) {
70600f54c589fd38431efd42ea2a551a49e64d595d5Grace Kloba                    final Bundle pairs = intent
70700f54c589fd38431efd42ea2a551a49e64d595d5Grace Kloba                            .getBundleExtra(Browser.EXTRA_HEADERS);
7082d508edbf54ea74cd4e89be8b622b1cbd587464aGrace Kloba                    if (pairs != null && !pairs.isEmpty()) {
70900f54c589fd38431efd42ea2a551a49e64d595d5Grace Kloba                        Iterator<String> iter = pairs.keySet().iterator();
710068e48b469f5abca53ee3da38f933cf2c25c93b8Grace Kloba                        headers = new HashMap<String, String>();
71100f54c589fd38431efd42ea2a551a49e64d595d5Grace Kloba                        while (iter.hasNext()) {
71200f54c589fd38431efd42ea2a551a49e64d595d5Grace Kloba                            String key = iter.next();
71300f54c589fd38431efd42ea2a551a49e64d595d5Grace Kloba                            headers.put(key, pairs.getString(key));
714068e48b469f5abca53ee3da38f933cf2c25c93b8Grace Kloba                        }
715068e48b469f5abca53ee3da38f933cf2c25c93b8Grace Kloba                    }
71625ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima                }
7170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } else if (Intent.ACTION_SEARCH.equals(action)
7180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    || MediaStore.INTENT_ACTION_MEDIA_SEARCH.equals(action)
7190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    || Intent.ACTION_WEB_SEARCH.equals(action)) {
7200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                url = intent.getStringExtra(SearchManager.QUERY);
7210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (url != null) {
7220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    mLastEnteredUrl = url;
723b446443e47c334bc3aaae98b67c8dca347da3032Leon Scroggins                    Browser.updateVisitedHistory(mResolver, url, false);
7240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // In general, we shouldn't modify URL from Intent.
7250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // But currently, we get the user-typed URL from search box as well.
7260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    url = fixUrl(url);
7270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    url = smartUrlFilter(url);
7280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    String searchSource = "&source=android-" + GOOGLE_SEARCH_SOURCE_SUGGEST + "&";
7290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    if (url.contains(searchSource)) {
7300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        String source = null;
7310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        final Bundle appData = intent.getBundleExtra(SearchManager.APP_DATA);
7320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        if (appData != null) {
73310d1cca0c208d1f9db23893a8515685e04cfe224Bjorn Bringert                            source = appData.getString(Search.SOURCE);
7340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }
7350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        if (TextUtils.isEmpty(source)) {
7360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            source = GOOGLE_SEARCH_SOURCE_UNKNOWN;
7370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }
7380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        url = url.replace(searchSource, "&source=android-"+source+"&");
7390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
7400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
7410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
7420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
74358d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        return new UrlData(url, headers, intent);
7440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
74558d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    /* package */ void showVoiceTitleBar(String title) {
74658d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        mTitleBar.setInVoiceMode(true);
74758d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        mFakeTitleBar.setInVoiceMode(true);
7480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
74958d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        mTitleBar.setDisplayTitle(title);
75058d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        mFakeTitleBar.setDisplayTitle(title);
75158d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    }
75258d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    /* package */ void revertVoiceTitleBar() {
75358d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        mTitleBar.setInVoiceMode(false);
75458d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        mFakeTitleBar.setInVoiceMode(false);
75558d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins
75658d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        mTitleBar.setDisplayTitle(mTitle);
75758d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        mFakeTitleBar.setDisplayTitle(mTitle);
75858d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins    }
7590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /* package */ static String fixUrl(String inUrl) {
760652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark        // FIXME: Converting the url to lower case
761652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark        // duplicates functionality in smartUrlFilter().
762652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark        // However, changing all current callers of fixUrl to
763652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark        // call smartUrlFilter in addition may have unwanted
764652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark        // consequences, and is deferred for now.
765652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark        int colon = inUrl.indexOf(':');
766652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark        boolean allLower = true;
767652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark        for (int index = 0; index < colon; index++) {
768652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark            char ch = inUrl.charAt(index);
769652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark            if (!Character.isLetter(ch)) {
770652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark                break;
771652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark            }
772652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark            allLower &= Character.isLowerCase(ch);
773652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark            if (index == colon - 1 && !allLower) {
774652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark                inUrl = inUrl.substring(0, colon).toLowerCase()
775652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark                        + inUrl.substring(colon);
776652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark            }
777652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark        }
7780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (inUrl.startsWith("http://") || inUrl.startsWith("https://"))
7790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return inUrl;
7800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (inUrl.startsWith("http:") ||
7810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                inUrl.startsWith("https:")) {
7820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (inUrl.startsWith("http:/") || inUrl.startsWith("https:/")) {
7830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                inUrl = inUrl.replaceFirst("/", "//");
7840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } else inUrl = inUrl.replaceFirst(":", "://");
7850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
7860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return inUrl;
7870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
7880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
78922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    @Override
79022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    protected void onResume() {
7910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        super.onResume();
79231a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort        if (LOGV_ENABLED) {
7930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Log.v(LOGTAG, "BrowserActivity.onResume: this=" + this);
7940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
7950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
7960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (!mActivityInPause) {
7970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Log.e(LOGTAG, "BrowserActivity is already resumed.");
7980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
7990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
8000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
8017bfa63b55644fbf2da1fe6a24b3be0267529202cMike Reed        mTabControl.resumeCurrentTab();
8020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mActivityInPause = false;
8037bfa63b55644fbf2da1fe6a24b3be0267529202cMike Reed        resumeWebViewTimers();
8040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
8050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mWakeLock.isHeld()) {
8060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mHandler.removeMessages(RELEASE_WAKELOCK);
8070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mWakeLock.release();
8080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
8090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
8100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mCredsDlg != null) {
8110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (!mHandler.hasMessages(CANCEL_CREDS_REQUEST)) {
8120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project             // In case credential request never comes back
8130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mHandler.sendEmptyMessageDelayed(CANCEL_CREDS_REQUEST, 6000);
8140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
8150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
8160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
8170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        registerReceiver(mNetworkStateIntentReceiver,
8180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                         mNetworkStateChangedFilter);
8190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebView.enablePlatformNotifications();
8200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
8210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
8223bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    /**
8233bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     * Since the actual title bar is embedded in the WebView, and removing it
824fe87bd3a3897e4bad65bb3d284659ae2f4e57570Leon Scroggins     * would change its appearance, use a different TitleBar to show overlayed
825fe87bd3a3897e4bad65bb3d284659ae2f4e57570Leon Scroggins     * at the top of the screen, when the menu is open or the page is loading.
8263bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     */
8273bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    private TitleBar mFakeTitleBar;
8283bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins
8293bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    /**
830d8fd2fcf4eb037fd65ae923c6dbeff6c6ecb4d4fLeon Scroggins     * Holder for the fake title bar.  It will have a foreground shadow, as well
831d8fd2fcf4eb037fd65ae923c6dbeff6c6ecb4d4fLeon Scroggins     * as a white background, so the fake title bar looks like the real one.
832d8fd2fcf4eb037fd65ae923c6dbeff6c6ecb4d4fLeon Scroggins     */
833d8fd2fcf4eb037fd65ae923c6dbeff6c6ecb4d4fLeon Scroggins    private ViewGroup mFakeTitleBarHolder;
834d8fd2fcf4eb037fd65ae923c6dbeff6c6ecb4d4fLeon Scroggins
835d8fd2fcf4eb037fd65ae923c6dbeff6c6ecb4d4fLeon Scroggins    /**
836d8fd2fcf4eb037fd65ae923c6dbeff6c6ecb4d4fLeon Scroggins     * Layout parameters for the fake title bar within mFakeTitleBarHolder
837d8fd2fcf4eb037fd65ae923c6dbeff6c6ecb4d4fLeon Scroggins     */
838d8fd2fcf4eb037fd65ae923c6dbeff6c6ecb4d4fLeon Scroggins    private FrameLayout.LayoutParams mFakeTitleBarParams
839d8fd2fcf4eb037fd65ae923c6dbeff6c6ecb4d4fLeon Scroggins            = new FrameLayout.LayoutParams(
84015b8ec6b226f4d57307716e1f495e10a91f8cbf4Romain Guy            ViewGroup.LayoutParams.MATCH_PARENT,
841d8fd2fcf4eb037fd65ae923c6dbeff6c6ecb4d4fLeon Scroggins            ViewGroup.LayoutParams.WRAP_CONTENT);
842d8fd2fcf4eb037fd65ae923c6dbeff6c6ecb4d4fLeon Scroggins    /**
8433bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     * Keeps track of whether the options menu is open.  This is important in
8443bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     * determining whether to show or hide the title bar overlay.
8453bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     */
8463bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    private boolean mOptionsMenuOpen;
8473bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins
8483bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    /**
8493bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     * Only meaningful when mOptionsMenuOpen is true.  This variable keeps track
8503bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     * of whether the configuration has changed.  The first onMenuOpened call
8513bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     * after a configuration change is simply a reopening of the same menu
8523bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     * (i.e. mIconView did not change).
8533bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     */
8543bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    private boolean mConfigChanged;
8553bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins
8563bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    /**
8573bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     * Whether or not the options menu is in its smaller, icon menu form.  When
8583bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     * true, we want the title bar overlay to be up.  When false, we do not.
8593bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     * Only meaningful if mOptionsMenuOpen is true.
8603bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     */
8613bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    private boolean mIconView;
8623bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins
863a81a764063d2f849fba0cbc3039f86e67c2960ddLeon Scroggins    @Override
864a81a764063d2f849fba0cbc3039f86e67c2960ddLeon Scroggins    public boolean onMenuOpened(int featureId, Menu menu) {
8653bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins        if (Window.FEATURE_OPTIONS_PANEL == featureId) {
8663bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins            if (mOptionsMenuOpen) {
8673bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                if (mConfigChanged) {
8683bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                    // We do not need to make any changes to the state of the
8693bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                    // title bar, since the only thing that happened was a
8703bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                    // change in orientation
8713bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                    mConfigChanged = false;
8723bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                } else {
8733bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                    if (mIconView) {
8743bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                        // Switching the menu to expanded view, so hide the
8753bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                        // title bar.
8763bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                        hideFakeTitleBar();
8773bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                        mIconView = false;
8783bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                    } else {
8793bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                        // Switching the menu back to icon view, so show the
8803bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                        // title bar once again.
8813bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                        showFakeTitleBar();
8823bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                        mIconView = true;
8833bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                    }
8843bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                }
8853bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins            } else {
8863bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                // The options menu is closed, so open it, and show the title
8873bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                showFakeTitleBar();
8883bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                mOptionsMenuOpen = true;
8893bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                mConfigChanged = false;
8903bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                mIconView = true;
8913bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins            }
8923bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins        }
893a81a764063d2f849fba0cbc3039f86e67c2960ddLeon Scroggins        return true;
894a81a764063d2f849fba0cbc3039f86e67c2960ddLeon Scroggins    }
895a81a764063d2f849fba0cbc3039f86e67c2960ddLeon Scroggins
896b94bf27370329abb27e5e33b493d6edb5662b36eLeon Scroggins    /**
897b94bf27370329abb27e5e33b493d6edb5662b36eLeon Scroggins     * Special class used exclusively for the shadow drawn underneath the fake
898b94bf27370329abb27e5e33b493d6edb5662b36eLeon Scroggins     * title bar.  The shadow does not need to be drawn if the WebView
899b94bf27370329abb27e5e33b493d6edb5662b36eLeon Scroggins     * underneath is scrolled to the top, because it will draw directly on top
900b94bf27370329abb27e5e33b493d6edb5662b36eLeon Scroggins     * of the embedded shadow.
901b94bf27370329abb27e5e33b493d6edb5662b36eLeon Scroggins     */
902b94bf27370329abb27e5e33b493d6edb5662b36eLeon Scroggins    private static class Shadow extends View {
903b94bf27370329abb27e5e33b493d6edb5662b36eLeon Scroggins        private WebView mWebView;
904b94bf27370329abb27e5e33b493d6edb5662b36eLeon Scroggins
905b94bf27370329abb27e5e33b493d6edb5662b36eLeon Scroggins        public Shadow(Context context, AttributeSet attrs) {
906b94bf27370329abb27e5e33b493d6edb5662b36eLeon Scroggins            super(context, attrs);
907b94bf27370329abb27e5e33b493d6edb5662b36eLeon Scroggins        }
908b94bf27370329abb27e5e33b493d6edb5662b36eLeon Scroggins
909b94bf27370329abb27e5e33b493d6edb5662b36eLeon Scroggins        public void setWebView(WebView view) {
910b94bf27370329abb27e5e33b493d6edb5662b36eLeon Scroggins            mWebView = view;
911b94bf27370329abb27e5e33b493d6edb5662b36eLeon Scroggins        }
912b94bf27370329abb27e5e33b493d6edb5662b36eLeon Scroggins
913b94bf27370329abb27e5e33b493d6edb5662b36eLeon Scroggins        @Override
914b94bf27370329abb27e5e33b493d6edb5662b36eLeon Scroggins        public void draw(Canvas canvas) {
915b94bf27370329abb27e5e33b493d6edb5662b36eLeon Scroggins            // In general onDraw is the method to override, but we care about
916b94bf27370329abb27e5e33b493d6edb5662b36eLeon Scroggins            // whether or not the background gets drawn, which happens in draw()
917b94bf27370329abb27e5e33b493d6edb5662b36eLeon Scroggins            if (mWebView == null || mWebView.getScrollY() > getHeight()) {
918b94bf27370329abb27e5e33b493d6edb5662b36eLeon Scroggins                super.draw(canvas);
919b94bf27370329abb27e5e33b493d6edb5662b36eLeon Scroggins            }
920b94bf27370329abb27e5e33b493d6edb5662b36eLeon Scroggins            // Need to invalidate so that if the scroll position changes, we
921b94bf27370329abb27e5e33b493d6edb5662b36eLeon Scroggins            // still draw as appropriate.
922b94bf27370329abb27e5e33b493d6edb5662b36eLeon Scroggins            invalidate();
923b94bf27370329abb27e5e33b493d6edb5662b36eLeon Scroggins        }
924b94bf27370329abb27e5e33b493d6edb5662b36eLeon Scroggins    }
925b94bf27370329abb27e5e33b493d6edb5662b36eLeon Scroggins
9263bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    private void showFakeTitleBar() {
927f8de8ecc321fe5b45846adc38d174d5bc2208f20Patrick Scott        final View decor = getWindow().peekDecorView();
928fe87bd3a3897e4bad65bb3d284659ae2f4e57570Leon Scroggins        if (mFakeTitleBar.getParent() == null && mActiveTabsPage == null
929f8de8ecc321fe5b45846adc38d174d5bc2208f20Patrick Scott                && !mActivityInPause && decor != null
930f8de8ecc321fe5b45846adc38d174d5bc2208f20Patrick Scott                && decor.getWindowToken() != null) {
931a04645545690d9f637ccae4d043a5a1b8478a832Cary Clark            Rect visRect = new Rect();
932a04645545690d9f637ccae4d043a5a1b8478a832Cary Clark            if (!mBrowserFrameLayout.getGlobalVisibleRect(visRect)) {
933a04645545690d9f637ccae4d043a5a1b8478a832Cary Clark                if (LOGD_ENABLED) {
934a04645545690d9f637ccae4d043a5a1b8478a832Cary Clark                    Log.d(LOGTAG, "showFakeTitleBar visRect failed");
935a04645545690d9f637ccae4d043a5a1b8478a832Cary Clark                }
936a04645545690d9f637ccae4d043a5a1b8478a832Cary Clark                return;
937a04645545690d9f637ccae4d043a5a1b8478a832Cary Clark            }
9383bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins
9393bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins            WindowManager manager
9403bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                    = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
9413bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins
9423bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins            // Add the title bar to the window manager so it can receive touches
9433bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins            // while the menu is up
9443bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins            WindowManager.LayoutParams params
9453bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                    = new WindowManager.LayoutParams(
94615b8ec6b226f4d57307716e1f495e10a91f8cbf4Romain Guy                    ViewGroup.LayoutParams.MATCH_PARENT,
9473bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                    ViewGroup.LayoutParams.WRAP_CONTENT,
9483bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                    WindowManager.LayoutParams.TYPE_APPLICATION_SUB_PANEL,
9493bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                    WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
950685498685d8424f48d77d26d8d5790da34645f44Leon Scroggins                    PixelFormat.TRANSLUCENT);
9513bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins            params.gravity = Gravity.TOP;
952a27ff19e24cb1c9fef5624dbc4554548349b5b31Leon Scroggins            WebView mainView = mTabControl.getCurrentWebView();
953685498685d8424f48d77d26d8d5790da34645f44Leon Scroggins            boolean atTop = mainView != null && mainView.getScrollY() == 0;
95483932c74ba031eb2f581f1557c1a90f4b5bbb423Leon Scroggins            params.windowAnimations = atTop ? 0 : R.style.TitleBar;
9553bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins            // XXX : Without providing an offset, the fake title bar will be
9563bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins            // placed underneath the status bar.  Use the global visible rect
9573bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins            // of mBrowserFrameLayout to determine the bottom of the status bar
958a04645545690d9f637ccae4d043a5a1b8478a832Cary Clark            params.y = visRect.top;
959685498685d8424f48d77d26d8d5790da34645f44Leon Scroggins            // Add a holder for the title bar.  It also holds a shadow to show
960685498685d8424f48d77d26d8d5790da34645f44Leon Scroggins            // below the title bar.
961d8fd2fcf4eb037fd65ae923c6dbeff6c6ecb4d4fLeon Scroggins            if (mFakeTitleBarHolder == null) {
962d8fd2fcf4eb037fd65ae923c6dbeff6c6ecb4d4fLeon Scroggins                mFakeTitleBarHolder = (ViewGroup) LayoutInflater.from(this)
963d8fd2fcf4eb037fd65ae923c6dbeff6c6ecb4d4fLeon Scroggins                    .inflate(R.layout.title_bar_bg, null);
964d8fd2fcf4eb037fd65ae923c6dbeff6c6ecb4d4fLeon Scroggins            }
965b94bf27370329abb27e5e33b493d6edb5662b36eLeon Scroggins            Shadow shadow = (Shadow) mFakeTitleBarHolder.findViewById(
966b94bf27370329abb27e5e33b493d6edb5662b36eLeon Scroggins                    R.id.shadow);
967b94bf27370329abb27e5e33b493d6edb5662b36eLeon Scroggins            shadow.setWebView(mainView);
968685498685d8424f48d77d26d8d5790da34645f44Leon Scroggins            mFakeTitleBarHolder.addView(mFakeTitleBar, 0, mFakeTitleBarParams);
969d8fd2fcf4eb037fd65ae923c6dbeff6c6ecb4d4fLeon Scroggins            manager.addView(mFakeTitleBarHolder, params);
9703bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins        }
9713bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    }
9723bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins
9733bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    @Override
9743bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    public void onOptionsMenuClosed(Menu menu) {
9753bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins        mOptionsMenuOpen = false;
976a27ff19e24cb1c9fef5624dbc4554548349b5b31Leon Scroggins        if (!mInLoad) {
977a27ff19e24cb1c9fef5624dbc4554548349b5b31Leon Scroggins            hideFakeTitleBar();
978a27ff19e24cb1c9fef5624dbc4554548349b5b31Leon Scroggins        } else if (!mIconView) {
979a27ff19e24cb1c9fef5624dbc4554548349b5b31Leon Scroggins            // The page is currently loading, and we are in expanded mode, so
980a27ff19e24cb1c9fef5624dbc4554548349b5b31Leon Scroggins            // we were not showing the menu.  Show it once again.  It will be
981a27ff19e24cb1c9fef5624dbc4554548349b5b31Leon Scroggins            // removed when the page finishes.
982a27ff19e24cb1c9fef5624dbc4554548349b5b31Leon Scroggins            showFakeTitleBar();
983a27ff19e24cb1c9fef5624dbc4554548349b5b31Leon Scroggins        }
9843bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    }
98522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
9863bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    private void hideFakeTitleBar() {
987fe87bd3a3897e4bad65bb3d284659ae2f4e57570Leon Scroggins        if (mFakeTitleBar.getParent() == null) return;
98820329570ba9409637298da90b83f25801d7a3d55Leon Scroggins        WindowManager.LayoutParams params = (WindowManager.LayoutParams)
98920329570ba9409637298da90b83f25801d7a3d55Leon Scroggins                mFakeTitleBarHolder.getLayoutParams();
99020329570ba9409637298da90b83f25801d7a3d55Leon Scroggins        WebView mainView = mTabControl.getCurrentWebView();
99120329570ba9409637298da90b83f25801d7a3d55Leon Scroggins        // Although we decided whether or not to animate based on the current
99220329570ba9409637298da90b83f25801d7a3d55Leon Scroggins        // scroll position, the scroll position may have changed since the
99320329570ba9409637298da90b83f25801d7a3d55Leon Scroggins        // fake title bar was displayed.  Make sure it has the appropriate
99420329570ba9409637298da90b83f25801d7a3d55Leon Scroggins        // animation/lack thereof before removing.
99520329570ba9409637298da90b83f25801d7a3d55Leon Scroggins        params.windowAnimations = mainView != null && mainView.getScrollY() == 0
99683932c74ba031eb2f581f1557c1a90f4b5bbb423Leon Scroggins                ? 0 : R.style.TitleBar;
9973bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins        WindowManager manager
9983bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                    = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
99920329570ba9409637298da90b83f25801d7a3d55Leon Scroggins        manager.updateViewLayout(mFakeTitleBarHolder, params);
1000d8fd2fcf4eb037fd65ae923c6dbeff6c6ecb4d4fLeon Scroggins        mFakeTitleBarHolder.removeView(mFakeTitleBar);
1001d8fd2fcf4eb037fd65ae923c6dbeff6c6ecb4d4fLeon Scroggins        manager.removeView(mFakeTitleBarHolder);
10023bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    }
10033bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins
10040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
1005c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins     * Special method for the fake title bar to call when displaying its context
1006c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins     * menu, since it is in its own Window, and its parent does not show a
1007c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins     * context menu.
1008c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins     */
1009c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins    /* package */ void showTitleBarContextMenu() {
101065f4a3ce9e5c4a5227bbcbb995e5e15f1f85d3d7Cary Clark        if (null == mTitleBar.getParent()) {
101165f4a3ce9e5c4a5227bbcbb995e5e15f1f85d3d7Cary Clark            return;
101265f4a3ce9e5c4a5227bbcbb995e5e15f1f85d3d7Cary Clark        }
1013c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins        openContextMenu(mTitleBar);
1014c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins    }
1015c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins
1016b2b19f501ee05448ca81bddaaca70e9b2f51cb54Leon Scroggins    @Override
1017b2b19f501ee05448ca81bddaaca70e9b2f51cb54Leon Scroggins    public void onContextMenuClosed(Menu menu) {
1018b2b19f501ee05448ca81bddaaca70e9b2f51cb54Leon Scroggins        super.onContextMenuClosed(menu);
1019b2b19f501ee05448ca81bddaaca70e9b2f51cb54Leon Scroggins        if (mInLoad) {
1020b2b19f501ee05448ca81bddaaca70e9b2f51cb54Leon Scroggins            showFakeTitleBar();
1021b2b19f501ee05448ca81bddaaca70e9b2f51cb54Leon Scroggins        }
1022b2b19f501ee05448ca81bddaaca70e9b2f51cb54Leon Scroggins    }
1023b2b19f501ee05448ca81bddaaca70e9b2f51cb54Leon Scroggins
1024c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins    /**
10250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *  onSaveInstanceState(Bundle map)
10260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *  onSaveInstanceState is called right before onStop(). The map contains
10270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *  the saved state.
10280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
102922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    @Override
103022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    protected void onSaveInstanceState(Bundle outState) {
103131a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort        if (LOGV_ENABLED) {
10320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Log.v(LOGTAG, "BrowserActivity.onSaveInstanceState: this=" + this);
10330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
10340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // the default implementation requires each view to have an id. As the
10350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // browser handles the state itself and it doesn't use id for the views,
10360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // don't call the default implementation. Otherwise it will trigger the
10370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // warning like this, "couldn't save which view has focus because the
10380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // focused view XXX has no id".
10390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
10400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Save all the tabs
10410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mTabControl.saveState(outState);
10420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
10430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
104422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    @Override
104522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    protected void onPause() {
10460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        super.onPause();
10470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
10480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mActivityInPause) {
10490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Log.e(LOGTAG, "BrowserActivity is already paused.");
10500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
10510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
10520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
10537bfa63b55644fbf2da1fe6a24b3be0267529202cMike Reed        mTabControl.pauseCurrentTab();
10540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mActivityInPause = true;
10557bfa63b55644fbf2da1fe6a24b3be0267529202cMike Reed        if (mTabControl.getCurrentIndex() >= 0 && !pauseWebViewTimers()) {
10560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mWakeLock.acquire();
10570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mHandler.sendMessageDelayed(mHandler
10580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    .obtainMessage(RELEASE_WAKELOCK), WAKELOCK_TIMEOUT);
10590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
10600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
10610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Clear the credentials toast if it is up
10620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mCredsDlg != null && mCredsDlg.isShowing()) {
10630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mCredsDlg.dismiss();
10640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
10650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mCredsDlg = null;
10660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
1067a2ab6a7dc0f7023c1d7ebb1cbad397c5dc3d6453Leon Scroggins        // FIXME: This removes the active tabs page and resets the menu to
1068a2ab6a7dc0f7023c1d7ebb1cbad397c5dc3d6453Leon Scroggins        // MAIN_MENU.  A better solution might be to do this work in onNewIntent
1069a2ab6a7dc0f7023c1d7ebb1cbad397c5dc3d6453Leon Scroggins        // but then we would need to save it in onSaveInstanceState and restore
1070a2ab6a7dc0f7023c1d7ebb1cbad397c5dc3d6453Leon Scroggins        // it in onCreate/onRestoreInstanceState
1071a2ab6a7dc0f7023c1d7ebb1cbad397c5dc3d6453Leon Scroggins        if (mActiveTabsPage != null) {
1072a2ab6a7dc0f7023c1d7ebb1cbad397c5dc3d6453Leon Scroggins            removeActiveTabPage(true);
1073a2ab6a7dc0f7023c1d7ebb1cbad397c5dc3d6453Leon Scroggins        }
1074a2ab6a7dc0f7023c1d7ebb1cbad397c5dc3d6453Leon Scroggins
10750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        cancelStopToast();
10760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
10770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // unregister network state listener
10780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        unregisterReceiver(mNetworkStateIntentReceiver);
10790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebView.disablePlatformNotifications();
10800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
10810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
108222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    @Override
108322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    protected void onDestroy() {
108431a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort        if (LOGV_ENABLED) {
10850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Log.v(LOGTAG, "BrowserActivity.onDestroy: this=" + this);
10860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
10870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        super.onDestroy();
10880923d69a8ca45222cabd82a80eaa88da9f132e9aGrace Kloba
10898d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins        if (mUploadMessage != null) {
10908d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins            mUploadMessage.onReceiveValue(null);
10918d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins            mUploadMessage = null;
10928d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins        }
10938d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins
10940923d69a8ca45222cabd82a80eaa88da9f132e9aGrace Kloba        if (mTabControl == null) return;
10950923d69a8ca45222cabd82a80eaa88da9f132e9aGrace Kloba
10961fc98a322e9df6b0e797c26de6b2cb23d69ad5d3Grace Kloba        // Remove the fake title bar if it is there
10971fc98a322e9df6b0e797c26de6b2cb23d69ad5d3Grace Kloba        hideFakeTitleBar();
10981fc98a322e9df6b0e797c26de6b2cb23d69ad5d3Grace Kloba
10990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Remove the current tab and sub window
110022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        Tab t = mTabControl.getCurrentTab();
1101fb5e77fac7b8b311fe72827183f8988f5ee92a5fPatrick Scott        if (t != null) {
1102fb5e77fac7b8b311fe72827183f8988f5ee92a5fPatrick Scott            dismissSubWindow(t);
1103fb5e77fac7b8b311fe72827183f8988f5ee92a5fPatrick Scott            removeTabFromContentView(t);
1104fb5e77fac7b8b311fe72827183f8988f5ee92a5fPatrick Scott        }
11050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Destroy all the tabs
11060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mTabControl.destroy();
11070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebIconDatabase.getInstance().close();
11080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
1109b4da0ad0351996f639b50f9f29b123a9b5c24fd0Grace Kloba        unregisterReceiver(mPackageInstallationReceiver);
11100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
11110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
11120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    @Override
11130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public void onConfigurationChanged(Configuration newConfig) {
11143bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins        mConfigChanged = true;
11150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        super.onConfigurationChanged(newConfig);
11160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
11170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mPageInfoDialog != null) {
11180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mPageInfoDialog.dismiss();
11190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            showPageInfo(
11200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mPageInfoView,
1121c7b92f811dfa3572578ddc6714c98a03936d9ce5Leon Scroggins                mPageInfoFromShowSSLCertificateOnError);
11220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
11230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mSSLCertificateDialog != null) {
11240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mSSLCertificateDialog.dismiss();
11250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            showSSLCertificate(
11260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mSSLCertificateView);
11270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
11280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mSSLCertificateOnErrorDialog != null) {
11290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mSSLCertificateOnErrorDialog.dismiss();
11300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            showSSLCertificateOnError(
11310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mSSLCertificateOnErrorView,
11320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mSSLCertificateOnErrorHandler,
11330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mSSLCertificateOnErrorError);
11340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
11350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mHttpAuthenticationDialog != null) {
11360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            String title = ((TextView) mHttpAuthenticationDialog
11370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    .findViewById(com.android.internal.R.id.alertTitle)).getText()
11380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    .toString();
11390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            String name = ((TextView) mHttpAuthenticationDialog
11400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    .findViewById(R.id.username_edit)).getText().toString();
11410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            String password = ((TextView) mHttpAuthenticationDialog
11420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    .findViewById(R.id.password_edit)).getText().toString();
11430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            int focusId = mHttpAuthenticationDialog.getCurrentFocus()
11440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    .getId();
11450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mHttpAuthenticationDialog.dismiss();
11460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            showHttpAuthentication(mHttpAuthHandler, null, null, title,
11470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    name, password, focusId);
11480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
11490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
11500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
115122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    @Override
115222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    public void onLowMemory() {
11530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        super.onLowMemory();
11540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mTabControl.freeMemory();
11550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
11560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
11577bfa63b55644fbf2da1fe6a24b3be0267529202cMike Reed    private boolean resumeWebViewTimers() {
115822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        Tab tab = mTabControl.getCurrentTab();
115922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        boolean inLoad = tab.inLoad();
116022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if ((!mActivityInPause && !inLoad) || (mActivityInPause && inLoad)) {
11610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            CookieSyncManager.getInstance().startSync();
116222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            WebView w = tab.getWebView();
11630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (w != null) {
11640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                w.resumeTimers();
11650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
11660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return true;
11670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
11680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return false;
11690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
11700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
11710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
11727bfa63b55644fbf2da1fe6a24b3be0267529202cMike Reed    private boolean pauseWebViewTimers() {
117322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        Tab tab = mTabControl.getCurrentTab();
117422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        boolean inLoad = tab.inLoad();
117522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mActivityInPause && !inLoad) {
11760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            CookieSyncManager.getInstance().stopSync();
11770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            WebView w = mTabControl.getCurrentWebView();
11780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (w != null) {
11790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                w.pauseTimers();
11800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
11810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return true;
11820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
11830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return false;
11840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
11850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
11860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
11871f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins    // FIXME: Do we want to call this when loading google for the first time?
11880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /*
11890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * This function is called when we are launching for the first time. We
11900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * are waiting for the login credentials before loading Google home
11910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * pages. This way the user will be logged in straight away.
11920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
11930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void waitForCredentials() {
11940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Show a toast
11950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mCredsDlg = new ProgressDialog(this);
11960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mCredsDlg.setIndeterminate(true);
11970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mCredsDlg.setMessage(getText(R.string.retrieving_creds_dlg_msg));
11980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // If the user cancels the operation, then cancel the Google
11990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Credentials request.
12000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mCredsDlg.setCancelMessage(mHandler.obtainMessage(CANCEL_CREDS_REQUEST));
12010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mCredsDlg.show();
12020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
12030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // We set a timeout for the retrieval of credentials in onResume()
12040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // as that is when we have freed up some CPU time to get
12050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // the login credentials.
12060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
12070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
12080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /*
12090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * If we have received the credentials or we have timed out and we are
12100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * showing the credentials dialog, then it is time to move on.
12110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
12120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void resumeAfterCredentials() {
12130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mCredsDlg == null) {
12140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
12150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
12160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
12170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Clear the toast
12180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mCredsDlg.isShowing()) {
12190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mCredsDlg.dismiss();
12200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
12210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mCredsDlg = null;
12220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
12230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Clear any pending timeout
12240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mHandler.removeMessages(CANCEL_CREDS_REQUEST);
12250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
12260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Load the page
12270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebView w = mTabControl.getCurrentWebView();
12280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (w != null) {
12290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            w.loadUrl(mSettings.getHomePage());
12300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
12310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
12320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Update the settings, need to do this last as it can take a moment
12330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // to persist the settings. In the mean time we could be loading
12340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // content.
12350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mSettings.setLoginInitialized(this);
12360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
12370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
12380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Open the icon database and retain all the icons for visited sites.
12390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void retainIconsOnStartup() {
12400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final WebIconDatabase db = WebIconDatabase.getInstance();
12410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        db.open(getDir("icons", 0).getPath());
12420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        try {
12430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Cursor c = Browser.getAllBookmarks(mResolver);
12440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (!c.moveToFirst()) {
12450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                c.deactivate();
12460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                return;
12470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
12480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            int urlIndex = c.getColumnIndex(Browser.BookmarkColumns.URL);
12490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            do {
12500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                String url = c.getString(urlIndex);
12510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                db.retainIconForPageUrl(url);
12520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } while (c.moveToNext());
12530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            c.deactivate();
12540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } catch (IllegalStateException e) {
12550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Log.e(LOGTAG, "retainIconsOnStartup", e);
12560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
12570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
12580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
12590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Helper method for getting the top window.
12600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    WebView getTopWindow() {
12610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return mTabControl.getCurrentTopWebView();
12620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
12630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
126422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    TabControl getTabControl() {
126522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return mTabControl;
126622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
126722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
12680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    @Override
12690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public boolean onCreateOptionsMenu(Menu menu) {
12700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        super.onCreateOptionsMenu(menu);
12710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
12720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        MenuInflater inflater = getMenuInflater();
12730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        inflater.inflate(R.menu.browser, menu);
12740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mMenu = menu;
12750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        updateInLoadMenuItems();
12760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return true;
12770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
12780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
12790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
12800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * As the menu can be open when loading state changes
12810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * we must manually update the state of the stop/reload menu
12820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * item
12830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
12840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void updateInLoadMenuItems() {
12850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mMenu == null) {
12860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
12870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
12880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        MenuItem src = mInLoad ?
12890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mMenu.findItem(R.id.stop_menu_id):
12900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    mMenu.findItem(R.id.reload_menu_id);
12910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        MenuItem dest = mMenu.findItem(R.id.stop_reload_menu_id);
12920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        dest.setIcon(src.getIcon());
12930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        dest.setTitle(src.getTitle());
12940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
12950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
12960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    @Override
12970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public boolean onContextItemSelected(MenuItem item) {
12980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // chording is not an issue with context menus, but we use the same
12990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // options selector, so set mCanChord to true so we can access them.
13000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mCanChord = true;
13010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        int id = item.getItemId();
130296afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins        boolean result = true;
13030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        switch (id) {
1304c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins            // For the context menu from the title bar
1305c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins            case R.id.title_bar_copy_page_url:
130696afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                Tab currentTab = mTabControl.getCurrentTab();
130796afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                if (null == currentTab) {
130896afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                    result = false;
130996afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                    break;
1310c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins                }
131196afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                WebView mainView = currentTab.getWebView();
131296afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                if (null == mainView) {
131396afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                    result = false;
131496afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                    break;
1315c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins                }
131696afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                copy(mainView.getUrl());
1317c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins                break;
13180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // -- Browser context menu
13190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.open_context_menu_id:
13200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.open_newtab_context_menu_id:
13210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.bookmark_context_menu_id:
13220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.save_link_context_menu_id:
13230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.share_link_context_menu_id:
13240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.copy_link_context_menu_id:
1325c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins                final WebView webView = getTopWindow();
1326c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins                if (null == webView) {
132796afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                    result = false;
132896afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                    break;
1329c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins                }
1330c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins                final HashMap hrefMap = new HashMap();
1331c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins                hrefMap.put("webview", webView);
1332c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins                final Message msg = mHandler.obtainMessage(
1333c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins                        FOCUS_NODE_HREF, id, 0, hrefMap);
13340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                webView.requestFocusNodeHref(msg);
13350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
13360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
13370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            default:
13380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // For other context menus
133996afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                result = onOptionsItemSelected(item);
13400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
13410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mCanChord = false;
134296afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins        return result;
13430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
13440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
13450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private Bundle createGoogleSearchSourceBundle(String source) {
13460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        Bundle bundle = new Bundle();
134710d1cca0c208d1f9db23893a8515685e04cfe224Bjorn Bringert        bundle.putString(Search.SOURCE, source);
13480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return bundle;
13490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
13500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
13510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
13524e5f58704099c37186d4825c3d55ea5b0527867fThe Android Open Source Project     * Overriding this to insert a local information bundle
13530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
13540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    @Override
13550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public boolean onSearchRequested() {
135668579393973f745fc65a2781061af9bb8f2d7020Leon Scroggins        if (mOptionsMenuOpen) closeOptionsMenu();
13575bbe98025a2c606a35c91b826760020890daadb1Leon Scroggins        String url = (getTopWindow() == null) ? null : getTopWindow().getUrl();
135883f473462fcd7869031a423c02b957c6e938a2f6Grace Kloba        startSearch(mSettings.getHomePage().equals(url) ? null : url, true,
13594e5f58704099c37186d4825c3d55ea5b0527867fThe Android Open Source Project                createGoogleSearchSourceBundle(GOOGLE_SEARCH_SOURCE_SEARCHKEY), false);
13600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return true;
13610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
13620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
13630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    @Override
13640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public void startSearch(String initialQuery, boolean selectInitialQuery,
13650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Bundle appSearchData, boolean globalSearch) {
13660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (appSearchData == null) {
13670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            appSearchData = createGoogleSearchSourceBundle(GOOGLE_SEARCH_SOURCE_TYPE);
13680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
13690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        super.startSearch(initialQuery, selectInitialQuery, appSearchData, globalSearch);
13700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
13710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
13721f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins    /**
13731f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins     * Switch tabs.  Called by the TitleBarSet when sliding the title bar
13741f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins     * results in changing tabs.
1375160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins     * @param index Index of the tab to change to, as defined by
1376160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins     *              mTabControl.getTabIndex(Tab t).
1377160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins     * @return boolean True if we successfully switched to a different tab.  If
1378160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins     *                 the indexth tab is null, or if that tab is the same as
1379160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins     *                 the current one, return false.
13801f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins     */
1381160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins    /* package */ boolean switchToTab(int index) {
138222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        Tab tab = mTabControl.getTab(index);
138322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        Tab currentTab = mTabControl.getCurrentTab();
13841f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins        if (tab == null || tab == currentTab) {
1385160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins            return false;
13861f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins        }
13871f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins        if (currentTab != null) {
13881f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins            // currentTab may be null if it was just removed.  In that case,
13891f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins            // we do not need to remove it
13901f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins            removeTabFromContentView(currentTab);
13911f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins        }
13921f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins        mTabControl.setCurrentTab(tab);
13931f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins        attachTabToContentView(tab);
1394eb6eef4c45df2d65c3e70660493a147a2be405e3Grace Kloba        resetTitleIconAndProgress();
1395eb6eef4c45df2d65c3e70660493a147a2be405e3Grace Kloba        updateLockIconToLatest();
1396160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins        return true;
13971f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins    }
13981f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins
139922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /* package */ Tab openTabToHomePage() {
14000a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins        return openTabAndShow(mSettings.getHomePage(), false, null);
14010a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins    }
14020a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins
14031f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins    /* package */ void closeCurrentWindow() {
140422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        final Tab current = mTabControl.getCurrentTab();
1405160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins        if (mTabControl.getTabCount() == 1) {
1406304442375719effd41dbd53ae62de7a8d0cec7d9Leon Scroggins            // This is the last tab.  Open a new one, with the home
1407304442375719effd41dbd53ae62de7a8d0cec7d9Leon Scroggins            // page and close the current one.
140822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            openTabToHomePage();
1409160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins            closeTab(current);
1410160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins            return;
1411160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins        }
141222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        final Tab parent = current.getParentTab();
14131f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins        int indexToShow = -1;
14141f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins        if (parent != null) {
14151f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins            indexToShow = mTabControl.getTabIndex(parent);
14161f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins        } else {
1417160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins            final int currentIndex = mTabControl.getCurrentIndex();
1418160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins            // Try to move to the tab to the right
1419160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins            indexToShow = currentIndex + 1;
1420160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins            if (indexToShow > mTabControl.getTabCount() - 1) {
1421160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins                // Try to move to the tab to the left
1422160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins                indexToShow = currentIndex - 1;
14231f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins            }
14241f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins        }
1425160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins        if (switchToTab(indexToShow)) {
1426160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins            // Close window
1427160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins            closeTab(current);
1428160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins        }
14291f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins    }
14301f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins
14310a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins    private ActiveTabsPage mActiveTabsPage;
14320a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins
14330a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins    /**
14340a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins     * Remove the active tabs page.
14350a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins     * @param needToAttach If true, the active tabs page did not attach a tab
14360a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins     *                     to the content view, so we need to do that here.
14370a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins     */
14380a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins    /* package */ void removeActiveTabPage(boolean needToAttach) {
14390a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins        mContentView.removeView(mActiveTabsPage);
14400a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins        mActiveTabsPage = null;
14410a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins        mMenuState = R.id.MAIN_MENU;
14420a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins        if (needToAttach) {
14430a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins            attachTabToContentView(mTabControl.getCurrentTab());
14440a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins        }
14450a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins        getTopWindow().requestFocus();
14460a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins    }
14470a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins
14480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    @Override
14490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public boolean onOptionsItemSelected(MenuItem item) {
14500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (!mCanChord) {
14510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // The user has already fired a shortcut with this hold down of the
14520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // menu key.
14530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return false;
14540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
14551f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins        if (null == getTopWindow()) {
14560d7ae0ed82e21d472cde8cf92b5657d8ee8ca0d8Leon Scroggins            return false;
14570d7ae0ed82e21d472cde8cf92b5657d8ee8ca0d8Leon Scroggins        }
14586ee9c498b8cf648f1507281ed5a1834ba3390907Grace Kloba        if (mMenuIsDown) {
14596ee9c498b8cf648f1507281ed5a1834ba3390907Grace Kloba            // The shortcut action consumes the MENU. Even if it is still down,
14606ee9c498b8cf648f1507281ed5a1834ba3390907Grace Kloba            // it won't trigger the next shortcut action. In the case of the
14616ee9c498b8cf648f1507281ed5a1834ba3390907Grace Kloba            // shortcut action triggering a new activity, like Bookmarks, we
14626ee9c498b8cf648f1507281ed5a1834ba3390907Grace Kloba            // won't get onKeyUp for MENU. So it is important to reset it here.
14636ee9c498b8cf648f1507281ed5a1834ba3390907Grace Kloba            mMenuIsDown = false;
14646ee9c498b8cf648f1507281ed5a1834ba3390907Grace Kloba        }
14650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        switch (item.getItemId()) {
14660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // -- Main menu
1467a81a764063d2f849fba0cbc3039f86e67c2960ddLeon Scroggins            case R.id.new_tab_menu_id:
14680a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins                openTabToHomePage();
1469a81a764063d2f849fba0cbc3039f86e67c2960ddLeon Scroggins                break;
1470a81a764063d2f849fba0cbc3039f86e67c2960ddLeon Scroggins
147164b80f3efd95d7b5192731e995ccde79c4c6c11fLeon Scroggins            case R.id.goto_menu_id:
1472b3a5bedeede968b53363a6c517f92bc2484bb42dLeon Scroggins                onSearchRequested();
1473b3a5bedeede968b53363a6c517f92bc2484bb42dLeon Scroggins                break;
1474b3a5bedeede968b53363a6c517f92bc2484bb42dLeon Scroggins
1475b3a5bedeede968b53363a6c517f92bc2484bb42dLeon Scroggins            case R.id.bookmarks_menu_id:
1476304442375719effd41dbd53ae62de7a8d0cec7d9Leon Scroggins                bookmarksOrHistoryPicker(false);
14770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
14780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
14790a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins            case R.id.active_tabs_menu_id:
14800a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins                mActiveTabsPage = new ActiveTabsPage(this, mTabControl);
14810a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins                removeTabFromContentView(mTabControl.getCurrentTab());
148243de61666cfc98a3acc41c7161a1a8b0bdb2b72bLeon Scroggins                hideFakeTitleBar();
14830a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins                mContentView.addView(mActiveTabsPage, COVER_SCREEN_PARAMS);
14840a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins                mActiveTabsPage.requestFocus();
14850a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins                mMenuState = EMPTY_MENU;
14860a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins                break;
14870a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins
14881f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins            case R.id.add_bookmark_menu_id:
14891f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                Intent i = new Intent(BrowserActivity.this,
14901f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                        AddBookmarkPage.class);
14911f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                WebView w = getTopWindow();
14921f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                i.putExtra("url", w.getUrl());
14931f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                i.putExtra("title", w.getTitle());
149483cdb2c40f2dbcbdf522a2af0ec8224c7195c6c1Grace Kloba                i.putExtra("touch_icon_url", w.getTouchIconUrl());
1495dcc2b6f08dd5677bc6ba761a9ba6f1c655113051Ben Murdoch                i.putExtra("thumbnail", createScreenshot(w));
14961f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                startActivity(i);
14970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
14980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
14990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.stop_reload_menu_id:
15000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (mInLoad) {
15010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    stopLoading();
15020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                } else {
15030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    getTopWindow().reload();
15040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
15050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
15060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
15070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.back_menu_id:
15080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                getTopWindow().goBack();
15090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
15100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
15110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.forward_menu_id:
15120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                getTopWindow().goForward();
15130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
15140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
15150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.close_menu_id:
15160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // Close the subwindow if it exists.
15170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (mTabControl.getCurrentSubWindow() != null) {
15180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    dismissSubWindow(mTabControl.getCurrentTab());
15190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    break;
15200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
15211f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                closeCurrentWindow();
15220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
15230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
15240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.homepage_menu_id:
152522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                Tab current = mTabControl.getCurrentTab();
15260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (current != null) {
15270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    dismissSubWindow(current);
15280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    current.getWebView().loadUrl(mSettings.getHomePage());
15290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
15300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
15310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
15320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.preferences_menu_id:
15330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                Intent intent = new Intent(this,
15340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        BrowserPreferencesPage.class);
1535d530494de9c182af4aff97ddd46343b32594da51Leon Scroggins                intent.putExtra(BrowserPreferencesPage.CURRENT_PAGE,
1536d530494de9c182af4aff97ddd46343b32594da51Leon Scroggins                        getTopWindow().getUrl());
15370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                startActivityForResult(intent, PREFERENCES_PAGE);
15380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
15390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
15400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.find_menu_id:
15410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (null == mFindDialog) {
15420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    mFindDialog = new FindDialog(this);
15430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
15440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mFindDialog.setWebView(getTopWindow());
15450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mFindDialog.show();
15460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mMenuState = EMPTY_MENU;
15470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
15480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
15490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.select_text_id:
15500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                getTopWindow().emulateShiftHeld();
15510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
15520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.page_info_menu_id:
15530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                showPageInfo(mTabControl.getCurrentTab(), false);
15540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
15550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
15560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.classic_history_menu_id:
1557304442375719effd41dbd53ae62de7a8d0cec7d9Leon Scroggins                bookmarksOrHistoryPicker(true);
15580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
15590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
156096afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins            case R.id.title_bar_share_page_url:
15610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.share_page_menu_id:
156296afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                Tab currentTab = mTabControl.getCurrentTab();
156396afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                if (null == currentTab) {
156496afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                    mCanChord = false;
156596afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                    return false;
156696afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                }
156796afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                currentTab.populatePickerData();
156896afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                sharePage(this, currentTab.getTitle(),
156996afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                        currentTab.getUrl(), currentTab.getFavicon(),
157096afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                        createScreenshot(currentTab.getWebView()));
15710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
15720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
15730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.dump_nav_menu_id:
15740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                getTopWindow().debugDump();
15750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
15760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
15777a8b88b0e0f20544df5ee34b798398603261b733Andrei Popescu            case R.id.dump_counters_menu_id:
15787a8b88b0e0f20544df5ee34b798398603261b733Andrei Popescu                getTopWindow().dumpV8Counters();
15797a8b88b0e0f20544df5ee34b798398603261b733Andrei Popescu                break;
15807a8b88b0e0f20544df5ee34b798398603261b733Andrei Popescu
15810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.zoom_in_menu_id:
15820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                getTopWindow().zoomIn();
15830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
15840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
15850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.zoom_out_menu_id:
15860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                getTopWindow().zoomOut();
15870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
15880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
15890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.view_downloads_menu_id:
15900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                viewDownloads(null);
15910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
15920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
15930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.window_one_menu_id:
15940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.window_two_menu_id:
15950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.window_three_menu_id:
15960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.window_four_menu_id:
15970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.window_five_menu_id:
15980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.window_six_menu_id:
15990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.window_seven_menu_id:
16000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.window_eight_menu_id:
16010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                {
16020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    int menuid = item.getItemId();
16030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    for (int id = 0; id < WINDOW_SHORTCUT_ID_ARRAY.length; id++) {
16040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        if (WINDOW_SHORTCUT_ID_ARRAY[id] == menuid) {
160522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            Tab desiredTab = mTabControl.getTab(id);
16060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            if (desiredTab != null &&
16070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    desiredTab != mTabControl.getCurrentTab()) {
16081f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                                switchToTab(id);
16090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            }
16100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            break;
16110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }
16120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
16130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
16140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
16150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
16160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            default:
16170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (!super.onOptionsItemSelected(item)) {
16180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    return false;
16190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
16200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // Otherwise fall through.
16210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
16220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mCanChord = false;
16230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return true;
16240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
16250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
16260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public void closeFind() {
16270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mMenuState = R.id.MAIN_MENU;
16280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
16290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
163022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    @Override
163122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    public boolean onPrepareOptionsMenu(Menu menu) {
16320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // This happens when the user begins to hold down the menu key, so
16330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // allow them to chord to get a shortcut.
16340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mCanChord = true;
16350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Note: setVisible will decide whether an item is visible; while
16360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // setEnabled() will decide whether an item is enabled, which also means
16370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // whether the matching shortcut key will function.
16380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        super.onPrepareOptionsMenu(menu);
16390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        switch (mMenuState) {
16400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case EMPTY_MENU:
16410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (mCurrentMenuState != mMenuState) {
16420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    menu.setGroupVisible(R.id.MAIN_MENU, false);
16430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    menu.setGroupEnabled(R.id.MAIN_MENU, false);
16440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    menu.setGroupEnabled(R.id.MAIN_SHORTCUT_MENU, false);
16450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
16460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
16470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            default:
16480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (mCurrentMenuState != mMenuState) {
16490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    menu.setGroupVisible(R.id.MAIN_MENU, true);
16500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    menu.setGroupEnabled(R.id.MAIN_MENU, true);
16510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    menu.setGroupEnabled(R.id.MAIN_SHORTCUT_MENU, true);
16520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
16530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                final WebView w = getTopWindow();
16540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                boolean canGoBack = false;
16550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                boolean canGoForward = false;
16560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                boolean isHome = false;
16570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (w != null) {
16580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    canGoBack = w.canGoBack();
16590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    canGoForward = w.canGoForward();
16600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    isHome = mSettings.getHomePage().equals(w.getUrl());
16610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
16620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                final MenuItem back = menu.findItem(R.id.back_menu_id);
16630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                back.setEnabled(canGoBack);
16640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
16650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                final MenuItem home = menu.findItem(R.id.homepage_menu_id);
16660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                home.setEnabled(!isHome);
16670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
16680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.forward_menu_id)
16690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        .setEnabled(canGoForward);
16700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
1671a81a764063d2f849fba0cbc3039f86e67c2960ddLeon Scroggins                menu.findItem(R.id.new_tab_menu_id).setEnabled(
167222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        mTabControl.canCreateNewTab());
1673a81a764063d2f849fba0cbc3039f86e67c2960ddLeon Scroggins
16740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // decide whether to show the share link option
16750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                PackageManager pm = getPackageManager();
16760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                Intent send = new Intent(Intent.ACTION_SEND);
16770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                send.setType("text/plain");
16780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                ResolveInfo ri = pm.resolveActivity(send, PackageManager.MATCH_DEFAULT_ONLY);
16790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.share_page_menu_id).setVisible(ri != null);
16800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
16810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                boolean isNavDump = mSettings.isNavDump();
16820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                final MenuItem nav = menu.findItem(R.id.dump_nav_menu_id);
16830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                nav.setVisible(isNavDump);
16840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                nav.setEnabled(isNavDump);
16857a8b88b0e0f20544df5ee34b798398603261b733Andrei Popescu
16867a8b88b0e0f20544df5ee34b798398603261b733Andrei Popescu                boolean showDebugSettings = mSettings.showDebugSettings();
16877a8b88b0e0f20544df5ee34b798398603261b733Andrei Popescu                final MenuItem counter = menu.findItem(R.id.dump_counters_menu_id);
16887a8b88b0e0f20544df5ee34b798398603261b733Andrei Popescu                counter.setVisible(showDebugSettings);
16897a8b88b0e0f20544df5ee34b798398603261b733Andrei Popescu                counter.setEnabled(showDebugSettings);
16907a8b88b0e0f20544df5ee34b798398603261b733Andrei Popescu
16910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
16920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
16930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mCurrentMenuState = mMenuState;
16940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return true;
16950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
16960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
16970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    @Override
16980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public void onCreateContextMenu(ContextMenu menu, View v,
16990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ContextMenuInfo menuInfo) {
17000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebView webview = (WebView) v;
17010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebView.HitTestResult result = webview.getHitTestResult();
17020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (result == null) {
17030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
17040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
17050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
17060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        int type = result.getType();
17070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (type == WebView.HitTestResult.UNKNOWN_TYPE) {
17080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Log.w(LOGTAG,
17090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    "We should not show context menu when nothing is touched");
17100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
17110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
17120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (type == WebView.HitTestResult.EDIT_TEXT_TYPE) {
17130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // let TextView handles context menu
17140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
17150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
17160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
17170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Note, http://b/issue?id=1106666 is requesting that
17180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // an inflated menu can be used again. This is not available
17190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // yet, so inflate each time (yuk!)
17200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        MenuInflater inflater = getMenuInflater();
17210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        inflater.inflate(R.menu.browsercontext, menu);
17220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
17230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Show the correct menu group
17240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String extra = result.getExtra();
17250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        menu.setGroupVisible(R.id.PHONE_MENU,
17260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                type == WebView.HitTestResult.PHONE_TYPE);
17270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        menu.setGroupVisible(R.id.EMAIL_MENU,
17280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                type == WebView.HitTestResult.EMAIL_TYPE);
17290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        menu.setGroupVisible(R.id.GEO_MENU,
17300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                type == WebView.HitTestResult.GEO_TYPE);
17310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        menu.setGroupVisible(R.id.IMAGE_MENU,
17320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                type == WebView.HitTestResult.IMAGE_TYPE
17330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                || type == WebView.HitTestResult.SRC_IMAGE_ANCHOR_TYPE);
17340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        menu.setGroupVisible(R.id.ANCHOR_MENU,
17350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                type == WebView.HitTestResult.SRC_ANCHOR_TYPE
17360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                || type == WebView.HitTestResult.SRC_IMAGE_ANCHOR_TYPE);
17370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
17380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Setup custom handling depending on the type
17390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        switch (type) {
17400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case WebView.HitTestResult.PHONE_TYPE:
17410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.setHeaderTitle(Uri.decode(extra));
17420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.dial_context_menu_id).setIntent(
17430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new Intent(Intent.ACTION_VIEW, Uri
17440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                .parse(WebView.SCHEME_TEL + extra)));
17450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                Intent addIntent = new Intent(Intent.ACTION_INSERT_OR_EDIT);
17460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                addIntent.putExtra(Insert.PHONE, Uri.decode(extra));
17475e335a381a0cd66e94117b202c1f34f5cb29c9b8Cary Clark                addIntent.setType(ContactsContract.Contacts.CONTENT_ITEM_TYPE);
17480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.add_contact_context_menu_id).setIntent(
17490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        addIntent);
17500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.copy_phone_context_menu_id).setOnMenuItemClickListener(
17510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new Copy(extra));
17520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
17530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
17540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case WebView.HitTestResult.EMAIL_TYPE:
17550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.setHeaderTitle(extra);
17560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.email_context_menu_id).setIntent(
17570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new Intent(Intent.ACTION_VIEW, Uri
17580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                .parse(WebView.SCHEME_MAILTO + extra)));
17590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.copy_mail_context_menu_id).setOnMenuItemClickListener(
17600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new Copy(extra));
17610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
17620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
17630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case WebView.HitTestResult.GEO_TYPE:
17640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.setHeaderTitle(extra);
17650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.map_context_menu_id).setIntent(
17660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new Intent(Intent.ACTION_VIEW, Uri
17670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                .parse(WebView.SCHEME_GEO
17680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        + URLEncoder.encode(extra))));
17690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.copy_geo_context_menu_id).setOnMenuItemClickListener(
17700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new Copy(extra));
17710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
17720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
17730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case WebView.HitTestResult.SRC_ANCHOR_TYPE:
17740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case WebView.HitTestResult.SRC_IMAGE_ANCHOR_TYPE:
17750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                TextView titleView = (TextView) LayoutInflater.from(this)
17760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        .inflate(android.R.layout.browser_link_context_header,
17770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        null);
17780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                titleView.setText(extra);
17790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.setHeaderView(titleView);
17800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // decide whether to show the open link in new tab option
17810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.open_newtab_context_menu_id).setVisible(
178222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        mTabControl.canCreateNewTab());
1783de353621650d17a412b6ffe2cbf0366db5f11c40Ben Murdoch                menu.findItem(R.id.bookmark_context_menu_id).setVisible(
1784de353621650d17a412b6ffe2cbf0366db5f11c40Ben Murdoch                        Bookmarks.urlHasAcceptableScheme(extra));
17850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                PackageManager pm = getPackageManager();
17860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                Intent send = new Intent(Intent.ACTION_SEND);
17870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                send.setType("text/plain");
17880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                ResolveInfo ri = pm.resolveActivity(send, PackageManager.MATCH_DEFAULT_ONLY);
17890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.share_link_context_menu_id).setVisible(ri != null);
17900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (type == WebView.HitTestResult.SRC_ANCHOR_TYPE) {
17910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    break;
17920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
17930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // otherwise fall through to handle image part
17940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case WebView.HitTestResult.IMAGE_TYPE:
17950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (type == WebView.HitTestResult.IMAGE_TYPE) {
17960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    menu.setHeaderTitle(extra);
17970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
17980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.view_image_context_menu_id).setIntent(
17990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new Intent(Intent.ACTION_VIEW, Uri.parse(extra)));
18000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.download_context_menu_id).
18010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        setOnMenuItemClickListener(new Download(extra));
18024f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                menu.findItem(R.id.set_wallpaper_context_menu_id).
18034f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                        setOnMenuItemClickListener(new SetAsWallpaper(extra));
18040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
18050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
18060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            default:
18070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                Log.w(LOGTAG, "We should not get here.");
18080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
18090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
1810b2b19f501ee05448ca81bddaaca70e9b2f51cb54Leon Scroggins        hideFakeTitleBar();
18110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
18120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
18130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Attach the given tab to the content view.
1814c928c30a51eee84b40cb7045842c288c1cfafff0Grace Kloba    // this should only be called for the current tab.
181522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private void attachTabToContentView(Tab t) {
18162bc69918d97a767a02132090e58718077381ba1aSteve Block        // Attach the container that contains the main WebView and any other UI
18172bc69918d97a767a02132090e58718077381ba1aSteve Block        // associated with the tab.
1818d0119535d0c490e087be114ae8fd1639bb1945dcPatrick Scott        t.attachTabToContentView(mContentView);
1819bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch
1820bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch        if (mShouldShowErrorConsole) {
182122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            ErrorConsoleView errorConsole = t.getErrorConsole(true);
1822bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch            if (errorConsole.numberOfErrors() == 0) {
1823bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch                errorConsole.showConsole(ErrorConsoleView.SHOW_NONE);
1824bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch            } else {
1825bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch                errorConsole.showConsole(ErrorConsoleView.SHOW_MINIMIZED);
1826bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch            }
1827bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch
1828bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch            mErrorConsoleContainer.addView(errorConsole,
182915b8ec6b226f4d57307716e1f495e10a91f8cbf4Romain Guy                    new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
1830bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch                                                  ViewGroup.LayoutParams.WRAP_CONTENT));
1831bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch        }
1832bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch
183339ab28eba0c8c837ac80851ec0dd2af336aa3f85Leon Scroggins        WebView view = t.getWebView();
183455a5bc2a8f3c9a0721eeaa5a45241e00d5da95efLeon Scroggins        view.setEmbeddedTitleBar(mTitleBar);
183558d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        if (t.isInVoiceSearchMode()) {
183658d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins            showVoiceTitleBar(t.getVoiceDisplayTitle());
183758d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        } else {
183858d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins            revertVoiceTitleBar();
183958d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        }
18400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Request focus on the top window.
18410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        t.getTopWindow().requestFocus();
18420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
18430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
18440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Attach a sub window to the main WebView of the given tab.
184522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void attachSubWindow(Tab t) {
1846d0119535d0c490e087be114ae8fd1639bb1945dcPatrick Scott        t.attachSubWindow(mContentView);
1847d0119535d0c490e087be114ae8fd1639bb1945dcPatrick Scott        getTopWindow().requestFocus();
18480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
18490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
18500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Remove the given tab from the content view.
185122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private void removeTabFromContentView(Tab t) {
18522bc69918d97a767a02132090e58718077381ba1aSteve Block        // Remove the container that contains the main WebView.
1853d0119535d0c490e087be114ae8fd1639bb1945dcPatrick Scott        t.removeTabFromContentView(mContentView);
1854bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch
185522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        ErrorConsoleView errorConsole = t.getErrorConsole(false);
185622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (errorConsole != null) {
185722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mErrorConsoleContainer.removeView(errorConsole);
1858bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch        }
1859bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch
186039ab28eba0c8c837ac80851ec0dd2af336aa3f85Leon Scroggins        WebView view = t.getWebView();
1861bb85b9016201d45ea939d7cb7edd0ba6616a111cLeon Scroggins        if (view != null) {
1862bb85b9016201d45ea939d7cb7edd0ba6616a111cLeon Scroggins            view.setEmbeddedTitleBar(null);
1863bb85b9016201d45ea939d7cb7edd0ba6616a111cLeon Scroggins        }
18640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
18650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
18660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Remove the sub window if it exists. Also called by TabControl when the
18670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // user clicks the 'X' to dismiss a sub window.
186822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /* package */ void dismissSubWindow(Tab t) {
1869d0119535d0c490e087be114ae8fd1639bb1945dcPatrick Scott        t.removeSubWindow(mContentView);
187022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // dismiss the subwindow. This will destroy the WebView.
187122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        t.dismissSubWindow();
1872d0119535d0c490e087be114ae8fd1639bb1945dcPatrick Scott        getTopWindow().requestFocus();
18730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
18740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
18751f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins    // A wrapper function of {@link #openTabAndShow(UrlData, boolean, String)}
187625ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima    // that accepts url as string.
187722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private Tab openTabAndShow(String url, boolean closeOnExit, String appId) {
18781f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins        return openTabAndShow(new UrlData(url), closeOnExit, appId);
18790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
18800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
18810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // This method does a ton of stuff. It will attempt to create a new tab
18820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // if we haven't reached MAX_TABS. Otherwise it uses the current tab. If
18831f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins    // url isn't null, it will load the given url.
188422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /* package */Tab openTabAndShow(UrlData urlData, boolean closeOnExit,
188522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            String appId) {
188622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        final Tab currentTab = mTabControl.getCurrentTab();
188722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mTabControl.canCreateNewTab()) {
188822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            final Tab tab = mTabControl.createNewTab(closeOnExit, appId,
188922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    urlData.mUrl);
18901f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins            WebView webview = tab.getWebView();
18910a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins            // If the last tab was removed from the active tabs page, currentTab
18920a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins            // will be null.
18930a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins            if (currentTab != null) {
18940a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins                removeTabFromContentView(currentTab);
18950a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins            }
18968bbd69f50abd537bfe7eb314b3a3e20241ac22bdPatrick Scott            // We must set the new tab as the current tab to reflect the old
18978bbd69f50abd537bfe7eb314b3a3e20241ac22bdPatrick Scott            // animation behavior.
18988bbd69f50abd537bfe7eb314b3a3e20241ac22bdPatrick Scott            mTabControl.setCurrentTab(tab);
1899eb6eef4c45df2d65c3e70660493a147a2be405e3Grace Kloba            attachTabToContentView(tab);
1900160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins            if (!urlData.isEmpty()) {
190158d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins                urlData.loadIn(tab);
19020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
19031f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins            return tab;
190464b80f3efd95d7b5192731e995ccde79c4c6c11fLeon Scroggins        } else {
19051f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins            // Get rid of the subwindow if it exists
19061f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins            dismissSubWindow(currentTab);
19071f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins            if (!urlData.isEmpty()) {
19081f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                // Load the given url.
190958d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins                urlData.loadIn(currentTab);
19100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
191158d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins            return currentTab;
19120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
19130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
19140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
191522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private Tab openTab(String url) {
19160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mSettings.openInBackground()) {
191722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            Tab t = mTabControl.createNewTab();
19180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (t != null) {
19191f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                WebView view = t.getWebView();
19201f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                view.loadUrl(url);
19210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
1922c9181841c7ed6b9f7dfc953eab8dc7ba1047022cGrace Kloba            return t;
19230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
19241f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins            return openTabAndShow(url, false, null);
19250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
19260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
19270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
19280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private class Copy implements OnMenuItemClickListener {
19290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        private CharSequence mText;
19300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
19310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public boolean onMenuItemClick(MenuItem item) {
19320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            copy(mText);
19330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return true;
19340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
19350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
19360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public Copy(CharSequence toCopy) {
19370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mText = toCopy;
19380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
19390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
19400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
19410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private class Download implements OnMenuItemClickListener {
19420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        private String mText;
19430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
19440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public boolean onMenuItemClick(MenuItem item) {
19450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            onDownloadStartNoStream(mText, null, null, null, -1);
19460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return true;
19470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
19480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
19490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public Download(String toDownload) {
19500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mText = toDownload;
19510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
19520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
19530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
19544f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch    private class SetAsWallpaper extends Thread implements
19554f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch            OnMenuItemClickListener, DialogInterface.OnCancelListener {
19564f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch        private URL mUrl;
19574f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch        private ProgressDialog mWallpaperProgress;
19584f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch        private boolean mCanceled = false;
19594f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch
19604f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch        public SetAsWallpaper(String url) {
19614f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch            try {
19624f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                mUrl = new URL(url);
19634f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch            } catch (MalformedURLException e) {
19644f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                mUrl = null;
19654f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch            }
19664f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch        }
19674f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch
19684f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch        public void onCancel(DialogInterface dialog) {
19694f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch            mCanceled = true;
19704f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch        }
19714f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch
19724f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch        public boolean onMenuItemClick(MenuItem item) {
19734f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch            if (mUrl != null) {
19744f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                // The user may have tried to set a image with a large file size as their
19754f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                // background so it may take a few moments to perform the operation. Display
19764f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                // a progress spinner while it is working.
19774f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                mWallpaperProgress = new ProgressDialog(BrowserActivity.this);
19784f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                mWallpaperProgress.setIndeterminate(true);
19794f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                mWallpaperProgress.setMessage(getText(R.string.progress_dialog_setting_wallpaper));
19804f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                mWallpaperProgress.setCancelable(true);
19814f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                mWallpaperProgress.setOnCancelListener(this);
19824f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                mWallpaperProgress.show();
19834f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                start();
19844f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch            }
19854f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch            return true;
19864f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch        }
19874f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch
19884f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch        public void run() {
19894f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch            Drawable oldWallpaper = BrowserActivity.this.getWallpaper();
19904f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch            try {
19914f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                // TODO: This will cause the resource to be downloaded again, when we
19924f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                // should in most cases be able to grab it from the cache. To fix this
19934f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                // we should query WebCore to see if we can access a cached version and
19944f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                // instead open an input stream on that. This pattern could also be used
19954f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                // in the download manager where the same problem exists.
19964f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                InputStream inputstream = mUrl.openStream();
19974f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                if (inputstream != null) {
19984f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                    setWallpaper(inputstream);
19994f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                }
20004f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch            } catch (IOException e) {
20014f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                Log.e(LOGTAG, "Unable to set new wallpaper");
20024f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                // Act as though the user canceled the operation so we try to
20034f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                // restore the old wallpaper.
20044f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                mCanceled = true;
20054f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch            }
20064f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch
20074f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch            if (mCanceled) {
20084f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                // Restore the old wallpaper if the user cancelled whilst we were setting
20094f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                // the new wallpaper.
20104f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                int width = oldWallpaper.getIntrinsicWidth();
20114f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                int height = oldWallpaper.getIntrinsicHeight();
20124f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                Bitmap bm = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);
20134f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                Canvas canvas = new Canvas(bm);
20144f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                oldWallpaper.setBounds(0, 0, width, height);
20154f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                oldWallpaper.draw(canvas);
20164f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                try {
20174f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                    setWallpaper(bm);
20184f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                } catch (IOException e) {
20194f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                    Log.e(LOGTAG, "Unable to restore old wallpaper.");
20204f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                }
20214f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                mCanceled = false;
20224f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch            }
20234f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch
20244f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch            if (mWallpaperProgress.isShowing()) {
20254f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch                mWallpaperProgress.dismiss();
20264f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch            }
20274f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch        }
20284f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch    }
20294f75ba226fb7fd1cf62caf807123dee8f5e65b13Ben Murdoch
20300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void copy(CharSequence text) {
20310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        try {
20320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            IClipboard clip = IClipboard.Stub.asInterface(ServiceManager.getService("clipboard"));
20330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (clip != null) {
20340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                clip.setClipboardText(text);
20350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
20360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } catch (android.os.RemoteException e) {
20370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Log.e(LOGTAG, "Copy failed", e);
20380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
20390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
20400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
20410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
20420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Resets the browser title-view to whatever it must be
20430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * (for example, if we had a loading error)
20440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * When we have a new page, we call resetTitle, when we
20450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * have to reset the titlebar to whatever it used to be
20460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * (for example, if the user chose to stop loading), we
20470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * call resetTitleAndRevertLockIcon.
20480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
20490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /* package */ void resetTitleAndRevertLockIcon() {
205022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mTabControl.getCurrentTab().revertLockIcon();
205122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        updateLockIconToLatest();
20520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        resetTitleIconAndProgress();
20530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
20540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
20550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
20560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Reset the title, favicon, and progress.
20570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
20580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void resetTitleIconAndProgress() {
20590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebView current = mTabControl.getCurrentWebView();
20600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (current == null) {
20610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
20620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
20630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        resetTitleAndIcon(current);
20640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        int progress = current.getProgress();
206522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        current.getWebChromeClient().onProgressChanged(current, progress);
20660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
20670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
20680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Reset the title and the icon based on the given item.
20690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void resetTitleAndIcon(WebView view) {
20700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebHistoryItem item = view.copyBackForwardList().getCurrentItem();
20710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (item != null) {
207268579393973f745fc65a2781061af9bb8f2d7020Leon Scroggins            setUrlTitle(item.getUrl(), item.getTitle());
20730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            setFavicon(item.getFavicon());
20740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
207568579393973f745fc65a2781061af9bb8f2d7020Leon Scroggins            setUrlTitle(null, null);
20760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            setFavicon(null);
20770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
20780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
20790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
20800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
20810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Sets a title composed of the URL and the title string.
20820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param url The URL of the site being loaded.
20830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param title The title of the site being loaded.
20840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
208522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void setUrlTitle(String url, String title) {
20860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mUrl = url;
20870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mTitle = title;
20880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
208958d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        // If we are in voice search mode, the title has already been set.
209058d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        if (mTabControl.getCurrentTab().isInVoiceSearchMode()) return;
209158d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        mTitleBar.setDisplayTitle(url);
209258d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        mFakeTitleBar.setDisplayTitle(url);
20930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
20940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
20950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
20960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param url The URL to build a title version of the URL from.
20970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @return The title version of the URL or null if fails.
20980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * The title version of the URL can be either the URL hostname,
20990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * or the hostname with an "https://" prefix (for secure URLs),
21000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * or an empty string if, for example, the URL in question is a
21010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * file:// URL with no hostname.
21020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
210332e14a6deccfa75490b3032bb4ddd5ae90f89de8Leon Scroggins    /* package */ static String buildTitleUrl(String url) {
21040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String titleUrl = null;
21050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
21060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (url != null) {
21070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            try {
21080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // parse the url string
21090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                URL urlObj = new URL(url);
21100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (urlObj != null) {
21110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    titleUrl = "";
21120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
21130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    String protocol = urlObj.getProtocol();
21140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    String host = urlObj.getHost();
21150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
21160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    if (host != null && 0 < host.length()) {
21170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        titleUrl = host;
21180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        if (protocol != null) {
21190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            // if a secure site, add an "https://" prefix!
21200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            if (protocol.equalsIgnoreCase("https")) {
21210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                titleUrl = protocol + "://" + host;
21220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            }
21230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }
21240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
21250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
21260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } catch (MalformedURLException e) {}
21270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
21280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
21290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return titleUrl;
21300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
21310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
21320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Set the favicon in the title bar.
213322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void setFavicon(Bitmap icon) {
213468579393973f745fc65a2781061af9bb8f2d7020Leon Scroggins        mTitleBar.setFavicon(icon);
2135fe87bd3a3897e4bad65bb3d284659ae2f4e57570Leon Scroggins        mFakeTitleBar.setFavicon(icon);
21360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
21370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
21380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
21390a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins     * Close the tab, remove its associated title bar, and adjust mTabControl's
21400a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins     * current tab to a valid value.
21411f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins     */
214222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    /* package */ void closeTab(Tab t) {
21430a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins        int currentIndex = mTabControl.getCurrentIndex();
21440a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins        int removeIndex = mTabControl.getTabIndex(t);
21451f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins        mTabControl.removeTab(t);
21460a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins        if (currentIndex >= removeIndex && currentIndex != 0) {
21470a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins            currentIndex--;
21480a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins        }
21490a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins        mTabControl.setCurrentTab(mTabControl.getTab(currentIndex));
2150a5bf1deca120315a2643ea5b010f94d853461b15Andrei Popescu        resetTitleIconAndProgress();
21510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
21520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
21530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void goBackOnePageOrQuit() {
215422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        Tab current = mTabControl.getCurrentTab();
21550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (current == null) {
21560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            /*
21570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project             * Instead of finishing the activity, simply push this to the back
21580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project             * of the stack and let ActivityManager to choose the foreground
21590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project             * activity. As BrowserActivity is singleTask, it will be always the
21600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project             * root of the task. So we can use either true or false for
21610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project             * moveTaskToBack().
21620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project             */
21630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            moveTaskToBack(true);
216400d85e74921459b34e70eb93368245b4c0a9bf5fGrace Kloba            return;
21650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
21660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebView w = current.getWebView();
21670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (w.canGoBack()) {
21680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            w.goBack();
21690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
21700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Check to see if we are closing a window that was created by
21710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // another window. If so, we switch back to that window.
217222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            Tab parent = current.getParentTab();
21730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (parent != null) {
21741f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                switchToTab(mTabControl.getTabIndex(parent));
21751f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                // Now we close the other tab
21761f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                closeTab(current);
21770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } else {
21780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (current.closeOnExit()) {
217922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    // force the tab's inLoad() to be false as we are going to
218022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    // either finish the activity or remove the tab. This will
218122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    // ensure pauseWebViewTimers() taking action.
218222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    mTabControl.getCurrentTab().clearInLoad();
21830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    if (mTabControl.getTabCount() == 1) {
21840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        finish();
21850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        return;
21860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
21877bfa63b55644fbf2da1fe6a24b3be0267529202cMike Reed                    // call pauseWebViewTimers() now, we won't be able to call
21887bfa63b55644fbf2da1fe6a24b3be0267529202cMike Reed                    // it in onPause() as the WebView won't be valid.
2189ec1b5ad8d8283b1fbbc5d7fa1cd50ef95b9e594dGrace Kloba                    // Temporarily change mActivityInPause to be true as
2190ec1b5ad8d8283b1fbbc5d7fa1cd50ef95b9e594dGrace Kloba                    // pauseWebViewTimers() will do nothing if mActivityInPause
2191ec1b5ad8d8283b1fbbc5d7fa1cd50ef95b9e594dGrace Kloba                    // is false.
2192918e1d78b2db6ef21c71a07868572d9cda498476Grace Kloba                    boolean savedState = mActivityInPause;
2193918e1d78b2db6ef21c71a07868572d9cda498476Grace Kloba                    if (savedState) {
2194ec1b5ad8d8283b1fbbc5d7fa1cd50ef95b9e594dGrace Kloba                        Log.e(LOGTAG, "BrowserActivity is already paused "
2195ec1b5ad8d8283b1fbbc5d7fa1cd50ef95b9e594dGrace Kloba                                + "while handing goBackOnePageOrQuit.");
2196918e1d78b2db6ef21c71a07868572d9cda498476Grace Kloba                    }
2197918e1d78b2db6ef21c71a07868572d9cda498476Grace Kloba                    mActivityInPause = true;
21987bfa63b55644fbf2da1fe6a24b3be0267529202cMike Reed                    pauseWebViewTimers();
2199918e1d78b2db6ef21c71a07868572d9cda498476Grace Kloba                    mActivityInPause = savedState;
22000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    removeTabFromContentView(current);
22010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    mTabControl.removeTab(current);
22020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
22030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                /*
22040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                 * Instead of finishing the activity, simply push this to the back
22050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                 * of the stack and let ActivityManager to choose the foreground
22060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                 * activity. As BrowserActivity is singleTask, it will be always the
22070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                 * root of the task. So we can use either true or false for
22080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                 * moveTaskToBack().
22090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                 */
22100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                moveTaskToBack(true);
22110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
22120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
22130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
22140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
221522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    boolean isMenuDown() {
221622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return mMenuIsDown;
221722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
221822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
22195942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba    @Override
22205942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba    public boolean onKeyDown(int keyCode, KeyEvent event) {
2221f65b50ddd2f7ed1205002d74082fff1ac2336d5cLeon Scroggins        // Even if MENU is already held down, we need to call to super to open
2222f65b50ddd2f7ed1205002d74082fff1ac2336d5cLeon Scroggins        // the IME on long press.
2223f65b50ddd2f7ed1205002d74082fff1ac2336d5cLeon Scroggins        if (KeyEvent.KEYCODE_MENU == keyCode) {
2224f65b50ddd2f7ed1205002d74082fff1ac2336d5cLeon Scroggins            mMenuIsDown = true;
2225f65b50ddd2f7ed1205002d74082fff1ac2336d5cLeon Scroggins            return super.onKeyDown(keyCode, event);
2226f65b50ddd2f7ed1205002d74082fff1ac2336d5cLeon Scroggins        }
22275942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba        // The default key mode is DEFAULT_KEYS_SEARCH_LOCAL. As the MENU is
22285942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba        // still down, we don't want to trigger the search. Pretend to consume
22295942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba        // the key and do nothing.
22305942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba        if (mMenuIsDown) return true;
22315942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba
22325942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba        switch(keyCode) {
22335942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba            case KeyEvent.KEYCODE_SPACE:
2234da0fe556a00773ce2af25eb6dcc5442bd08c7addGrace Kloba                // WebView/WebTextView handle the keys in the KeyDown. As
2235da0fe556a00773ce2af25eb6dcc5442bd08c7addGrace Kloba                // the Activity's shortcut keys are only handled when WebView
2236da0fe556a00773ce2af25eb6dcc5442bd08c7addGrace Kloba                // doesn't, have to do it in onKeyDown instead of onKeyUp.
2237da0fe556a00773ce2af25eb6dcc5442bd08c7addGrace Kloba                if (event.isShiftPressed()) {
2238da0fe556a00773ce2af25eb6dcc5442bd08c7addGrace Kloba                    getTopWindow().pageUp(false);
2239da0fe556a00773ce2af25eb6dcc5442bd08c7addGrace Kloba                } else {
2240da0fe556a00773ce2af25eb6dcc5442bd08c7addGrace Kloba                    getTopWindow().pageDown(false);
2241da0fe556a00773ce2af25eb6dcc5442bd08c7addGrace Kloba                }
22425942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                return true;
22435942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba            case KeyEvent.KEYCODE_BACK:
22445942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                if (event.getRepeatCount() == 0) {
22455942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                    event.startTracking();
22465942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                    return true;
22475942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                } else if (mCustomView == null && mActiveTabsPage == null
22485942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                        && event.isLongPress()) {
22495942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                    bookmarksOrHistoryPicker(true);
22505942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                    return true;
22510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
22525942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                break;
22530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
22545942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba        return super.onKeyDown(keyCode, event);
22550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
22560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
22575942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba    @Override
22585942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba    public boolean onKeyUp(int keyCode, KeyEvent event) {
22595942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba        switch(keyCode) {
22605942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba            case KeyEvent.KEYCODE_MENU:
22615942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                mMenuIsDown = false;
22625942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                break;
22635942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba            case KeyEvent.KEYCODE_BACK:
22645942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                if (event.isTracking() && !event.isCanceled()) {
22655942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                    if (mCustomView != null) {
22665942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                        // if a custom view is showing, hide it
226722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        mTabControl.getCurrentWebView().getWebChromeClient()
226822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                .onHideCustomView();
22695942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                    } else if (mActiveTabsPage != null) {
22705942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                        // if tab page is showing, hide it
22715942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                        removeActiveTabPage(true);
22720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    } else {
22735942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                        WebView subwindow = mTabControl.getCurrentSubWindow();
22745942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                        if (subwindow != null) {
22755942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                            if (subwindow.canGoBack()) {
22765942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                                subwindow.goBack();
22775942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                            } else {
22785942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                                dismissSubWindow(mTabControl.getCurrentTab());
22795942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                            }
22805942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                        } else {
22815942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                            goBackOnePageOrQuit();
22825942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                        }
22830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
22845942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                    return true;
22855942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                }
22865942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                break;
22870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
22885942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba        return super.onKeyUp(keyCode, event);
22890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
22900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
229168579393973f745fc65a2781061af9bb8f2d7020Leon Scroggins    /* package */ void stopLoading() {
2292b7cc8b439dc595dc48e1c2183b35d23ad72dfbe5Ben Murdoch        mDidStopLoad = true;
22930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        resetTitleAndRevertLockIcon();
22940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebView w = getTopWindow();
22950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        w.stopLoading();
229622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // FIXME: before refactor, it is using mWebViewClient. So I keep the
229722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // same logic here. But for subwindow case, should we call into the main
229822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // WebView's onPageFinished as we never call its onPageStarted and if
229922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // the page finishes itself, we don't call onPageFinished.
230022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mTabControl.getCurrentWebView().getWebViewClient().onPageFinished(w,
230122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                w.getUrl());
23020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
23030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        cancelStopToast();
23040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mStopToast = Toast
23050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .makeText(this, R.string.stopping, Toast.LENGTH_SHORT);
23060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mStopToast.show();
23070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
23080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
230922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    boolean didUserStopLoading() {
231022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return mDidStopLoad;
231122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
231222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
23130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void cancelStopToast() {
23140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mStopToast != null) {
23150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mStopToast.cancel();
23160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mStopToast = null;
23170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
23180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
23190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
232022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // called by a UI or non-UI thread to post the message
232122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    public void postMessage(int what, int arg1, int arg2, Object obj,
232222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            long delayMillis) {
232322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mHandler.sendMessageDelayed(mHandler.obtainMessage(what, arg1, arg2,
232422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                obj), delayMillis);
232522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
232622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
232722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // called by a UI or non-UI thread to remove the message
232822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void removeMessages(int what, Object object) {
232922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mHandler.removeMessages(what, object);
23300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
23310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
23320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // public message ids
23330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public final static int LOAD_URL                = 1001;
23340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public final static int STOP_LOAD               = 1002;
23350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
23360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Message Ids
23370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private static final int FOCUS_NODE_HREF         = 102;
23380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private static final int CANCEL_CREDS_REQUEST    = 103;
233992c18a52ca7a79c114028b5ba22c3dfe443bd1a4Grace Kloba    private static final int RELEASE_WAKELOCK        = 107;
23400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
234122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    static final int UPDATE_BOOKMARK_THUMBNAIL       = 108;
23422694e23a55d5ca526fc29534a80a200e2c58698bBen Murdoch
23430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Private handler for handling javascript and saving passwords
23440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private Handler mHandler = new Handler() {
23450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
23460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public void handleMessage(Message msg) {
23470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            switch (msg.what) {
23480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                case FOCUS_NODE_HREF:
23492694e23a55d5ca526fc29534a80a200e2c58698bBen Murdoch                {
23500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    String url = (String) msg.getData().get("url");
235190d088caeee718f89755ee9c25249ba6da15ab97Ben Murdoch                    String title = (String) msg.getData().get("title");
23520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    if (url == null || url.length() == 0) {
23530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        break;
23540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
23550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    HashMap focusNodeMap = (HashMap) msg.obj;
23560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    WebView view = (WebView) focusNodeMap.get("webview");
23570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // Only apply the action if the top window did not change.
23580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    if (getTopWindow() != view) {
23590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        break;
23600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
23610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    switch (msg.arg1) {
23620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        case R.id.open_context_menu_id:
23630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        case R.id.view_image_context_menu_id:
23640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            loadURL(getTopWindow(), url);
23650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            break;
23660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        case R.id.open_newtab_context_menu_id:
236722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            final Tab parent = mTabControl.getCurrentTab();
236822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                            final Tab newTab = openTab(url);
2369c9181841c7ed6b9f7dfc953eab8dc7ba1047022cGrace Kloba                            if (newTab != parent) {
2370c9181841c7ed6b9f7dfc953eab8dc7ba1047022cGrace Kloba                                parent.addChildTab(newTab);
2371c9181841c7ed6b9f7dfc953eab8dc7ba1047022cGrace Kloba                            }
23720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            break;
23730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        case R.id.bookmark_context_menu_id:
23740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            Intent intent = new Intent(BrowserActivity.this,
23750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    AddBookmarkPage.class);
23760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            intent.putExtra("url", url);
237790d088caeee718f89755ee9c25249ba6da15ab97Ben Murdoch                            intent.putExtra("title", title);
23780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            startActivity(intent);
23790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            break;
23800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        case R.id.share_link_context_menu_id:
238196afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                            // See if this site has been visited before
238296afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                            StringBuilder sb = new StringBuilder(
238396afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                                    Browser.BookmarkColumns.URL + " = ");
238496afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                            DatabaseUtils.appendEscapedSQLString(sb, url);
238596afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                            Cursor c = mResolver.query(Browser.BOOKMARKS_URI,
238696afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                                    Browser.HISTORY_PROJECTION,
238796afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                                    sb.toString(),
238896afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                                    null,
238996afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                                    null);
239096afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                            if (c.moveToFirst()) {
239196afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                                // The site has been visited before, so grab the
239296afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                                // info from the database.
239396afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                                Bitmap favicon = null;
239496afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                                Bitmap thumbnail = null;
239596afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                                String linkTitle = c.getString(Browser.
239696afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                                        HISTORY_PROJECTION_TITLE_INDEX);
239796afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                                byte[] data = c.getBlob(Browser.
239896afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                                        HISTORY_PROJECTION_FAVICON_INDEX);
239996afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                                if (data != null) {
240096afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                                    favicon = BitmapFactory.decodeByteArray(
240196afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                                            data, 0, data.length);
240296afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                                }
240396afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                                data = c.getBlob(Browser.
240496afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                                        HISTORY_PROJECTION_THUMBNAIL_INDEX);
240596afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                                if (data != null) {
240696afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                                    thumbnail = BitmapFactory.decodeByteArray(
240796afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                                            data, 0, data.length);
240896afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                                }
240996afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                                sharePage(BrowserActivity.this,
241096afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                                        linkTitle, url, favicon, thumbnail);
241196afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                            } else {
241296afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                                Browser.sendString(BrowserActivity.this, url,
241396afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                                        getString(
241496afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                                        R.string.choosertitle_sharevia));
241596afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                            }
24160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            break;
24170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        case R.id.copy_link_context_menu_id:
24180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            copy(url);
24190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            break;
24200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        case R.id.save_link_context_menu_id:
24210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        case R.id.download_context_menu_id:
24220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            onDownloadStartNoStream(url, null, null, null, -1);
24230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            break;
24240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
24250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    break;
24262694e23a55d5ca526fc29534a80a200e2c58698bBen Murdoch                }
24270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
24280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                case LOAD_URL:
24290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    loadURL(getTopWindow(), (String) msg.obj);
24300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    break;
24310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
24320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                case STOP_LOAD:
24330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    stopLoading();
24340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    break;
24350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
24360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                case CANCEL_CREDS_REQUEST:
24370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    resumeAfterCredentials();
24380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    break;
24390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
24400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                case RELEASE_WAKELOCK:
24410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    if (mWakeLock.isHeld()) {
24420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        mWakeLock.release();
24435d0e02e646e46b14289168f75c2a8f6ed43cac54Grace Kloba                        // if we reach here, Browser should be still in the
24445d0e02e646e46b14289168f75c2a8f6ed43cac54Grace Kloba                        // background loading after WAKELOCK_TIMEOUT (5-min).
24455d0e02e646e46b14289168f75c2a8f6ed43cac54Grace Kloba                        // To avoid burning the battery, stop loading.
24465d0e02e646e46b14289168f75c2a8f6ed43cac54Grace Kloba                        mTabControl.stopAllLoading();
24470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
24480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    break;
24492694e23a55d5ca526fc29534a80a200e2c58698bBen Murdoch
24502694e23a55d5ca526fc29534a80a200e2c58698bBen Murdoch                case UPDATE_BOOKMARK_THUMBNAIL:
24512694e23a55d5ca526fc29534a80a200e2c58698bBen Murdoch                    WebView view = (WebView) msg.obj;
24522694e23a55d5ca526fc29534a80a200e2c58698bBen Murdoch                    if (view != null) {
24532694e23a55d5ca526fc29534a80a200e2c58698bBen Murdoch                        updateScreenshot(view);
24542694e23a55d5ca526fc29534a80a200e2c58698bBen Murdoch                    }
24552694e23a55d5ca526fc29534a80a200e2c58698bBen Murdoch                    break;
24560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
24570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
24580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    };
24590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
246096afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins    /**
246196afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins     * Share a page, providing the title, url, favicon, and a screenshot.  Uses
246296afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins     * an {@link Intent} to launch the Activity chooser.
246396afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins     * @param c Context used to launch a new Activity.
246496afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins     * @param title Title of the page.  Stored in the Intent with
246596afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins     *          {@link Browser#EXTRA_SHARE_TITLE}
246696afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins     * @param url URL of the page.  Stored in the Intent with
246796afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins     *          {@link Intent#EXTRA_TEXT}
246896afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins     * @param favicon Bitmap of the favicon for the page.  Stored in the Intent
246996afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins     *          with {@link Browser#EXTRA_SHARE_FAVICON}
247096afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins     * @param screenshot Bitmap of a screenshot of the page.  Stored in the
247196afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins     *          Intent with {@link Browser#EXTRA_SHARE_SCREENSHOT}
247296afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins     */
247396afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins    public static final void sharePage(Context c, String title, String url,
247496afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins            Bitmap favicon, Bitmap screenshot) {
247596afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins        Intent send = new Intent(Intent.ACTION_SEND);
247696afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins        send.setType("text/plain");
247796afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins        send.putExtra(Intent.EXTRA_TEXT, url);
247896afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins        send.putExtra(Browser.EXTRA_SHARE_TITLE, title);
247996afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins        send.putExtra(Browser.EXTRA_SHARE_FAVICON, favicon);
248096afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins        send.putExtra(Browser.EXTRA_SHARE_SCREENSHOT, screenshot);
248196afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins        try {
248296afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins            c.startActivity(Intent.createChooser(send, c.getString(
248396afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins                    R.string.choosertitle_sharevia)));
248496afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins        } catch(android.content.ActivityNotFoundException ex) {
248596afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins            // if no app handles it, do nothing
248696afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins        }
248796afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins    }
248896afcb1a85b1d14be910bfe0a2c4104e6ec87964Leon Scroggins
248989c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins    private void updateScreenshot(WebView view) {
249089c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins        // If this is a bookmarked site, add a screenshot to the database.
249189c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins        // FIXME: When should we update?  Every time?
249289c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins        // FIXME: Would like to make sure there is actually something to
249389c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins        // draw, but the API for that (WebViewCore.pictureReady()) is not
249489c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins        // currently accessible here.
2495aac7aa6fcfcb519755987ec126be066323f589c8Ben Murdoch
24963918d4443ff38ef1870e02aa51a8b29f8352bb1aPatrick Scott        ContentResolver cr = getContentResolver();
24973918d4443ff38ef1870e02aa51a8b29f8352bb1aPatrick Scott        final Cursor c = BrowserBookmarksAdapter.queryBookmarksForUrl(
2498aac7aa6fcfcb519755987ec126be066323f589c8Ben Murdoch                cr, view.getOriginalUrl(), view.getUrl(), true);
24993918d4443ff38ef1870e02aa51a8b29f8352bb1aPatrick Scott        if (c != null) {
250089c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins            boolean succeed = c.moveToFirst();
250189c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins            ContentValues values = null;
250289c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins            while (succeed) {
250389c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins                if (values == null) {
250489c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins                    final ByteArrayOutputStream os
250589c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins                            = new ByteArrayOutputStream();
2506dcc2b6f08dd5677bc6ba761a9ba6f1c655113051Ben Murdoch                    Bitmap bm = createScreenshot(view);
25074580057e772b60433272af5cd691825748892693Leon Scroggins                    if (bm == null) {
25084580057e772b60433272af5cd691825748892693Leon Scroggins                        c.close();
25094580057e772b60433272af5cd691825748892693Leon Scroggins                        return;
25104580057e772b60433272af5cd691825748892693Leon Scroggins                    }
251189c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins                    bm.compress(Bitmap.CompressFormat.PNG, 100, os);
251289c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins                    values = new ContentValues();
251389c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins                    values.put(Browser.BookmarkColumns.THUMBNAIL,
251489c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins                            os.toByteArray());
251589c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins                }
251689c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins                cr.update(ContentUris.withAppendedId(Browser.BOOKMARKS_URI,
251789c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins                        c.getInt(0)), values, null, null);
251889c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins                succeed = c.moveToNext();
251989c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins            }
252089c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins            c.close();
252189c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins        }
252289c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins    }
252389c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins
252406ec5f2d8735d1ba17b779deb0f8da032e0a62eaLeon Scroggins    /**
2525f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins     * Values for the size of the thumbnail created when taking a screenshot.
2526f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins     * Lazily initialized.  Instead of using these directly, use
2527f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins     * getDesiredThumbnailWidth() or getDesiredThumbnailHeight().
252806ec5f2d8735d1ba17b779deb0f8da032e0a62eaLeon Scroggins     */
2529f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins    private static int THUMBNAIL_WIDTH = 0;
2530f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins    private static int THUMBNAIL_HEIGHT = 0;
2531f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins
2532f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins    /**
2533f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins     * Return the desired width for thumbnail screenshots, which are stored in
2534f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins     * the database, and used on the bookmarks screen.
2535f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins     * @param context Context for finding out the density of the screen.
2536f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins     * @return int desired width for thumbnail screenshot.
2537f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins     */
2538f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins    /* package */ static int getDesiredThumbnailWidth(Context context) {
2539f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins        if (THUMBNAIL_WIDTH == 0) {
2540f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins            float density = context.getResources().getDisplayMetrics().density;
2541f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins            THUMBNAIL_WIDTH = (int) (90 * density);
2542f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins            THUMBNAIL_HEIGHT = (int) (80 * density);
2543f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins        }
2544f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins        return THUMBNAIL_WIDTH;
2545f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins    }
2546f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins
2547f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins    /**
2548f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins     * Return the desired height for thumbnail screenshots, which are stored in
2549f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins     * the database, and used on the bookmarks screen.
2550f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins     * @param context Context for finding out the density of the screen.
2551f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins     * @return int desired height for thumbnail screenshot.
2552f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins     */
2553f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins    /* package */ static int getDesiredThumbnailHeight(Context context) {
2554f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins        // To ensure that they are both initialized.
2555f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins        getDesiredThumbnailWidth(context);
2556f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins        return THUMBNAIL_HEIGHT;
2557f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins    }
255806ec5f2d8735d1ba17b779deb0f8da032e0a62eaLeon Scroggins
2559dcc2b6f08dd5677bc6ba761a9ba6f1c655113051Ben Murdoch    private Bitmap createScreenshot(WebView view) {
2560dcc2b6f08dd5677bc6ba761a9ba6f1c655113051Ben Murdoch        Picture thumbnail = view.capturePicture();
25614580057e772b60433272af5cd691825748892693Leon Scroggins        if (thumbnail == null) {
25624580057e772b60433272af5cd691825748892693Leon Scroggins            return null;
25634580057e772b60433272af5cd691825748892693Leon Scroggins        }
2564f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins        Bitmap bm = Bitmap.createBitmap(getDesiredThumbnailWidth(this),
2565f85516172840450a4d1270b658905dc1649ceaf2Leon Scroggins                getDesiredThumbnailHeight(this), Bitmap.Config.ARGB_4444);
2566dcc2b6f08dd5677bc6ba761a9ba6f1c655113051Ben Murdoch        Canvas canvas = new Canvas(bm);
2567dcc2b6f08dd5677bc6ba761a9ba6f1c655113051Ben Murdoch        // May need to tweak these values to determine what is the
2568dcc2b6f08dd5677bc6ba761a9ba6f1c655113051Ben Murdoch        // best scale factor
25692694e23a55d5ca526fc29534a80a200e2c58698bBen Murdoch        int thumbnailWidth = thumbnail.getWidth();
2570ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch        int thumbnailHeight = thumbnail.getHeight();
2571ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch        float scaleFactorX = 1.0f;
2572ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch        float scaleFactorY = 1.0f;
25732694e23a55d5ca526fc29534a80a200e2c58698bBen Murdoch        if (thumbnailWidth > 0) {
2574ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch            scaleFactorX = (float) getDesiredThumbnailWidth(this) /
25752694e23a55d5ca526fc29534a80a200e2c58698bBen Murdoch                    (float)thumbnailWidth;
2576ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch        } else {
2577ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch            return null;
257806ec5f2d8735d1ba17b779deb0f8da032e0a62eaLeon Scroggins        }
2579ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch
2580ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch        if (view.getWidth() > view.getHeight() &&
2581ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch                thumbnailHeight < view.getHeight() && thumbnailHeight > 0) {
2582ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch            // If the device is in landscape and the page is shorter
2583ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch            // than the height of the view, stretch the thumbnail to fill the
2584ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch            // space.
2585ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch            scaleFactorY = (float) getDesiredThumbnailHeight(this) /
2586ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch                    (float)thumbnailHeight;
2587ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch        } else {
2588ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch            // In the portrait case, this looks nice.
2589ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch            scaleFactorY = scaleFactorX;
2590ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch        }
2591ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch
2592ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch        canvas.scale(scaleFactorX, scaleFactorY);
2593ae59c3f5a5b492f91d72e1d26702a13b91a43fa4Ben Murdoch
2594dcc2b6f08dd5677bc6ba761a9ba6f1c655113051Ben Murdoch        thumbnail.draw(canvas);
2595dcc2b6f08dd5677bc6ba761a9ba6f1c655113051Ben Murdoch        return bm;
2596dcc2b6f08dd5677bc6ba761a9ba6f1c655113051Ben Murdoch    }
2597dcc2b6f08dd5677bc6ba761a9ba6f1c655113051Ben Murdoch
25980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // -------------------------------------------------------------------------
259922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // Helper function for WebViewClient.
26000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    //-------------------------------------------------------------------------
26010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
26020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Use in overrideUrlLoading
26030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /* package */ final static String SCHEME_WTAI = "wtai://wp/";
26040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /* package */ final static String SCHEME_WTAI_MC = "wtai://wp/mc;";
26050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /* package */ final static String SCHEME_WTAI_SD = "wtai://wp/sd;";
26060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /* package */ final static String SCHEME_WTAI_AP = "wtai://wp/ap;";
26070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
260822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void onPageStarted(WebView view, String url, Bitmap favicon) {
260922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // when BrowserActivity just starts, onPageStarted may be called before
261022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // onResume as it is triggered from onCreate. Call resumeWebViewTimers
261122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // to start the timer. As we won't switch tabs while an activity is in
261222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // pause state, we can ensure calling resume and pause in pair.
261322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mActivityInPause) resumeWebViewTimers();
261422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
261522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        resetLockIcon(url);
261622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        setUrlTitle(url, null);
261722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        setFavicon(favicon);
26188cf8f682e90f004d4b8028d2f5b74f72c0cf4e19Leon Scroggins        // Keep this initial progress in sync with initialProgressValue (* 100)
26198cf8f682e90f004d4b8028d2f5b74f72c0cf4e19Leon Scroggins        // in ProgressTracker.cpp
26208cf8f682e90f004d4b8028d2f5b74f72c0cf4e19Leon Scroggins        // Show some progress so that the user knows the page is beginning to
26218cf8f682e90f004d4b8028d2f5b74f72c0cf4e19Leon Scroggins        // load
26228cf8f682e90f004d4b8028d2f5b74f72c0cf4e19Leon Scroggins        onProgressChanged(view, 10);
262322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mDidStopLoad = false;
262422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (!mIsNetworkUp) createAndShowNetworkDialog();
26250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
262622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mSettings.isTracing()) {
262722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            String host;
262822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            try {
262922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                WebAddress uri = new WebAddress(url);
263022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                host = uri.mHost;
263122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            } catch (android.net.ParseException ex) {
263222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                host = "browser";
263322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
263422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            host = host.replace('.', '_');
263522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            host += ".trace";
263622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mInTrace = true;
263722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            Debug.startMethodTracing(host, 20 * 1024 * 1024);
263815525d48024d325c8a52766d8ca727191251a8d4Patrick Scott        }
263915525d48024d325c8a52766d8ca727191251a8d4Patrick Scott
264022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Performance probe
264122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (false) {
264222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mStart = SystemClock.uptimeMillis();
264322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mProcessStart = Process.getElapsedCpuTime();
264422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            long[] sysCpu = new long[7];
264522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (Process.readProcFile("/proc/stat", SYSTEM_CPU_FORMAT, null,
264622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    sysCpu, null)) {
264722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                mUserStart = sysCpu[0] + sysCpu[1];
264822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                mSystemStart = sysCpu[2];
264922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                mIdleStart = sysCpu[3];
265022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                mIrqStart = sysCpu[4] + sysCpu[5] + sysCpu[6];
265122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
265222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mUiStart = SystemClock.currentThreadTimeMillis();
26530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
26540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
26550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
265622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void onPageFinished(WebView view, String url) {
265722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Reset the title and icon in case we stopped a provisional load.
265822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        resetTitleAndIcon(view);
265922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Update the lock icon image only once we are done loading
266022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        updateLockIconToLatest();
266122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // pause the WebView timer and release the wake lock if it is finished
266222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // while BrowserActivity is in pause state.
266322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mActivityInPause && pauseWebViewTimers()) {
266422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (mWakeLock.isHeld()) {
266522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                mHandler.removeMessages(RELEASE_WAKELOCK);
266622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                mWakeLock.release();
266722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            }
266822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
266922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
267022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Performance probe
267122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (false) {
267222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            long[] sysCpu = new long[7];
267322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (Process.readProcFile("/proc/stat", SYSTEM_CPU_FORMAT, null,
267422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    sysCpu, null)) {
267522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                String uiInfo = "UI thread used "
267622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        + (SystemClock.currentThreadTimeMillis() - mUiStart)
267722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        + " ms";
267822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                if (LOGD_ENABLED) {
267922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    Log.d(LOGTAG, uiInfo);
268022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                }
268122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                //The string that gets written to the log
268222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                String performanceString = "It took total "
268322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        + (SystemClock.uptimeMillis() - mStart)
268422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        + " ms clock time to load the page."
268522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        + "\nbrowser process used "
268622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        + (Process.getElapsedCpuTime() - mProcessStart)
268722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        + " ms, user processes used "
268822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        + (sysCpu[0] + sysCpu[1] - mUserStart) * 10
268922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        + " ms, kernel used "
269022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        + (sysCpu[2] - mSystemStart) * 10
269122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        + " ms, idle took " + (sysCpu[3] - mIdleStart) * 10
269222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        + " ms and irq took "
269322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        + (sysCpu[4] + sysCpu[5] + sysCpu[6] - mIrqStart)
269422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        * 10 + " ms, " + uiInfo;
269522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                if (LOGD_ENABLED) {
269622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    Log.d(LOGTAG, performanceString + "\nWebpage: " + url);
26970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
269822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                if (url != null) {
269922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    // strip the url to maintain consistency
270022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    String newUrl = new String(url);
270122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    if (newUrl.startsWith("http://www.")) {
270222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        newUrl = newUrl.substring(11);
270322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    } else if (newUrl.startsWith("http://")) {
270422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        newUrl = newUrl.substring(7);
270522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    } else if (newUrl.startsWith("https://www.")) {
270622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        newUrl = newUrl.substring(12);
270722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    } else if (newUrl.startsWith("https://")) {
270822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        newUrl = newUrl.substring(8);
27090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
271031a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort                    if (LOGD_ENABLED) {
271122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        Log.d(LOGTAG, newUrl + " loaded");
27120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
27130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
27140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
271522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba         }
27160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
271722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mInTrace) {
271822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mInTrace = false;
271922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            Debug.stopMethodTracing();
27200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
272122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
27220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
272322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    boolean shouldOverrideUrlLoading(WebView view, String url) {
272422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (url.startsWith(SCHEME_WTAI)) {
272522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // wtai://wp/mc;number
272622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // number=string(phone-number)
272722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (url.startsWith(SCHEME_WTAI_MC)) {
272822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                Intent intent = new Intent(Intent.ACTION_VIEW,
272922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        Uri.parse(WebView.SCHEME_TEL +
273022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        url.substring(SCHEME_WTAI_MC.length())));
273122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                startActivity(intent);
273222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                return true;
27330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
273422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // wtai://wp/sd;dtmf
273522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // dtmf=string(dialstring)
273622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (url.startsWith(SCHEME_WTAI_SD)) {
273722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                // TODO: only send when there is active voice connection
27389918943559193e3e047a1c18442e2cdb0fe22b15Dianne Hackborn                return false;
27399918943559193e3e047a1c18442e2cdb0fe22b15Dianne Hackborn            }
274022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // wtai://wp/ap;number;name
274122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // number=string(phone-number)
274222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // name=string
274322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (url.startsWith(SCHEME_WTAI_AP)) {
274422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                // TODO
27450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                return false;
27460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
27470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
27480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
274922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // The "about:" schemes are internal to the browser; don't want these to
275022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // be dispatched to other apps.
275122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (url.startsWith("about:")) {
275222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            return false;
27530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
27540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
275522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        Intent intent;
275622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // perform generic parsing of the URI to turn it into an Intent.
275722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        try {
275822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            intent = Intent.parseUri(url, Intent.URI_INTENT_SCHEME);
275922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        } catch (URISyntaxException ex) {
276022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            Log.w("Browser", "Bad URI " + url + ": " + ex.getMessage());
276122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            return false;
27620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
27630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
276422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // check whether the intent can be resolved. If not, we will see
276522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // whether we can download it from the Market.
276622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (getPackageManager().resolveActivity(intent, 0) == null) {
276722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            String packagename = intent.getPackage();
276822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (packagename != null) {
276922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                intent = new Intent(Intent.ACTION_VIEW, Uri
277022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        .parse("market://search?q=pname:" + packagename));
277122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                intent.addCategory(Intent.CATEGORY_BROWSABLE);
277222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                startActivity(intent);
277322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                return true;
27740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } else {
27750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                return false;
27760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
27770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
27780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
277922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // sanitize the Intent, ensuring web pages can not bypass browser
278022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // security (only access to BROWSABLE activities).
278122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        intent.addCategory(Intent.CATEGORY_BROWSABLE);
278222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        intent.setComponent(null);
278322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        try {
278422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (startActivityIfNeeded(intent, -1)) {
27850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                return true;
27860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
278722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        } catch (ActivityNotFoundException ex) {
278822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // ignore the error. If no application can handle the URL,
278922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // eg about:blank, assume the browser can handle it.
279022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        }
27910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
279222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mMenuIsDown) {
279322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            openTab(url);
279422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            closeOptionsMenu();
27950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return true;
27960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
279722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return false;
279822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
27990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
280022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // -------------------------------------------------------------------------
280122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // Helper function for WebChromeClient
280222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // -------------------------------------------------------------------------
28030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
280422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void onProgressChanged(WebView view, int newProgress) {
280522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mTitleBar.setProgress(newProgress);
280622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mFakeTitleBar.setProgress(newProgress);
280722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
280822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (newProgress == 100) {
280922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // onProgressChanged() may continue to be called after the main
281022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // frame has finished loading, as any remaining sub frames continue
281122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // to load. We'll only get called once though with newProgress as
281222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // 100 when everything is loaded. (onPageFinished is called once
281322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // when the main frame completes loading regardless of the state of
281422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // any sub frames so calls to onProgressChanges may continue after
281522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // onPageFinished has executed)
281622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (mInLoad) {
281722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                mInLoad = false;
2818a27ff19e24cb1c9fef5624dbc4554548349b5b31Leon Scroggins                updateInLoadMenuItems();
281922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                // If the options menu is open, leave the title bar
282022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                if (!mOptionsMenuOpen || !mIconView) {
282122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    hideFakeTitleBar();
28220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
28230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
282422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        } else if (!mInLoad) {
282522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // onPageFinished may have already been called but a subframe is
282622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // still loading and updating the progress. Reset mInLoad and update
282722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            // the menu items.
282822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mInLoad = true;
282922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            updateInLoadMenuItems();
283022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (!mOptionsMenuOpen || mIconView) {
283122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                // This page has begun to load, so show the title bar
283222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                showFakeTitleBar();
28333918d4443ff38ef1870e02aa51a8b29f8352bb1aPatrick Scott            }
28340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
283522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
2836092dd5d22d7f2ee0efcc68bd6e5a3afd1ea98953Ben Murdoch
283722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void onShowCustomView(View view, WebChromeClient.CustomViewCallback callback) {
28388ff57db0a8dc8eb659fbcdcd4a856208609e6070Derek Sollenberger        // if a view already exists then immediately terminate the new one
28398ff57db0a8dc8eb659fbcdcd4a856208609e6070Derek Sollenberger        if (mCustomView != null) {
28408ff57db0a8dc8eb659fbcdcd4a856208609e6070Derek Sollenberger            callback.onCustomViewHidden();
284122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            return;
28428ff57db0a8dc8eb659fbcdcd4a856208609e6070Derek Sollenberger        }
28432bc69918d97a767a02132090e58718077381ba1aSteve Block
284422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Add the custom view to its container.
284522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mCustomViewContainer.addView(view, COVER_SCREEN_GRAVITY_CENTER);
284622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mCustomView = view;
284722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mCustomViewCallback = callback;
284822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Save the menu state and set it to empty while the custom
284922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // view is showing.
285022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mOldMenuState = mMenuState;
285122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mMenuState = EMPTY_MENU;
285222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Hide the content view.
285322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mContentView.setVisibility(View.GONE);
285422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Finally show the custom view container.
2855163ab74e2f85b53a1a374c49677073fb64d35f28Andrei Popescu        setStatusBarVisibility(false);
285622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mCustomViewContainer.setVisibility(View.VISIBLE);
285722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mCustomViewContainer.bringToFront();
285822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
285922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
286022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void onHideCustomView() {
286122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mCustomView == null)
286222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            return;
28632bc69918d97a767a02132090e58718077381ba1aSteve Block
286422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Hide the custom view.
286522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mCustomView.setVisibility(View.GONE);
286622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Remove the custom view from its container.
286722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mCustomViewContainer.removeView(mCustomView);
286822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mCustomView = null;
286922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Reset the old menu state.
287022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mMenuState = mOldMenuState;
287122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mOldMenuState = EMPTY_MENU;
287222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mCustomViewContainer.setVisibility(View.GONE);
287322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mCustomViewCallback.onCustomViewHidden();
287422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        // Show the content view.
2875163ab74e2f85b53a1a374c49677073fb64d35f28Andrei Popescu        setStatusBarVisibility(true);
287622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mContentView.setVisibility(View.VISIBLE);
287722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
2878540035dfd1347c78eeec10ec0847e18fcc50ef36Andrei Popescu
287922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    Bitmap getDefaultVideoPoster() {
288022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mDefaultVideoPoster == null) {
288122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mDefaultVideoPoster = BitmapFactory.decodeResource(
288222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    getResources(), R.drawable.default_video_poster);
2883540035dfd1347c78eeec10ec0847e18fcc50ef36Andrei Popescu        }
288422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return mDefaultVideoPoster;
288522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
2886540035dfd1347c78eeec10ec0847e18fcc50ef36Andrei Popescu
288722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    View getVideoLoadingProgressView() {
288822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mVideoProgressView == null) {
288922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            LayoutInflater inflater = LayoutInflater.from(BrowserActivity.this);
289022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            mVideoProgressView = inflater.inflate(
289122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                    R.layout.video_loading_progress, null);
2892540035dfd1347c78eeec10ec0847e18fcc50ef36Andrei Popescu        }
289322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return mVideoProgressView;
289422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
28950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
28968d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins    /*
28978d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins     * The Object used to inform the WebView of the file to upload.
28988d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins     */
28998d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins    private ValueCallback<Uri> mUploadMessage;
29008d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins
290122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void openFileChooser(ValueCallback<Uri> uploadMsg) {
290222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        if (mUploadMessage != null) return;
290322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mUploadMessage = uploadMsg;
290422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        Intent i = new Intent(Intent.ACTION_GET_CONTENT);
290522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        i.addCategory(Intent.CATEGORY_OPENABLE);
290622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        i.setType("*/*");
290722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        BrowserActivity.this.startActivityForResult(Intent.createChooser(i,
290822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                getString(R.string.choose_upload)), FILE_SELECTED);
290922ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
291022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
291122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // -------------------------------------------------------------------------
291222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // Implement functions for DownloadListener
291322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // -------------------------------------------------------------------------
291422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
29150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
29160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Notify the host application a download should be done, or that
29170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * the data should be streamed if a streaming viewer is available.
29180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param url The full url to the content that should be downloaded
29190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param contentDisposition Content-disposition http header, if
29200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *                           present.
29210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param mimetype The mimetype of the content reported by the server
29220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param contentLength The file size reported by the server
29230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
29240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public void onDownloadStart(String url, String userAgent,
29250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            String contentDisposition, String mimetype, long contentLength) {
29260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // if we're dealing wih A/V content that's not explicitly marked
29270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        //     for download, check if it's streamable.
29280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (contentDisposition == null
2929e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                || !contentDisposition.regionMatches(
2930e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                        true, 0, "attachment", 0, 10)) {
29310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // query the package manager to see if there's a registered handler
29320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            //     that matches.
29330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Intent intent = new Intent(Intent.ACTION_VIEW);
29340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            intent.setDataAndType(Uri.parse(url), mimetype);
2935e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott            ResolveInfo info = getPackageManager().resolveActivity(intent,
2936e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                    PackageManager.MATCH_DEFAULT_ONLY);
2937e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott            if (info != null) {
2938e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                ComponentName myName = getComponentName();
2939e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                // If we resolved to ourselves, we don't want to attempt to
2940e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                // load the url only to try and download it again.
2941e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                if (!myName.getPackageName().equals(
2942e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                        info.activityInfo.packageName)
2943e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                        || !myName.getClassName().equals(
2944e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                                info.activityInfo.name)) {
2945e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                    // someone (other than us) knows how to handle this mime
2946e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                    // type with this scheme, don't download.
2947e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                    try {
2948e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                        startActivity(intent);
2949e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                        return;
2950e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                    } catch (ActivityNotFoundException ex) {
2951e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                        if (LOGD_ENABLED) {
2952e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                            Log.d(LOGTAG, "activity not found for " + mimetype
2953e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                                    + " over " + Uri.parse(url).getScheme(),
2954e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                                    ex);
2955e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                        }
2956e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                        // Best behavior is to fall back to a download in this
2957e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                        // case
29580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
29590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
29600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
29610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
29620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        onDownloadStartNoStream(url, userAgent, contentDisposition, mimetype, contentLength);
29630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
29640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
29650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
29660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Notify the host application a download should be done, even if there
29670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * is a streaming viewer available for thise type.
29680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param url The full url to the content that should be downloaded
29690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param contentDisposition Content-disposition http header, if
29700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *                           present.
29710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param mimetype The mimetype of the content reported by the server
29720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param contentLength The file size reported by the server
29730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
29740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /*package */ void onDownloadStartNoStream(String url, String userAgent,
29750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            String contentDisposition, String mimetype, long contentLength) {
29760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
29770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String filename = URLUtil.guessFileName(url,
29780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                contentDisposition, mimetype);
29790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
29800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Check to see if we have an SDCard
29810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String status = Environment.getExternalStorageState();
29820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (!status.equals(Environment.MEDIA_MOUNTED)) {
29830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            int title;
29840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            String msg;
29850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
29860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Check to see if the SDCard is busy, same as the music app
29870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (status.equals(Environment.MEDIA_SHARED)) {
29880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                msg = getString(R.string.download_sdcard_busy_dlg_msg);
29890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                title = R.string.download_sdcard_busy_dlg_title;
29900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } else {
29910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                msg = getString(R.string.download_no_sdcard_dlg_msg, filename);
29920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                title = R.string.download_no_sdcard_dlg_title;
29930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
29940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
29950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            new AlertDialog.Builder(this)
29960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setTitle(title)
29970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setIcon(android.R.drawable.ic_dialog_alert)
29980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setMessage(msg)
29990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setPositiveButton(R.string.ok, null)
30000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .show();
30010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
30020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
30030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
30040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // java.net.URI is a lot stricter than KURL so we have to undo
30050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // KURL's percent-encoding and redo the encoding using java.net.URI.
30060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        URI uri = null;
30070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        try {
30080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Undo the percent-encoding that KURL may have done.
30090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            String newUrl = new String(URLUtil.decode(url.getBytes()));
30100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Parse the url into pieces
30110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            WebAddress w = new WebAddress(newUrl);
30120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            String frag = null;
30130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            String query = null;
30140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            String path = w.mPath;
30150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Break the path into path, query, and fragment
30160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (path.length() > 0) {
30170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // Strip the fragment
30180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                int idx = path.lastIndexOf('#');
30190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (idx != -1) {
30200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    frag = path.substring(idx + 1);
30210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    path = path.substring(0, idx);
30220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
30230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                idx = path.lastIndexOf('?');
30240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (idx != -1) {
30250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    query = path.substring(idx + 1);
30260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    path = path.substring(0, idx);
30270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
30280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
30290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            uri = new URI(w.mScheme, w.mAuthInfo, w.mHost, w.mPort, path,
30300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    query, frag);
30310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } catch (Exception e) {
30320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Log.e(LOGTAG, "Could not parse url for download: " + url, e);
30330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
30340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
30350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
30360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // XXX: Have to use the old url since the cookies were stored using the
30370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // old percent-encoded url.
30380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String cookies = CookieManager.getInstance().getCookie(url);
30390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
30400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        ContentValues values = new ContentValues();
30411e5bad97ca8fb9b12501f4f747941d02f03e1362Jean-Baptiste Queru        values.put(Downloads.Impl.COLUMN_URI, uri.toString());
30421e5bad97ca8fb9b12501f4f747941d02f03e1362Jean-Baptiste Queru        values.put(Downloads.Impl.COLUMN_COOKIE_DATA, cookies);
30431e5bad97ca8fb9b12501f4f747941d02f03e1362Jean-Baptiste Queru        values.put(Downloads.Impl.COLUMN_USER_AGENT, userAgent);
30441e5bad97ca8fb9b12501f4f747941d02f03e1362Jean-Baptiste Queru        values.put(Downloads.Impl.COLUMN_NOTIFICATION_PACKAGE,
30450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                getPackageName());
30461e5bad97ca8fb9b12501f4f747941d02f03e1362Jean-Baptiste Queru        values.put(Downloads.Impl.COLUMN_NOTIFICATION_CLASS,
30470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                BrowserDownloadPage.class.getCanonicalName());
30481e5bad97ca8fb9b12501f4f747941d02f03e1362Jean-Baptiste Queru        values.put(Downloads.Impl.COLUMN_VISIBILITY,
30491e5bad97ca8fb9b12501f4f747941d02f03e1362Jean-Baptiste Queru                Downloads.Impl.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
30501e5bad97ca8fb9b12501f4f747941d02f03e1362Jean-Baptiste Queru        values.put(Downloads.Impl.COLUMN_MIME_TYPE, mimetype);
30511e5bad97ca8fb9b12501f4f747941d02f03e1362Jean-Baptiste Queru        values.put(Downloads.Impl.COLUMN_FILE_NAME_HINT, filename);
30521e5bad97ca8fb9b12501f4f747941d02f03e1362Jean-Baptiste Queru        values.put(Downloads.Impl.COLUMN_DESCRIPTION, uri.getHost());
30530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (contentLength > 0) {
30541e5bad97ca8fb9b12501f4f747941d02f03e1362Jean-Baptiste Queru            values.put(Downloads.Impl.COLUMN_TOTAL_BYTES, contentLength);
30550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
30560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mimetype == null) {
30570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // We must have long pressed on a link or image to download it. We
30580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // are not sure of the mimetype in this case, so do a head request
30590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            new FetchUrlMimeType(this).execute(values);
30600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
30610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            final Uri contentUri =
30621e5bad97ca8fb9b12501f4f747941d02f03e1362Jean-Baptiste Queru                    getContentResolver().insert(Downloads.Impl.CONTENT_URI, values);
30630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
30640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
30650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
30660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
306722ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    // -------------------------------------------------------------------------
306822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
30690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
30700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Resets the lock icon. This method is called when we start a new load and
30710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * know the url to be loaded.
30720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
30730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void resetLockIcon(String url) {
30740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Save the lock-icon state (we revert to it if the load gets cancelled)
307522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        mTabControl.getCurrentTab().resetLockIcon(url);
30760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        updateLockIconImage(LOCK_ICON_UNSECURE);
30770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
30780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
30790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
30803bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     * Update the lock icon to correspond to our latest state.
30813bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     */
308222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private void updateLockIconToLatest() {
308322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        updateLockIconImage(mTabControl.getCurrentTab().getLockIconType());
30843bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    }
30853bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins
30863bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    /**
30870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Updates the lock-icon image in the title-bar.
30880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
30890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void updateLockIconImage(int lockIconType) {
30900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        Drawable d = null;
30910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (lockIconType == LOCK_ICON_SECURE) {
30920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            d = mSecLockIcon;
30930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else if (lockIconType == LOCK_ICON_MIXED) {
30940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            d = mMixLockIcon;
30950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
309668579393973f745fc65a2781061af9bb8f2d7020Leon Scroggins        mTitleBar.setLock(d);
3097fe87bd3a3897e4bad65bb3d284659ae2f4e57570Leon Scroggins        mFakeTitleBar.setLock(d);
30980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
30990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
31000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
31010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Displays a page-info dialog.
31020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param tab The tab to show info about
31030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param fromShowSSLCertificateOnError The flag that indicates whether
31040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * this dialog was opened from the SSL-certificate-on-error dialog or
31050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * not. This is important, since we need to know whether to return to
31060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * the parent dialog or simply dismiss.
31070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
310822ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private void showPageInfo(final Tab tab,
31090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                              final boolean fromShowSSLCertificateOnError) {
31100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final LayoutInflater factory = LayoutInflater
31110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .from(this);
31120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
31130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final View pageInfoView = factory.inflate(R.layout.page_info, null);
31140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
31150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final WebView view = tab.getWebView();
31160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
31170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String url = null;
31180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String title = null;
31190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
31200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (view == null) {
31210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            url = tab.getUrl();
31220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            title = tab.getTitle();
31230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else if (view == mTabControl.getCurrentWebView()) {
31240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project             // Use the cached title and url if this is the current WebView
31250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            url = mUrl;
31260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            title = mTitle;
31270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
31280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            url = view.getUrl();
31290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            title = view.getTitle();
31300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
31310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
31320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (url == null) {
31330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            url = "";
31340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
31350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (title == null) {
31360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            title = "";
31370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
31380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
31390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        ((TextView) pageInfoView.findViewById(R.id.address)).setText(url);
31400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        ((TextView) pageInfoView.findViewById(R.id.title)).setText(title);
31410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
31420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mPageInfoView = tab;
3143c7b92f811dfa3572578ddc6714c98a03936d9ce5Leon Scroggins        mPageInfoFromShowSSLCertificateOnError = fromShowSSLCertificateOnError;
31440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
31450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        AlertDialog.Builder alertDialogBuilder =
31460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            new AlertDialog.Builder(this)
31470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            .setTitle(R.string.page_info).setIcon(android.R.drawable.ic_dialog_info)
31480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            .setView(pageInfoView)
31490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            .setPositiveButton(
31500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                R.string.ok,
31510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                new DialogInterface.OnClickListener() {
31520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    public void onClick(DialogInterface dialog,
31530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        int whichButton) {
31540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        mPageInfoDialog = null;
31550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        mPageInfoView = null;
31560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
31570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        // if we came here from the SSL error dialog
31580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        if (fromShowSSLCertificateOnError) {
31590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            // go back to the SSL error dialog
31600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            showSSLCertificateOnError(
31610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorView,
31620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorHandler,
31630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorError);
31640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }
31650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
31660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                })
31670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            .setOnCancelListener(
31680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                new DialogInterface.OnCancelListener() {
31690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    public void onCancel(DialogInterface dialog) {
31700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        mPageInfoDialog = null;
31710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        mPageInfoView = null;
31720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
31730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        // if we came here from the SSL error dialog
31740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        if (fromShowSSLCertificateOnError) {
31750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            // go back to the SSL error dialog
31760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            showSSLCertificateOnError(
31770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorView,
31780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorHandler,
31790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorError);
31800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }
31810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
31820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                });
31830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
31840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // if we have a main top-level page SSL certificate set or a certificate
31850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // error
31860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (fromShowSSLCertificateOnError ||
31870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                (view != null && view.getCertificate() != null)) {
31880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // add a 'View Certificate' button
31890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            alertDialogBuilder.setNeutralButton(
31900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                R.string.view_certificate,
31910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                new DialogInterface.OnClickListener() {
31920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    public void onClick(DialogInterface dialog,
31930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        int whichButton) {
31940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        mPageInfoDialog = null;
31950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        mPageInfoView = null;
31960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
31970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        // if we came here from the SSL error dialog
31980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        if (fromShowSSLCertificateOnError) {
31990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            // go back to the SSL error dialog
32000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            showSSLCertificateOnError(
32010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorView,
32020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorHandler,
32030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorError);
32040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        } else {
32050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            // otherwise, display the top-most certificate from
32060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            // the chain
32070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            if (view.getCertificate() != null) {
32080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                showSSLCertificate(tab);
32090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            }
32100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }
32110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
32120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                });
32130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
32140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
32150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mPageInfoDialog = alertDialogBuilder.show();
32160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
32170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
32180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project       /**
32190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Displays the main top-level page SSL certificate dialog
32200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * (accessible from the Page-Info dialog).
32210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param tab The tab to show certificate for.
32220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
322322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private void showSSLCertificate(final Tab tab) {
32240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final View certificateView =
32250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                inflateCertificateView(tab.getWebView().getCertificate());
32260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (certificateView == null) {
32270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
32280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
32290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
32300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        LayoutInflater factory = LayoutInflater.from(this);
32310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
32320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final LinearLayout placeholder =
32330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                (LinearLayout)certificateView.findViewById(R.id.placeholder);
32340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
32350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        LinearLayout ll = (LinearLayout) factory.inflate(
32360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            R.layout.ssl_success, placeholder);
32370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        ((TextView)ll.findViewById(R.id.success))
32380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            .setText(R.string.ssl_certificate_is_valid);
32390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
32400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mSSLCertificateView = tab;
32410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mSSLCertificateDialog =
32420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            new AlertDialog.Builder(this)
32430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setTitle(R.string.ssl_certificate).setIcon(
32440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    R.drawable.ic_dialog_browser_certificate_secure)
32450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setView(certificateView)
32460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setPositiveButton(R.string.ok,
32470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new DialogInterface.OnClickListener() {
32480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            public void onClick(DialogInterface dialog,
32490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    int whichButton) {
32500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateDialog = null;
32510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateView = null;
32520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
32530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                showPageInfo(tab, false);
32540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            }
32550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        })
32560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setOnCancelListener(
32570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new DialogInterface.OnCancelListener() {
32580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            public void onCancel(DialogInterface dialog) {
32590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateDialog = null;
32600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateView = null;
32610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
32620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                showPageInfo(tab, false);
32630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            }
32640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        })
32650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .show();
32660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
32670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
32680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
32690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Displays the SSL error certificate dialog.
32700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param view The target web-view.
32710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param handler The SSL error handler responsible for cancelling the
32720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * connection that resulted in an SSL error or proceeding per user request.
32730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param error The SSL error object.
32740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
327522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void showSSLCertificateOnError(
32760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final WebView view, final SslErrorHandler handler, final SslError error) {
32770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
32780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final View certificateView =
32790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            inflateCertificateView(error.getCertificate());
32800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (certificateView == null) {
32810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
32820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
32830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
32840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        LayoutInflater factory = LayoutInflater.from(this);
32850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
32860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final LinearLayout placeholder =
32870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                (LinearLayout)certificateView.findViewById(R.id.placeholder);
32880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
32890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (error.hasError(SslError.SSL_UNTRUSTED)) {
32900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            LinearLayout ll = (LinearLayout)factory
32910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .inflate(R.layout.ssl_warning, placeholder);
32920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((TextView)ll.findViewById(R.id.warning))
32930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setText(R.string.ssl_untrusted);
32940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
32950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
32960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (error.hasError(SslError.SSL_IDMISMATCH)) {
32970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            LinearLayout ll = (LinearLayout)factory
32980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .inflate(R.layout.ssl_warning, placeholder);
32990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((TextView)ll.findViewById(R.id.warning))
33000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setText(R.string.ssl_mismatch);
33010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
33020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
33030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (error.hasError(SslError.SSL_EXPIRED)) {
33040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            LinearLayout ll = (LinearLayout)factory
33050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .inflate(R.layout.ssl_warning, placeholder);
33060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((TextView)ll.findViewById(R.id.warning))
33070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setText(R.string.ssl_expired);
33080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
33090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
33100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (error.hasError(SslError.SSL_NOTYETVALID)) {
33110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            LinearLayout ll = (LinearLayout)factory
33120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .inflate(R.layout.ssl_warning, placeholder);
33130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((TextView)ll.findViewById(R.id.warning))
33140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setText(R.string.ssl_not_yet_valid);
33150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
33160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
33170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mSSLCertificateOnErrorHandler = handler;
33180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mSSLCertificateOnErrorView = view;
33190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mSSLCertificateOnErrorError = error;
33200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mSSLCertificateOnErrorDialog =
33210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            new AlertDialog.Builder(this)
33220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setTitle(R.string.ssl_certificate).setIcon(
33230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    R.drawable.ic_dialog_browser_certificate_partially_secure)
33240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setView(certificateView)
33250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setPositiveButton(R.string.ok,
33260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new DialogInterface.OnClickListener() {
33270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            public void onClick(DialogInterface dialog,
33280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    int whichButton) {
33290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorDialog = null;
33300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorView = null;
33310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorHandler = null;
33320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorError = null;
33330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
333422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                view.getWebViewClient().onReceivedSslError(
333522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                                view, handler, error);
33360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            }
33370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        })
33380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                 .setNeutralButton(R.string.page_info_view,
33390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new DialogInterface.OnClickListener() {
33400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            public void onClick(DialogInterface dialog,
33410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    int whichButton) {
33420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorDialog = null;
33430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
33440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                // do not clear the dialog state: we will
33450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                // need to show the dialog again once the
33460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                // user is done exploring the page-info details
33470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
33480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                showPageInfo(mTabControl.getTabFromView(view),
33490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        true);
33500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            }
33510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        })
33520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setOnCancelListener(
33530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new DialogInterface.OnCancelListener() {
33540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            public void onCancel(DialogInterface dialog) {
33550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorDialog = null;
33560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorView = null;
33570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorHandler = null;
33580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorError = null;
33590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
336022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                view.getWebViewClient().onReceivedSslError(
336122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                                                view, handler, error);
33620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            }
33630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        })
33640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .show();
33650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
33660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
33670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
33680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Inflates the SSL certificate view (helper method).
33690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param certificate The SSL certificate.
33700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @return The resultant certificate view with issued-to, issued-by,
33710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * issued-on, expires-on, and possibly other fields set.
33720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * If the input certificate is null, returns null.
33730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
33740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private View inflateCertificateView(SslCertificate certificate) {
33750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (certificate == null) {
33760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return null;
33770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
33780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
33790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        LayoutInflater factory = LayoutInflater.from(this);
33800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
33810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        View certificateView = factory.inflate(
33820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            R.layout.ssl_certificate, null);
33830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
33840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // issued to:
33850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        SslCertificate.DName issuedTo = certificate.getIssuedTo();
33860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (issuedTo != null) {
33870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((TextView) certificateView.findViewById(R.id.to_common))
33880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setText(issuedTo.getCName());
33890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((TextView) certificateView.findViewById(R.id.to_org))
33900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setText(issuedTo.getOName());
33910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((TextView) certificateView.findViewById(R.id.to_org_unit))
33920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setText(issuedTo.getUName());
33930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
33940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
33950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // issued by:
33960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        SslCertificate.DName issuedBy = certificate.getIssuedBy();
33970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (issuedBy != null) {
33980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((TextView) certificateView.findViewById(R.id.by_common))
33990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setText(issuedBy.getCName());
34000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((TextView) certificateView.findViewById(R.id.by_org))
34010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setText(issuedBy.getOName());
34020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((TextView) certificateView.findViewById(R.id.by_org_unit))
34030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setText(issuedBy.getUName());
34040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
34050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
34060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // issued on:
34070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String issuedOn = reformatCertificateDate(
34080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            certificate.getValidNotBefore());
34090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        ((TextView) certificateView.findViewById(R.id.issued_on))
34100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            .setText(issuedOn);
34110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
34120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // expires on:
34130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String expiresOn = reformatCertificateDate(
34140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            certificate.getValidNotAfter());
34150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        ((TextView) certificateView.findViewById(R.id.expires_on))
34160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            .setText(expiresOn);
34170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
34180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return certificateView;
34190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
34200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
34210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
34220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Re-formats the certificate date (Date.toString()) string to
34230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * a properly localized date string.
34240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @return Properly localized version of the certificate date string and
34250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * the original certificate date string if fails to localize.
34260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * If the original string is null, returns an empty string "".
34270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
34280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private String reformatCertificateDate(String certificateDate) {
34290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project      String reformattedDate = null;
34300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
34310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project      if (certificateDate != null) {
34320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project          Date date = null;
34330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project          try {
34340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project              date = java.text.DateFormat.getInstance().parse(certificateDate);
34350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project          } catch (ParseException e) {
34360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project              date = null;
34370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project          }
34380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
34390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project          if (date != null) {
34400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project              reformattedDate =
34410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                  DateFormat.getDateFormat(this).format(date);
34420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project          }
34430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project      }
34440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
34450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project      return reformattedDate != null ? reformattedDate :
34460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project          (certificateDate != null ? certificateDate : "");
34470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
34480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
34490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
34500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Displays an http-authentication dialog.
34510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
345222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    void showHttpAuthentication(final HttpAuthHandler handler,
34530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            final String host, final String realm, final String title,
34540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            final String name, final String password, int focusId) {
34550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        LayoutInflater factory = LayoutInflater.from(this);
34560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final View v = factory
34570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .inflate(R.layout.http_authentication, null);
34580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (name != null) {
34590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((EditText) v.findViewById(R.id.username_edit)).setText(name);
34600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
34610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (password != null) {
34620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((EditText) v.findViewById(R.id.password_edit)).setText(password);
34630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
34640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
34650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String titleText = title;
34660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (titleText == null) {
34670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            titleText = getText(R.string.sign_in_to).toString().replace(
34680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    "%s1", host).replace("%s2", realm);
34690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
34700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
34710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mHttpAuthHandler = handler;
34720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        AlertDialog dialog = new AlertDialog.Builder(this)
34730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setTitle(titleText)
34740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setIcon(android.R.drawable.ic_dialog_alert)
34750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setView(v)
34760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setPositiveButton(R.string.action,
34770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new DialogInterface.OnClickListener() {
34780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                             public void onClick(DialogInterface dialog,
34790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                     int whichButton) {
34800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                String nm = ((EditText) v
34810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        .findViewById(R.id.username_edit))
34820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        .getText().toString();
34830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                String pw = ((EditText) v
34840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        .findViewById(R.id.password_edit))
34850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        .getText().toString();
34860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                BrowserActivity.this.setHttpAuthUsernamePassword
34870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        (host, realm, nm, pw);
34880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                handler.proceed(nm, pw);
34890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mHttpAuthenticationDialog = null;
34900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mHttpAuthHandler = null;
34910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            }})
34920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setNegativeButton(R.string.cancel,
34930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new DialogInterface.OnClickListener() {
34940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            public void onClick(DialogInterface dialog,
34950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    int whichButton) {
34960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                handler.cancel();
34970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                BrowserActivity.this.resetTitleAndRevertLockIcon();
34980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mHttpAuthenticationDialog = null;
34990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mHttpAuthHandler = null;
35000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            }})
35010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setOnCancelListener(new DialogInterface.OnCancelListener() {
35020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        public void onCancel(DialogInterface dialog) {
35030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            handler.cancel();
35040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            BrowserActivity.this.resetTitleAndRevertLockIcon();
35050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            mHttpAuthenticationDialog = null;
35060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            mHttpAuthHandler = null;
35070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }})
35080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .create();
35090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Make the IME appear when the dialog is displayed if applicable.
35100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        dialog.getWindow().setSoftInputMode(
35110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);
35120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        dialog.show();
35130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (focusId != 0) {
35140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            dialog.findViewById(focusId).requestFocus();
35150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
35160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            v.findViewById(R.id.username_edit).requestFocus();
35170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
35180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mHttpAuthenticationDialog = dialog;
35190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
35200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
35210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public int getProgress() {
35220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebView w = mTabControl.getCurrentWebView();
35230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (w != null) {
35240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return w.getProgress();
35250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
35260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return 100;
35270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
35280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
35290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
35300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
35310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Set HTTP authentication password.
35320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *
35330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param host The host for the password
35340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param realm The realm for the password
35350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param username The username for the password. If it is null, it means
35360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *            password can't be saved.
35370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param password The password
35380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
35390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public void setHttpAuthUsernamePassword(String host, String realm,
35400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                            String username,
35410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                            String password) {
35420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebView w = mTabControl.getCurrentWebView();
35430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (w != null) {
35440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            w.setHttpAuthUsernamePassword(host, realm, username, password);
35450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
35460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
35470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
35480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
35490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * connectivity manager says net has come or gone... inform the user
35500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param up true if net has come up, false if net has gone down
35510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
35520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public void onNetworkToggle(boolean up) {
35530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (up == mIsNetworkUp) {
35540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
35550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else if (up) {
35560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mIsNetworkUp = true;
35570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (mAlertDialog != null) {
35580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mAlertDialog.cancel();
35590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mAlertDialog = null;
35600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
35610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
35620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mIsNetworkUp = false;
3563eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott            if (mInLoad) {
3564eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott                createAndShowNetworkDialog();
3565eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott           }
35660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
35670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebView w = mTabControl.getCurrentWebView();
35680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (w != null) {
35690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            w.setNetworkAvailable(up);
35700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
35710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
35720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
357322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    boolean isNetworkUp() {
357422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return mIsNetworkUp;
357522ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
357622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
3577eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott    // This method shows the network dialog alerting the user that the net is
3578eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott    // down. It will only show the dialog if mAlertDialog is null.
3579eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott    private void createAndShowNetworkDialog() {
3580eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott        if (mAlertDialog == null) {
3581eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott            mAlertDialog = new AlertDialog.Builder(this)
3582eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott                    .setTitle(R.string.loadSuspendedTitle)
3583eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott                    .setMessage(R.string.loadSuspended)
3584eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott                    .setPositiveButton(R.string.ok, null)
3585eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott                    .show();
3586eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott        }
3587eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott    }
3588eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott
35890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    @Override
35900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    protected void onActivityResult(int requestCode, int resultCode,
35910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    Intent intent) {
3592bb394f3e134b6e5898ef7ae861b75e95e618688fGrace Kloba        if (getTopWindow() == null) return;
3593bb394f3e134b6e5898ef7ae861b75e95e618688fGrace Kloba
35940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        switch (requestCode) {
35950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case COMBO_PAGE:
35960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (resultCode == RESULT_OK && intent != null) {
35970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    String data = intent.getAction();
35980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    Bundle extras = intent.getExtras();
35990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    if (extras != null && extras.getBoolean("new_window", false)) {
360025d3547e0df084f963e38c6a93c99b02bd619de3Leon Scroggins                        openTab(data);
36010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    } else {
360222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                        final Tab currentTab =
36030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mTabControl.getCurrentTab();
36041f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                        dismissSubWindow(currentTab);
36051f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                        if (data != null && data.length() != 0) {
36061f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                            getTopWindow().loadUrl(data);
36070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }
36080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
36090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
3610fde9746ac3055848e110c35f19ec5893c621f766Leon Scroggins                // Deliberately fall through to PREFERENCES_PAGE, since the
3611fde9746ac3055848e110c35f19ec5893c621f766Leon Scroggins                // same extra may be attached to the COMBO_PAGE
3612fde9746ac3055848e110c35f19ec5893c621f766Leon Scroggins            case PREFERENCES_PAGE:
3613fde9746ac3055848e110c35f19ec5893c621f766Leon Scroggins                if (resultCode == RESULT_OK && intent != null) {
3614fde9746ac3055848e110c35f19ec5893c621f766Leon Scroggins                    String action = intent.getStringExtra(Intent.EXTRA_TEXT);
3615fde9746ac3055848e110c35f19ec5893c621f766Leon Scroggins                    if (BrowserSettings.PREF_CLEAR_HISTORY.equals(action)) {
3616fde9746ac3055848e110c35f19ec5893c621f766Leon Scroggins                        mTabControl.removeParentChildRelationShips();
3617fde9746ac3055848e110c35f19ec5893c621f766Leon Scroggins                    }
3618fde9746ac3055848e110c35f19ec5893c621f766Leon Scroggins                }
36190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
36208d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins            // Choose a file from the file picker.
36218d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins            case FILE_SELECTED:
36228d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins                if (null == mUploadMessage) break;
36238d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins                Uri result = intent == null || resultCode != RESULT_OK ? null
36248d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins                        : intent.getData();
36258d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins                mUploadMessage.onReceiveValue(result);
36268d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins                mUploadMessage = null;
36278d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins                break;
36280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            default:
36290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
36300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
3631304442375719effd41dbd53ae62de7a8d0cec7d9Leon Scroggins        getTopWindow().requestFocus();
36320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
36330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
36340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /*
36350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * This method is called as a result of the user selecting the options
3636f08809b2cf7e502fef5965691a7fb6d7cf0322afLeon Scroggins     * menu to see the download window. It shows the download window on top of
3637f08809b2cf7e502fef5965691a7fb6d7cf0322afLeon Scroggins     * the current window.
36380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
3639f08809b2cf7e502fef5965691a7fb6d7cf0322afLeon Scroggins    private void viewDownloads(Uri downloadRecord) {
36400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        Intent intent = new Intent(this,
36410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                BrowserDownloadPage.class);
36420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        intent.setData(downloadRecord);
364322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        startActivityForResult(intent, BrowserActivity.DOWNLOAD_PAGE);
36440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
36450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
36460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
3647160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins    /**
3648160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins     * Open the Go page.
3649160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins     * @param startWithHistory If true, open starting on the history tab.
3650160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins     *                         Otherwise, start with the bookmarks tab.
3651160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins     */
3652304442375719effd41dbd53ae62de7a8d0cec7d9Leon Scroggins    /* package */ void bookmarksOrHistoryPicker(boolean startWithHistory) {
36530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebView current = mTabControl.getCurrentWebView();
36540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (current == null) {
36550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
36560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
36570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        Intent intent = new Intent(this,
36580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                CombinedBookmarkHistoryActivity.class);
36590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String title = current.getTitle();
36600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String url = current.getUrl();
3661dcc2b6f08dd5677bc6ba761a9ba6f1c655113051Ben Murdoch        Bitmap thumbnail = createScreenshot(current);
3662dcc2b6f08dd5677bc6ba761a9ba6f1c655113051Ben Murdoch
36630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Just in case the user opens bookmarks before a page finishes loading
36640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // so the current history item, and therefore the page, is null.
36650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (null == url) {
36660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            url = mLastEnteredUrl;
36670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // This can happen.
36680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (null == url) {
36690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                url = mSettings.getHomePage();
36700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
36710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
36720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // In case the web page has not yet received its associated title.
36730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (title == null) {
36740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            title = url;
36750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
36760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        intent.putExtra("title", title);
36770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        intent.putExtra("url", url);
3678dcc2b6f08dd5677bc6ba761a9ba6f1c655113051Ben Murdoch        intent.putExtra("thumbnail", thumbnail);
3679304442375719effd41dbd53ae62de7a8d0cec7d9Leon Scroggins        // Disable opening in a new window if we have maxed out the windows
368022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        intent.putExtra("disable_new_window", !mTabControl.canCreateNewTab());
36813918d4443ff38ef1870e02aa51a8b29f8352bb1aPatrick Scott        intent.putExtra("touch_icon_url", current.getTouchIconUrl());
36820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (startWithHistory) {
36830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            intent.putExtra(CombinedBookmarkHistoryActivity.STARTING_TAB,
36840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    CombinedBookmarkHistoryActivity.HISTORY_TAB);
36850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
36860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        startActivityForResult(intent, COMBO_PAGE);
36870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
36880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
36890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Called when loading from context menu or LOAD_URL message
36900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void loadURL(WebView view, String url) {
36910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // In case the user enters nothing.
36920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (url != null && url.length() != 0 && view != null) {
36930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            url = smartUrlFilter(url);
369422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba            if (!view.getWebViewClient().shouldOverrideUrlLoading(view, url)) {
36950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                view.loadUrl(url);
36960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
36970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
36980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
36990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
37000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private String smartUrlFilter(Uri inUri) {
37010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (inUri != null) {
37020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return smartUrlFilter(inUri.toString());
37030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
37040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return null;
37050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
37060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
3707b34f87a2e13af13d697130482af01b537ab7c5fdFeng Qian    protected static final Pattern ACCEPTED_URI_SCHEMA = Pattern.compile(
37080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            "(?i)" + // switch on case insensitive matching
37090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            "(" +    // begin group for schema
37100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            "(?:http|https|file):\\/\\/" +
371125ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima            "|(?:inline|data|about|content|javascript):" +
37120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ")" +
37130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            "(.*)" );
37140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
37150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
37160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Attempts to determine whether user input is a URL or search
37170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * terms.  Anything with a space is passed to search.
37180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *
37190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Converts to lowercase any mistakenly uppercased schema (i.e.,
37200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * "Http://" converts to "http://"
37210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *
37220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @return Original or modified URL
37230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *
37240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
37250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    String smartUrlFilter(String url) {
37260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
37270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String inUrl = url.trim();
37280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        boolean hasSpace = inUrl.indexOf(' ') != -1;
37290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
37300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        Matcher matcher = ACCEPTED_URI_SCHEMA.matcher(inUrl);
37310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (matcher.matches()) {
37320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // force scheme to lowercase
37330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            String scheme = matcher.group(1);
37340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            String lcScheme = scheme.toLowerCase();
37350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (!lcScheme.equals(scheme)) {
3736123ecfb21e7ca670e3d04efe58780b3bac54a9a1Mitsuru Oshima                inUrl = lcScheme + matcher.group(2);
3737123ecfb21e7ca670e3d04efe58780b3bac54a9a1Mitsuru Oshima            }
3738123ecfb21e7ca670e3d04efe58780b3bac54a9a1Mitsuru Oshima            if (hasSpace) {
3739123ecfb21e7ca670e3d04efe58780b3bac54a9a1Mitsuru Oshima                inUrl = inUrl.replace(" ", "%20");
37400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
37410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return inUrl;
37420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
37430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (hasSpace) {
3744565505b1a2c1d3099496af5910760087602e994aSatish Sampath            // FIXME: Is this the correct place to add to searches?
3745565505b1a2c1d3099496af5910760087602e994aSatish Sampath            // what if someone else calls this function?
3746565505b1a2c1d3099496af5910760087602e994aSatish Sampath            int shortcut = parseUrlShortcut(inUrl);
3747565505b1a2c1d3099496af5910760087602e994aSatish Sampath            if (shortcut != SHORTCUT_INVALID) {
3748565505b1a2c1d3099496af5910760087602e994aSatish Sampath                Browser.addSearchUrl(mResolver, inUrl);
3749565505b1a2c1d3099496af5910760087602e994aSatish Sampath                String query = inUrl.substring(2);
3750565505b1a2c1d3099496af5910760087602e994aSatish Sampath                switch (shortcut) {
3751565505b1a2c1d3099496af5910760087602e994aSatish Sampath                case SHORTCUT_GOOGLE_SEARCH:
375247fdfdb989ffb79590a39c40792be995de32e521Grace Kloba                    return URLUtil.composeSearchUrl(query, QuickSearch_G, QUERY_PLACE_HOLDER);
3753565505b1a2c1d3099496af5910760087602e994aSatish Sampath                case SHORTCUT_WIKIPEDIA_SEARCH:
3754565505b1a2c1d3099496af5910760087602e994aSatish Sampath                    return URLUtil.composeSearchUrl(query, QuickSearch_W, QUERY_PLACE_HOLDER);
3755565505b1a2c1d3099496af5910760087602e994aSatish Sampath                case SHORTCUT_DICTIONARY_SEARCH:
3756565505b1a2c1d3099496af5910760087602e994aSatish Sampath                    return URLUtil.composeSearchUrl(query, QuickSearch_D, QUERY_PLACE_HOLDER);
3757565505b1a2c1d3099496af5910760087602e994aSatish Sampath                case SHORTCUT_GOOGLE_MOBILE_LOCAL_SEARCH:
37580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // FIXME: we need location in this case
3759565505b1a2c1d3099496af5910760087602e994aSatish Sampath                    return URLUtil.composeSearchUrl(query, QuickSearch_L, QUERY_PLACE_HOLDER);
37600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
37610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
37620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
37635ee906c089567bca705e18561357510d7b55cb5aDan Egnor            if (Patterns.WEB_URL.matcher(inUrl).matches()) {
37640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                return URLUtil.guessUrl(inUrl);
37650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
37660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
37670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
37680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        Browser.addSearchUrl(mResolver, inUrl);
376947fdfdb989ffb79590a39c40792be995de32e521Grace Kloba        return URLUtil.composeSearchUrl(inUrl, QuickSearch_G, QUERY_PLACE_HOLDER);
37700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
37710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
3772bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch    /* package */ void setShouldShowErrorConsole(boolean flag) {
3773bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch        if (flag == mShouldShowErrorConsole) {
3774bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch            // Nothing to do.
3775bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch            return;
3776bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch        }
3777bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch
3778bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch        mShouldShowErrorConsole = flag;
3779bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch
378022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        ErrorConsoleView errorConsole = mTabControl.getCurrentTab()
378122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba                .getErrorConsole(true);
3782bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch
3783bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch        if (flag) {
3784bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch            // Setting the show state of the console will cause it's the layout to be inflated.
3785bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch            if (errorConsole.numberOfErrors() > 0) {
3786bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch                errorConsole.showConsole(ErrorConsoleView.SHOW_MINIMIZED);
3787bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch            } else {
3788bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch                errorConsole.showConsole(ErrorConsoleView.SHOW_NONE);
3789bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch            }
3790bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch
3791bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch            // Now we can add it to the main view.
3792bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch            mErrorConsoleContainer.addView(errorConsole,
379315b8ec6b226f4d57307716e1f495e10a91f8cbf4Romain Guy                    new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
3794bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch                                                  ViewGroup.LayoutParams.WRAP_CONTENT));
3795bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch        } else {
3796bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch            mErrorConsoleContainer.removeView(errorConsole);
3797bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch        }
3798bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch
3799bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch    }
3800bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch
380122ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    boolean shouldShowErrorConsole() {
380222ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba        return mShouldShowErrorConsole;
380322ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    }
380422ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba
3805163ab74e2f85b53a1a374c49677073fb64d35f28Andrei Popescu    private void setStatusBarVisibility(boolean visible) {
3806163ab74e2f85b53a1a374c49677073fb64d35f28Andrei Popescu        int flag = visible ? 0 : WindowManager.LayoutParams.FLAG_FULLSCREEN;
3807163ab74e2f85b53a1a374c49677073fb64d35f28Andrei Popescu        getWindow().setFlags(flag, WindowManager.LayoutParams.FLAG_FULLSCREEN);
3808163ab74e2f85b53a1a374c49677073fb64d35f28Andrei Popescu    }
3809163ab74e2f85b53a1a374c49677073fb64d35f28Andrei Popescu
381056199cc25e7ee0455ec2a8099098b66b8554f677Andrei Popescu
381156199cc25e7ee0455ec2a8099098b66b8554f677Andrei Popescu    private void sendNetworkType(String type, String subtype) {
381256199cc25e7ee0455ec2a8099098b66b8554f677Andrei Popescu        WebView w = mTabControl.getCurrentWebView();
381356199cc25e7ee0455ec2a8099098b66b8554f677Andrei Popescu        if (w != null) {
381456199cc25e7ee0455ec2a8099098b66b8554f677Andrei Popescu            w.setNetworkType(type, subtype);
381556199cc25e7ee0455ec2a8099098b66b8554f677Andrei Popescu        }
381656199cc25e7ee0455ec2a8099098b66b8554f677Andrei Popescu    }
381756199cc25e7ee0455ec2a8099098b66b8554f677Andrei Popescu
381830995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu    private void packageChanged(String packageName, boolean wasAdded) {
381930995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu        WebView w = mTabControl.getCurrentWebView();
382030995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu        if (w == null) {
382130995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu            return;
382230995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu        }
382330995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu
382430995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu        if (wasAdded) {
382530995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu            w.addPackageName(packageName);
382630995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu        } else {
382730995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu            w.removePackageName(packageName);
382830995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu        }
382930995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu    }
383030995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu
383130995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu    private void addPackageNames(Set<String> packageNames) {
383230995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu        WebView w = mTabControl.getCurrentWebView();
383330995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu        if (w == null) {
383430995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu            return;
383530995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu        }
383630995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu
383730995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu        w.addPackageNames(packageNames);
383830995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu    }
383930995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu
384030995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu    private void getInstalledPackages() {
384130995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu        AsyncTask<Void, Void, Set<String> > task =
384230995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu            new AsyncTask<Void, Void, Set<String> >() {
384330995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu            protected Set<String> doInBackground(Void... unused) {
384430995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu                Set<String> installedPackages = new HashSet<String>();
384530995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu                PackageManager pm = BrowserActivity.this.getPackageManager();
384630995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu                if (pm != null) {
384730995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu                    List<PackageInfo> packages = pm.getInstalledPackages(0);
384830995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu                    for (PackageInfo p : packages) {
384930995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu                        if (BrowserActivity.this.sGoogleApps.contains(p.packageName)) {
385030995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu                            installedPackages.add(p.packageName);
385130995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu                        }
385230995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu                    }
385330995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu                }
385430995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu
385530995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu                return installedPackages;
385630995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu            }
385730995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu
385830995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu            // Executes on the UI thread
385930995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu            protected void onPostExecute(Set<String> installedPackages) {
386030995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu                addPackageNames(installedPackages);
386130995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu            }
386230995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu        };
386330995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu        task.execute();
386430995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu    }
386530995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu
3866eb6eef4c45df2d65c3e70660493a147a2be405e3Grace Kloba    final static int LOCK_ICON_UNSECURE = 0;
3867eb6eef4c45df2d65c3e70660493a147a2be405e3Grace Kloba    final static int LOCK_ICON_SECURE   = 1;
3868eb6eef4c45df2d65c3e70660493a147a2be405e3Grace Kloba    final static int LOCK_ICON_MIXED    = 2;
38690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
38700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private BrowserSettings mSettings;
38710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private TabControl      mTabControl;
38720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private ContentResolver mResolver;
38730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private FrameLayout     mContentView;
3874adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu    private View            mCustomView;
3875adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu    private FrameLayout     mCustomViewContainer;
3876c9b5556351b59caec77b4eec1ad30652fec6a4d9Andrei Popescu    private WebChromeClient.CustomViewCallback mCustomViewCallback;
38770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
38780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // FIXME, temp address onPrepareMenu performance problem. When we move everything out of
38790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // view, we should rewrite this.
38800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private int mCurrentMenuState = 0;
38810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private int mMenuState = R.id.MAIN_MENU;
3882adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu    private int mOldMenuState = EMPTY_MENU;
38830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private static final int EMPTY_MENU = -1;
38840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private Menu mMenu;
38850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
38860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private FindDialog mFindDialog;
38870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Used to prevent chording to result in firing two shortcuts immediately
38880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // one after another.  Fixes bug 1211714.
38890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    boolean mCanChord;
38900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
38910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private boolean mInLoad;
38920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private boolean mIsNetworkUp;
3893b7cc8b439dc595dc48e1c2183b35d23ad72dfbe5Ben Murdoch    private boolean mDidStopLoad;
38940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
38950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private boolean mActivityInPause = true;
38960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
38970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private boolean mMenuIsDown;
38980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
38990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private static boolean mInTrace;
39000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
39010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Performance probe
39020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private static final int[] SYSTEM_CPU_FORMAT = new int[] {
39030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Process.PROC_SPACE_TERM | Process.PROC_COMBINE,
39040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Process.PROC_SPACE_TERM | Process.PROC_OUT_LONG, // 1: user time
39050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Process.PROC_SPACE_TERM | Process.PROC_OUT_LONG, // 2: nice time
39060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Process.PROC_SPACE_TERM | Process.PROC_OUT_LONG, // 3: sys time
39070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Process.PROC_SPACE_TERM | Process.PROC_OUT_LONG, // 4: idle time
39080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Process.PROC_SPACE_TERM | Process.PROC_OUT_LONG, // 5: iowait time
39090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Process.PROC_SPACE_TERM | Process.PROC_OUT_LONG, // 6: irq time
39100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Process.PROC_SPACE_TERM | Process.PROC_OUT_LONG  // 7: softirq time
39110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    };
39120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
39130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private long mStart;
39140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private long mProcessStart;
39150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private long mUserStart;
39160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private long mSystemStart;
39170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private long mIdleStart;
39180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private long mIrqStart;
39190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
39200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private long mUiStart;
39210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
39220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private Drawable    mMixLockIcon;
39230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private Drawable    mSecLockIcon;
39240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
39250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /* hold a ref so we can auto-cancel if necessary */
39260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private AlertDialog mAlertDialog;
39270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
39280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Wait for credentials before loading google.com
39290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private ProgressDialog mCredsDlg;
39300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
39310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // The up-to-date URL and title (these can be different from those stored
39320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // in WebView, since it takes some time for the information in WebView to
39330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // get updated)
39340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private String mUrl;
39350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private String mTitle;
39360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
39370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // As PageInfo has different style for landscape / portrait, we have
39380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // to re-open it when configuration changed
39390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private AlertDialog mPageInfoDialog;
394022ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private Tab mPageInfoView;
39410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // If the Page-Info dialog is launched from the SSL-certificate-on-error
39420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // dialog, we should not just dismiss it, but should get back to the
39430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // SSL-certificate-on-error dialog. This flag is used to store this state
3944c7b92f811dfa3572578ddc6714c98a03936d9ce5Leon Scroggins    private boolean mPageInfoFromShowSSLCertificateOnError;
39450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
39460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // as SSLCertificateOnError has different style for landscape / portrait,
39470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // we have to re-open it when configuration changed
39480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private AlertDialog mSSLCertificateOnErrorDialog;
39490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private WebView mSSLCertificateOnErrorView;
39500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private SslErrorHandler mSSLCertificateOnErrorHandler;
39510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private SslError mSSLCertificateOnErrorError;
39520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
39530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // as SSLCertificate has different style for landscape / portrait, we
39540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // have to re-open it when configuration changed
39550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private AlertDialog mSSLCertificateDialog;
395622ac16eab0b62d24a99fc360f2ccea14837f4127Grace Kloba    private Tab mSSLCertificateView;
39570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
39580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // as HttpAuthentication has different style for landscape / portrait, we
39590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // have to re-open it when configuration changed
39600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private AlertDialog mHttpAuthenticationDialog;
39610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private HttpAuthHandler mHttpAuthHandler;
39620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
39630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /*package*/ static final FrameLayout.LayoutParams COVER_SCREEN_PARAMS =
39640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                            new FrameLayout.LayoutParams(
396515b8ec6b226f4d57307716e1f495e10a91f8cbf4Romain Guy                                            ViewGroup.LayoutParams.MATCH_PARENT,
396615b8ec6b226f4d57307716e1f495e10a91f8cbf4Romain Guy                                            ViewGroup.LayoutParams.MATCH_PARENT);
3967adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu    /*package*/ static final FrameLayout.LayoutParams COVER_SCREEN_GRAVITY_CENTER =
3968adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu                                            new FrameLayout.LayoutParams(
396915b8ec6b226f4d57307716e1f495e10a91f8cbf4Romain Guy                                            ViewGroup.LayoutParams.MATCH_PARENT,
397015b8ec6b226f4d57307716e1f495e10a91f8cbf4Romain Guy                                            ViewGroup.LayoutParams.MATCH_PARENT,
3971adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu                                            Gravity.CENTER);
397247fdfdb989ffb79590a39c40792be995de32e521Grace Kloba    // Google search
397347fdfdb989ffb79590a39c40792be995de32e521Grace Kloba    final static String QuickSearch_G = "http://www.google.com/m?q=%s";
39740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Wikipedia search
39750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    final static String QuickSearch_W = "http://en.wikipedia.org/w/index.php?search=%s&go=Go";
39760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Dictionary search
39770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    final static String QuickSearch_D = "http://dictionary.reference.com/search?q=%s";
39780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Google Mobile Local search
39790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    final static String QuickSearch_L = "http://www.google.com/m/search?site=local&q=%s&near=mountain+view";
39800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
39810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    final static String QUERY_PLACE_HOLDER = "%s";
39820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
39830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // "source" parameter for Google search through search key
39840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    final static String GOOGLE_SEARCH_SOURCE_SEARCHKEY = "browser-key";
39850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // "source" parameter for Google search through goto menu
39860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    final static String GOOGLE_SEARCH_SOURCE_GOTO = "browser-goto";
39870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // "source" parameter for Google search through simplily type
39880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    final static String GOOGLE_SEARCH_SOURCE_TYPE = "browser-type";
39890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // "source" parameter for Google search suggested by the browser
39900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    final static String GOOGLE_SEARCH_SOURCE_SUGGEST = "browser-suggest";
39910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // "source" parameter for Google search from unknown source
39920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    final static String GOOGLE_SEARCH_SOURCE_UNKNOWN = "unknown";
39930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
39940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private final static String LOGTAG = "browser";
39950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
39960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private String mLastEnteredUrl;
39970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
39980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private PowerManager.WakeLock mWakeLock;
39990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private final static int WAKELOCK_TIMEOUT = 5 * 60 * 1000; // 5 minutes
40000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
40010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private Toast mStopToast;
40020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
400368579393973f745fc65a2781061af9bb8f2d7020Leon Scroggins    private TitleBar mTitleBar;
400481db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins
4005bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch    private LinearLayout mErrorConsoleContainer = null;
4006bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch    private boolean mShouldShowErrorConsole = false;
4007bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch
40080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // As the ids are dynamically created, we can't guarantee that they will
40090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // be in sequence, so this static array maps ids to a window number.
40100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    final static private int[] WINDOW_SHORTCUT_ID_ARRAY =
40110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    { R.id.window_one_menu_id, R.id.window_two_menu_id, R.id.window_three_menu_id,
40120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project      R.id.window_four_menu_id, R.id.window_five_menu_id, R.id.window_six_menu_id,
40130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project      R.id.window_seven_menu_id, R.id.window_eight_menu_id };
40140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
40150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // monitor platform changes
40160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private IntentFilter mNetworkStateChangedFilter;
40170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private BroadcastReceiver mNetworkStateIntentReceiver;
40180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
4019b4da0ad0351996f639b50f9f29b123a9b5c24fd0Grace Kloba    private BroadcastReceiver mPackageInstallationReceiver;
4020b4da0ad0351996f639b50f9f29b123a9b5c24fd0Grace Kloba
40210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // activity requestCode
402278a98e459323f938e97789a6131beddbebb459ceNicolas Roard    final static int COMBO_PAGE                 = 1;
402378a98e459323f938e97789a6131beddbebb459ceNicolas Roard    final static int DOWNLOAD_PAGE              = 2;
402478a98e459323f938e97789a6131beddbebb459ceNicolas Roard    final static int PREFERENCES_PAGE           = 3;
40258d5fa439c93c336197cfca4a0bfca7147e43353dLeon Scroggins    final static int FILE_SELECTED              = 4;
40260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
4027540035dfd1347c78eeec10ec0847e18fcc50ef36Andrei Popescu    // the default <video> poster
4028540035dfd1347c78eeec10ec0847e18fcc50ef36Andrei Popescu    private Bitmap mDefaultVideoPoster;
4029540035dfd1347c78eeec10ec0847e18fcc50ef36Andrei Popescu    // the video progress view
4030540035dfd1347c78eeec10ec0847e18fcc50ef36Andrei Popescu    private View mVideoProgressView;
4031540035dfd1347c78eeec10ec0847e18fcc50ef36Andrei Popescu
403230995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu    // The Google packages we monitor for the navigator.isApplicationInstalled()
403330995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu    // API. Add as needed.
403430995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu    private static Set<String> sGoogleApps;
403530995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu    static {
403630995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu        sGoogleApps = new HashSet<String>();
403730995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu        sGoogleApps.add("com.google.android.youtube");
403830995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu    }
403930995e7cef0a0d5f9c7228d504076e0c158fa8b7Andrei Popescu
404025ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima    /**
404125ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima     * A UrlData class to abstract how the content will be set to WebView.
404225ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima     * This base class uses loadUrl to show the content.
404325ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima     */
404425ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima    private static class UrlData {
4045068e48b469f5abca53ee3da38f933cf2c25c93b8Grace Kloba        final String mUrl;
4046068e48b469f5abca53ee3da38f933cf2c25c93b8Grace Kloba        final Map<String, String> mHeaders;
404758d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        final Intent mVoiceIntent;
404860e095c190496d42327f8ec2ef990c044d15a76fGrace Kloba
404925ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima        UrlData(String url) {
405025ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima            this.mUrl = url;
4051068e48b469f5abca53ee3da38f933cf2c25c93b8Grace Kloba            this.mHeaders = null;
405258d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins            this.mVoiceIntent = null;
405325ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima        }
405460e095c190496d42327f8ec2ef990c044d15a76fGrace Kloba
405558d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        UrlData(String url, Map<String, String> headers, Intent intent) {
4056068e48b469f5abca53ee3da38f933cf2c25c93b8Grace Kloba            this.mUrl = url;
4057068e48b469f5abca53ee3da38f933cf2c25c93b8Grace Kloba            this.mHeaders = headers;
4058a1cc3fdce19a336c251297c61cd83ac6cf767cd1Leon Scroggins            if (RecognizerResultsIntent.ACTION_VOICE_SEARCH_RESULTS
4059a1cc3fdce19a336c251297c61cd83ac6cf767cd1Leon Scroggins                    .equals(intent.getAction())) {
406058d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins                this.mVoiceIntent = intent;
406158d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins            } else {
406258d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins                this.mVoiceIntent = null;
406358d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins            }
406460e095c190496d42327f8ec2ef990c044d15a76fGrace Kloba        }
406560e095c190496d42327f8ec2ef990c044d15a76fGrace Kloba
406625ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima        boolean isEmpty() {
406758d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins            return mVoiceIntent == null && (mUrl == null || mUrl.length() == 0);
406825ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima        }
406925ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima
407058d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins        public void loadIn(Tab t) {
407158d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins            if (mVoiceIntent != null) {
407258d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins                t.activateVoiceSearchMode(mVoiceIntent);
407358d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins            } else {
407458d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins                t.getWebView().loadUrl(mUrl, mHeaders);
407558d56c6b5052faa86083965132cd51b1a9594d0eLeon Scroggins            }
407625ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima        }
407725ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima    };
407825ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima
40791f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins    /* package */ static final UrlData EMPTY_URL_DATA = new UrlData(null);
40800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project}
4081